import { Selector, t } from "testcafe"; import { RequestLogger } from "testcafe"; const logger = RequestLogger(/http:\/\/localhost:2343\/api\/v1\/*/, { logResponseHeaders: true, logResponseBody: true, }); export default class Page { constructor() { this.view = Selector("div.p-view-select", { timeout: 15000 }); this.camera = Selector("div.p-camera-select", { timeout: 15000 }); this.countries = Selector("div.p-countries-select", { timeout: 15000 }); this.time = Selector("div.p-time-select", { timeout: 15000 }); this.search1 = Selector("div.input-search input", { timeout: 15000 }); } async setFilter(filter, option) { let filterSelector = ""; switch (filter) { case "view": filterSelector = "div.p-view-select"; break; case "camera": filterSelector = "div.p-camera-select"; break; case "time": filterSelector = "div.p-time-select"; break; case "countries": filterSelector = "div.p-countries-select"; break; default: throw "unknown filter"; } if (!(await Selector(filterSelector).visible)) { await t.click(Selector(".p-expand-search")); } await t.click(filterSelector, { timeout: 15000 }); if (option) { await t.click(Selector('div[role="listitem"]').withText(option), { timeout: 15000 }); } else { await t.click(Selector('div[role="listitem"]').nth(1), { timeout: 15000 }); } } async search(term) { await t .typeText(this.search1, term, { replace: true }) .pressKey("enter") .wait(10000) .expect(this.search1.value) .contains(term); } async openNav() { if (await Selector("button.nav-show").exists) { await t.click(Selector("button.nav-show")); } else if (await Selector("div.nav-expand").exists) { await t.click(Selector("div.nav-expand i")); } } async selectFromUID(uid) { await t .hover(Selector("a").withAttribute("data-uid", uid)) .click(Selector(`.uid-${uid} .input-select`)); } async selectPhotoFromUID(uid) { await t .hover(Selector("div").withAttribute("data-uid", uid)) .click(Selector(`.uid-${uid} .input-select`)); } async selectFromUIDInFullscreen(uid) { await t.hover(Selector("div").withAttribute("data-uid", uid)); if (await Selector(`.uid-${uid} .action-fullscreen`).exists) { await t.click(Selector(`.uid-${uid} .action-fullscreen`)); } else { await t.click(Selector("div").withAttribute("data-uid", uid)); } await t .expect(Selector("#photo-viewer").visible) .ok() .click(Selector('button[title="Select"]')) .click(Selector(".action-close", { timeout: 4000 })); } async toggleSelectNthPhoto(nPhoto) { await t .hover(Selector(".is-photo.type-image", { timeout: 4000 }).nth(nPhoto)) .click(Selector(".is-photo.type-image .input-select").nth(nPhoto)); } async toggleLike(uid) { await t.click(Selector(`.uid-${uid} .input-favorite`)); } async archiveSelected() { if (!(await Selector("#t-clipboard button.action-archive").visible)) { await t.click(Selector("button.action-menu", { timeout: 5000 })); } if (t.browser.platform === "mobile") { if (!(await Selector("#t-clipboard button.action-archive").visible)) { await t.click(Selector("button.action-menu", { timeout: 5000 })); if (!(await Selector("#t-clipboard button.action-archive").visible)) { await t.click(Selector("button.action-menu", { timeout: 5000 })); } if (!(await Selector("#t-clipboard button.action-archive").visible)) { await t.click(Selector("button.action-menu", { timeout: 5000 })); } } } await t.click(Selector("#t-clipboard button.action-archive", { timeout: 5000 })); } async privateSelected() { await t.click(Selector("button.action-menu", { timeout: 5000 })); if (!(await Selector("button.action-private").visible)) { await t.click(Selector("button.action-menu", { timeout: 5000 })); if (!(await Selector("button.action-private").visible)) { await t.click(Selector("button.action-menu", { timeout: 5000 })); } if (!(await Selector("button.action-private").visible)) { await t.click(Selector("button.action-menu", { timeout: 5000 })); } } await t.click(Selector("button.action-private", { timeout: 5000 })); } async restoreSelected() { await t.click(Selector("button.action-menu")).click(Selector("button.action-restore")); } async editSelected() { if (await Selector("button.action-edit").visible) { await t.click(Selector("button.action-edit")); } else if (await Selector("button.action-menu").exists) { await t.click(Selector("button.action-menu")).click(Selector("button.action-edit")); } } async deleteSelected() { await t .click(Selector("button.action-menu")) .click(Selector("button.action-delete")) .click(Selector("button.action-confirm")); } async removeSelected() { await t.click(Selector("button.action-menu")).click(Selector("button.action-remove")); } async addSelectedToAlbum(name, type) { await t .click(Selector("button.action-menu")) .click(Selector("button.action-" + type, { timeout: 15000 })) .typeText(Selector(".input-album input"), name, { replace: true }) .pressKey("enter"); } async turnSwitchOff(type) { await t .click("#tab-info") .expect( Selector(".input-" + type + " input", { timeout: 8000 }).hasAttribute( "aria-checked", "true" ) ) .ok() .click(Selector(".input-" + type + " input")) .expect( Selector(".input-" + type + " input", { timeout: 8000 }).hasAttribute( "aria-checked", "false" ) ) .ok(); } async turnSwitchOn(type) { await t .click("#tab-info") .expect( Selector(".input-" + type + " input", { timeout: 8000 }).hasAttribute( "aria-checked", "false" ) ) .ok() .click(Selector(".input-" + type + " input")) .expect( Selector(".input-" + type + " input", { timeout: 8000 }).hasAttribute( "aria-checked", "true" ) ) .ok(); } async clearSelection() { if (await Selector(".action-clear").visible) { await t.click(Selector(".action-clear")); } else { await t.click(Selector(".action-menu")).click(Selector(".action-clear")); } } async login(username, password) { await t .typeText(Selector(".input-name input"), username, { replace: true, timeout: 5000 }) .typeText(Selector(".input-password input"), password, { replace: true }) .click(Selector(".action-confirm")); } async logout() { await t.click(Selector("div.nav-logout")); } async testCreateEditDeleteSharingLink(type) { await this.openNav(); if (type === "states") { await t.click(Selector(".nav-places + div")); } await t.click(Selector(".nav-" + type)); const FirstAlbum = await Selector("a.is-album").nth(0).getAttribute("data-uid"); await this.selectFromUID(FirstAlbum); const clipboardCount = await Selector("span.count-clipboard"); await t .expect(clipboardCount.textContent) .eql("1") .click(Selector("button.action-menu")) .click(Selector("button.action-share")) .click(Selector("div.v-expansion-panel__header__icon").nth(0)); const InitialUrl = await Selector(".action-url").innerText; const InitialSecret = await Selector(".input-secret input").value; const InitialExpire = await Selector("div.v-select__selections").innerText; await t .expect(InitialUrl) .notContains("secretfortesting") .expect(InitialExpire) .contains("Never") .typeText(Selector(".input-secret input"), "secretForTesting", { replace: true }) .click(Selector(".input-expires input")) .click(Selector("div").withText("After 1 day").parent('div[role="listitem"]')) .click(Selector("button.action-save")) .click(Selector("button.action-close")); await this.clearSelection(); await t .click(Selector("a.is-album").withAttribute("data-uid", FirstAlbum)) .click(Selector("button.action-share")) .click(Selector("div.v-expansion-panel__header__icon").nth(0)); const UrlAfterChange = await Selector(".action-url").innerText; const ExpireAfterChange = await Selector("div.v-select__selections").innerText; await t .expect(UrlAfterChange) .contains("secretfortesting") .expect(ExpireAfterChange) .contains("After 1 day") .typeText(Selector(".input-secret input"), InitialSecret, { replace: true }) .click(Selector(".input-expires input")) .click(Selector("div").withText("Never").parent('div[role="listitem"]')) .click(Selector("button.action-save")) .click(Selector("div.v-expansion-panel__header__icon")); const LinkCount = await Selector(".action-url").count; await t.click(".action-add-link"); const LinkCountAfterAdd = await Selector(".action-url").count; await t .expect(LinkCountAfterAdd) .eql(LinkCount + 1) .click(Selector("div.v-expansion-panel__header__icon")) .click(Selector(".action-delete")); const LinkCountAfterDelete = await Selector(".action-url").count; await t .expect(LinkCountAfterDelete) .eql(LinkCountAfterAdd - 1) .click(Selector("button.action-close")); await this.openNav(); await t .click(".nav-" + type) .click("a.uid-" + FirstAlbum + " .action-share") .click(Selector("div.v-expansion-panel__header__icon")) .click(Selector(".action-delete")); } async checkButtonVisibility(button, inContextMenu, inAlbum) { const FirstAlbum = await Selector("a.is-album").nth(0).getAttribute("data-uid"); await this.selectFromUID(FirstAlbum); await t.click(Selector("button.action-menu")); if (inContextMenu) { await t.expect(Selector("button.action-" + button).visible).ok(); } else { await t.expect(Selector("button.action-" + button).visible).notOk(); } await this.clearSelection(); if (t.browser.platform !== "mobile") { await t.click(Selector("a.is-album").nth(0)); if (inAlbum) { await t.expect(Selector("button.action-" + button).visible).ok(); } else { await t.expect(Selector("button.action-" + button).visible).notOk(); } } } async deletePhotoFromUID(uid) { await this.selectPhotoFromUID(uid); await this.archiveSelected(); await this.openNav(); await t.click(Selector(".nav-browse + div")).click(Selector(".nav-archive")); await this.selectPhotoFromUID(uid); await t .click(Selector("button.action-menu", { timeout: 5000 })) .click(Selector(".remove")) .click(Selector(".action-confirm")) .expect(Selector("div").withAttribute("data-uid", uid).exists, { timeout: 5000 }) .notOk(); } async validateDownloadRequest(request, filename, extension) { const downloadedFileName = request.headers["content-disposition"]; await t .expect(request.statusCode === 200) .ok() .expect(downloadedFileName) .contains(filename) .expect(downloadedFileName) .contains(extension); await logger.clear(); } async checkEditFormValues( title, day, month, year, localTime, utcTime, timezone, country, altitude, lat, lng, camera, iso, exposure, lens, fnumber, flength, subject, artist, copyright, license, description, keywords, notes ) { if (title !== "") { await t.expect(Selector(".input-title input").value).eql(title); } if (day !== "") { await t.expect(Selector(".input-day input").value).eql(day); } if (month !== "") { await t.expect(Selector(".input-month input").value).eql(month); } if (year !== "") { await t.expect(Selector(".input-year input").value).eql(year); } if (timezone !== "") { await t.expect(Selector(".input-timezone input").value).eql(timezone); } if (localTime !== "") { await t.expect(Selector(".input-local-time input").value).eql(localTime); } if (utcTime !== "") { await t.expect(Selector(".input-utc-time input").value).eql(utcTime); } if (altitude !== "") { await t.expect(Selector(".input-altitude input").value).eql(altitude); } if (country !== "") { await t.expect(Selector("div").withText(country).visible).ok(); } if (lat !== "") { await t.expect(Selector(".input-latitude input").value).eql(lat); } if (lng !== "") { await t.expect(Selector(".input-longitude input").value).eql(lng); } if (camera !== "") { await t.expect(Selector("div").withText(camera).visible).ok(); } if (lens !== "") { await t.expect(Selector("div").withText(lens).visible).ok(); } if (iso !== "") { await t.expect(Selector(".input-iso input").value).eql(iso); } if (exposure !== "") { await t.expect(Selector(".input-exposure input").value).eql(exposure); } if (fnumber !== "") { await t.expect(Selector(".input-fnumber input").value).eql(fnumber); } if (flength !== "") { await t.expect(Selector(".input-focal-length input").value).eql(flength); } if (subject !== "") { await t.expect(Selector(".input-subject textarea").value).eql(subject); } if (artist !== "") { await t.expect(Selector(".input-artist input").value).eql(artist); } if (copyright !== "") { await t.expect(Selector(".input-copyright input").value).eql(copyright); } if (license !== "") { await t.expect(Selector(".input-license textarea").value).eql(license); } if (description !== "") { await t.expect(Selector(".input-description textarea").value).eql(description); } if (notes !== "") { await t.expect(Selector(".input-notes textarea").value).contains(notes); } if (keywords !== "") { await t.expect(Selector(".input-keywords textarea").value).contains(keywords); } } async editPhoto( title, timezone, day, month, year, localTime, altitude, lat, lng, iso, exposure, fnumber, flength, subject, artist, copyright, license, description, keywords, notes ) { await t .typeText(Selector(".input-title input"), title, { replace: true }) .typeText(Selector(".input-timezone input"), timezone, { replace: true }) .click(Selector("div").withText(timezone).parent('div[role="listitem"]')) .typeText(Selector(".input-day input"), day, { replace: true }) .pressKey("enter") .typeText(Selector(".input-month input"), month, { replace: true }) .pressKey("enter") .typeText(Selector(".input-year input"), year, { replace: true }) .click(Selector("div").withText(year).parent('div[role="listitem"]')) .click(Selector(".input-local-time input")) .pressKey("ctrl+a delete") .typeText(Selector(".input-local-time input"), localTime, { replace: true }) .pressKey("enter") .typeText(Selector(".input-altitude input"), altitude, { replace: true }) .typeText(Selector(".input-latitude input"), lat, { replace: true }) .typeText(Selector(".input-longitude input"), lng, { replace: true }) //.click(Selector('.input-camera input')) //.hover(Selector('div').withText('Apple iPhone 6').parent('div[role="listitem"]')) //.click(Selector('div').withText('Apple iPhone 6').parent('div[role="listitem"]')) //.click(Selector('.input-lens input')) //.click(Selector('div').withText('Apple iPhone 5s back camera 4.15mm f/2.2').parent('div[role="listitem"]')) .typeText(Selector(".input-iso input"), iso, { replace: true }) .typeText(Selector(".input-exposure input"), exposure, { replace: true }) .typeText(Selector(".input-fnumber input"), fnumber, { replace: true }) .typeText(Selector(".input-focal-length input"), flength, { replace: true }) .typeText(Selector(".input-subject textarea"), subject, { replace: true }) .typeText(Selector(".input-artist input"), artist, { replace: true }) .typeText(Selector(".input-copyright input"), copyright, { replace: true }) .typeText(Selector(".input-license textarea"), license, { replace: true }) .typeText(Selector(".input-description textarea"), description, { replace: true, }) .typeText(Selector(".input-keywords textarea"), keywords) .typeText(Selector(".input-notes textarea"), notes, { replace: true }) .click(Selector("button.action-approve")); await t.expect(Selector(".input-latitude input").visible, { timeout: 5000 }).ok(); if (t.browser.platform === "mobile") { await t.click(Selector("button.action-apply")).click(Selector("button.action-close")); } else { await t.click(Selector("button.action-done", { timeout: 5000 })); } } async undoPhotoEdit( title, timezone, day, month, year, localTime, altitude, lat, lng, country, iso, exposure, fnumber, flength, subject, artist, copyright, license, description, keywords, notes ) { if (title.empty || title === "") { await t.click(Selector(".input-title input")).pressKey("ctrl+a delete"); } else { await t.typeText(Selector(".input-title input"), title, { replace: true }); } await t .typeText(Selector(".input-day input"), day, { replace: true }) .pressKey("enter") .typeText(Selector(".input-month input"), month, { replace: true }) .pressKey("enter") .typeText(Selector(".input-year input"), year, { replace: true }) .pressKey("enter"); if (localTime.empty || localTime === "") { await t.click(Selector(".input-local-time input")).pressKey("ctrl+a delete"); } else { await t .click(Selector(".input-local-time input")) .pressKey("ctrl+a delete") .typeText(Selector(".input-local-time input"), localTime, { replace: true }) .pressKey("enter"); } if (timezone.empty || timezone === "") { await t .click(Selector(".input-timezone input")) .typeText(Selector(".input-timezone input"), "UTC", { replace: true }) .pressKey("enter"); } else { await t .typeText(Selector(".input-timezone input"), timezone, { replace: true }) .pressKey("enter"); } if (lat.empty || lat === "") { await t.click(Selector(".input-latitude input")).pressKey("ctrl+a delete"); } else { await t.typeText(Selector(".input-latitude input"), lat, { replace: true }); } if (lng.empty || lng === "") { await t.click(Selector(".input-longitude input")).pressKey("ctrl+a delete"); } else { await t.typeText(Selector(".input-longitude input"), lng, { replace: true }); } if (altitude.empty || altitude === "") { await t.click(Selector(".input-altitude input")).pressKey("ctrl+a delete"); } else { await t.typeText(Selector(".input-altitude input"), altitude, { replace: true }); } if (country.empty || country === "") { await t.click(Selector(".input-longitude input")).pressKey("ctrl+a delete"); } else { await t .click(Selector(".input-country input")) .pressKey("ctrl+a delete") .typeText(Selector(".input-country input"), country, { replace: true }) .pressKey("enter"); } // if (FirstPhotoCamera.empty || FirstPhotoCamera === "") //{ await t //.click(Selector('.input-camera input')) // .hover(Selector('div').withText('Unknown').parent('div[role="listitem"]')) // .click(Selector('div').withText('Unknown').parent('div[role="listitem"]'))} //else //{await t // .click(Selector('.input-camera input')) // .hover(Selector('div').withText(FirstPhotoCamera).parent('div[role="listitem"]')) // .click(Selector('div').withText(FirstPhotoCamera).parent('div[role="listitem"]'))} //if (FirstPhotoLens.empty || FirstPhotoLens === "") //{ await t // .click(Selector('.input-lens input')) // .click(Selector('div').withText('Unknown').parent('div[role="listitem"]'))} //else //{await t // .click(Selector('.input-lens input')) // .click(Selector('div').withText(FirstPhotoLens).parent('div[role="listitem"]'))} if (iso.empty || iso === "") { await t.click(Selector(".input-iso input")).pressKey("ctrl+a delete"); } else { await t.typeText(Selector(".input-iso input"), iso, { replace: true }); } if (exposure.empty || exposure === "") { await t.click(Selector(".input-exposure input")).pressKey("ctrl+a delete"); } else { await t.typeText(Selector(".input-exposure input"), exposure, { replace: true }); } if (fnumber.empty || fnumber === "") { await t.click(Selector(".input-fnumber input")).pressKey("ctrl+a delete"); } else { await t.typeText(Selector(".input-fnumber input"), fnumber, { replace: true }); } if (flength.empty || flength === "") { await t.click(Selector(".input-focal-length input")).pressKey("ctrl+a delete"); } else { await t.typeText(Selector(".input-focal-length input"), flength, { replace: true, }); } if (subject.empty || subject === "") { await t.click(Selector(".input-subject textarea")).pressKey("ctrl+a delete"); } else { await t.typeText(Selector(".input-subject textarea"), subject, { replace: true }); } if (artist.empty || artist === "") { await t.click(Selector(".input-artist input")).pressKey("ctrl+a delete"); } else { await t.typeText(Selector(".input-artist input"), artist, { replace: true }); } if (copyright.empty || copyright === "") { await t.click(Selector(".input-copyright input")).pressKey("ctrl+a delete"); } else { await t.typeText(Selector(".input-copyright input"), copyright, { replace: true }); } if (license.empty || license === "") { await t.click(Selector(".input-license textarea")).pressKey("ctrl+a delete"); } else { await t.typeText(Selector(".input-license textarea"), license, { replace: true }); } if (description.empty || description === "") { await t.click(Selector(".input-description textarea")).pressKey("ctrl+a delete"); } else { await t.typeText(Selector(".input-description textarea"), description, { replace: true, }); } if (keywords.empty || keywords === "") { await t.click(Selector(".input-keywords textarea")).pressKey("ctrl+a delete"); } else { await t.typeText(Selector(".input-keywords textarea"), keywords, { replace: true }); } if (notes.empty || notes === "") { await t.click(Selector(".input-notes textarea")).pressKey("ctrl+a delete"); } else { await t.typeText(Selector(".input-notes textarea"), notes, { replace: true }); } if (t.browser.platform === "mobile") { await t.click(Selector("button.action-apply")).click(Selector("button.action-close")); } else { await t.click(Selector("button.action-done", { timeout: 5000 })); } } }