diff --git a/Makefile b/Makefile index 2ef2d1c7a..8ee5ca7d5 100644 --- a/Makefile +++ b/Makefile @@ -43,13 +43,13 @@ test-pkg: reset-sqlite run-test-pkg test-api: reset-sqlite run-test-api test-short: reset-sqlite run-test-short test-mariadb: reset-acceptance run-test-mariadb -acceptance-private-run-chromium: acceptance-private-restart acceptance-private acceptance-private-stop +acceptance-auth-run-chromium: acceptance-auth-restart acceptance-auth acceptance-aut-stop acceptance-public-run-chromium: acceptance-restart acceptance acceptance-stop -acceptance-private-run-firefox: acceptance-private-restart acceptance-private-firefox acceptance-private-stop +acceptance-auth-run-firefox: acceptance-auth-restart acceptance-auth-firefox acceptance-auth-stop acceptance-public-run-firefox: acceptance-restart acceptance-firefox acceptance-stop -acceptance-run-chromium-smoke: acceptance-private-restart acceptance-private-smoke acceptance-private-stop acceptance-restart acceptance-smoke acceptance-stop -acceptance-run-chromium: acceptance-private-restart acceptance-private acceptance-private-stop acceptance-restart acceptance acceptance-stop -acceptance-run-firefox: acceptance-private-restart acceptance-private-firefox acceptance-private-stop acceptance-restart acceptance-firefox acceptance-stop +acceptance-run-chromium-short: acceptance-auth-restart acceptance-auth-short acceptance-auth-stop acceptance-restart acceptance-short acceptance-stop +acceptance-run-chromium: acceptance-auth-restart acceptance-auth acceptance-auth-stop acceptance-restart acceptance acceptance-stop +acceptance-run-firefox: acceptance-auth-restart acceptance-auth-firefox acceptance-auth-stop acceptance-restart acceptance-firefox acceptance-stop test-all: test acceptance-run-chromium fmt: fmt-js fmt-go clean-local: clean-local-config clean-local-cache @@ -121,11 +121,11 @@ acceptance-restart: ./photoprism -p --url "http://localhost:2343/" --upload-nsfw=false --db "sqlite" --dsn "./storage/acceptance/index.db" --import-path "./storage/acceptance/import" --port 2343 -c "./storage/acceptance/config" -o "./storage/acceptance/originals" -s "./storage/acceptance" --test --backup-path "./storage/acceptance/backup" --disable-backups start -d acceptance-stop: ./photoprism -p --url "http://localhost:2343/" --upload-nsfw=false --db "sqlite" --dsn "./storage/acceptance/index.db" --import-path "./storage/acceptance/import" --port 2343 -c "./storage/acceptance/config" -o "./storage/acceptance/originals" -s "./storage/acceptance" --test --backup-path "./storage/acceptance/backup" --disable-backups stop -acceptance-private-restart: +acceptance-auth-restart: cp -f storage/acceptance/backup.db storage/acceptance/index.db cp -f storage/acceptance/config/settingsBackup.yml storage/acceptance/config/settings.yml ./photoprism --auth-mode "passwd" --url "http://localhost:2343/" --upload-nsfw=false --db "sqlite" --dsn "./storage/acceptance/index.db" --import-path "./storage/acceptance/import" --port 2343 -c "./storage/acceptance/config" -o "./storage/acceptance/originals" -s "./storage/acceptance" --test --backup-path "./storage/acceptance/backup" --disable-backups start -d -acceptance-private-stop: +acceptance-auth-stop: ./photoprism --auth-mode "passwd" --url "http://localhost:2343/" --upload-nsfw=false --db "sqlite" --dsn "./storage/acceptance/index.db" --import-path "./storage/acceptance/import" --port 2343 -c "./storage/acceptance/config" -o "./storage/acceptance/originals" -s "./storage/acceptance" --test --backup-path "./storage/acceptance/backup" --disable-backups stop start: ./photoprism start -d @@ -200,24 +200,27 @@ watch-js: test-js: $(info Running JS unit tests...) (cd frontend && env NODE_ENV=development BABEL_ENV=test npm run test) +acceptance-old: + $(info Running JS acceptance tests in Chrome...) + (cd frontend && npm run acceptance --first="chromium:headless" --second=plus --third=public && cd ..) acceptance: $(info Running JS acceptance tests in Chrome...) - (cd frontend && npm run acceptance && cd ..) -acceptance-smoke: + (cd frontend && npm run acceptance --first="chromium:headless" --second="^(Common|Core)\:*" --third=public --fourth="tests/acceptance" && cd ..) +acceptance-short: $(info Running JS acceptance tests in Chrome...) - (cd frontend && npm run acceptance-smoke && cd ..) + (cd frontend && npm run acceptance-short --first="chromium:headless" --second="^(Common|Core)\:*" --third=public --fourth="tests/acceptance" && cd ..) acceptance-firefox: $(info Running JS acceptance tests in Firefox...) - (cd frontend && npm run acceptance-firefox && cd ..) -acceptance-private: - $(info Running JS acceptance-private tests in Chrome...) - (cd frontend && npm run acceptance-private && cd ..) -acceptance-private-smoke: - $(info Running JS acceptance-private tests in Chrome...) - (cd frontend && npm run acceptance-private-smoke && cd ..) -acceptance-private-firefox: - $(info Running JS acceptance-private tests in Firefox...) - (cd frontend && npm run acceptance-private-firefox && cd ..) + (cd frontend && npm run acceptance --first="firefox:headless" --second="^(Common|Core)\:*" --third=public --fourth="tests/acceptance" && cd ..) +acceptance-auth: + $(info Running JS acceptance-auth tests in Chrome...) + (cd frontend && npm run acceptance --first="chromium:headless" --second="^(Common|Core)\:*" --third=auth --fourth="tests/acceptance" && cd ..) +acceptance-auth-short: + $(info Running JS acceptance-auth tests in Chrome...) + (cd frontend && npm run acceptance-short --first="chromium:headless" --second="^(Common|Core)\:*" --third=auth --fourth="tests/acceptance" && cd ..) +acceptance-auth-firefox: + $(info Running JS acceptance-auth tests in Firefox...) + (cd frontend && npm run acceptance --first="firefox:headless" --second="^(Common|Core)\:*" --third=auth --fourth="tests/acceptance" && cd ..) reset-mariadb-testdb: $(info Resetting testdb database...) mysql < scripts/sql/reset-testdb.sql diff --git a/frontend/package.json b/frontend/package.json index b843623d0..b1f8dcf7b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -13,13 +13,9 @@ "fmt": "eslint --cache --fix src/ *.js .eslintrc.js", "test": "karma start", "upgrade": "npm --depth 10 update && npm audit fix", - "acceptance": "testcafe chromium:headless --skip-js-errors --quarantine-mode --selector-timeout 5000 -S -s tests/screenshots tests/acceptance", - "acceptance-smoke": "testcafe chromium:headless --skip-js-errors --quarantine-mode --test-meta type=smoke --selector-timeout 5000 -S -s tests/screenshots tests/acceptance", - "acceptance-firefox": "testcafe firefox:headless --skip-js-errors --quarantine-mode --selector-timeout 5000 -S -s tests/screenshots tests/acceptance", - "acceptance-private": "testcafe chromium:headless --skip-js-errors --quarantine-mode --selector-timeout 5000 -S -s tests/screenshots tests/acceptance-private", - "acceptance-private-smoke": "testcafe chromium:headless --skip-js-errors --quarantine-mode --test-meta type=smoke --selector-timeout 5000 -S -s tests/screenshots tests/acceptance-private", - "acceptance-private-firefox": "testcafe firefox:headless --skip-js-errors --quarantine-mode --selector-timeout 5000 -S -s tests/screenshots tests/acceptance-private", - "acceptance-local": "testcafe chromium --selector-timeout 5000 -S -s tests/screenshots tests/acceptance", + "acceptance": "testcafe $npm_config_first --skip-js-errors --quarantine-mode --selector-timeout 5000 -S -s tests/acceptance/screenshots --test-grep $npm_config_second --test-meta mode=$npm_config_third $npm_config_fourth", + "acceptance-short": "testcafe $npm_config_first --skip-js-errors --quarantine-mode --selector-timeout 5000 -S -s tests/acceptance/screenshots --test-grep $npm_config_second --test-meta mode=$npm_config_third,type=short $npm_config_fourth", + "acceptance-local": "testcafe chromium --selector-timeout 5000 -S -s tests/acceptance/screenshots tests/acceptance", "gettext-extract": "gettext-extract --output src/locales/translations.pot $(find src -type f \\( -iname \\*.vue -o -iname \\*.js \\) -not -path src/common/vm.js)", "gettext-compile": "gettext-compile --output src/locales/translations.json src/locales/*.po" }, diff --git a/frontend/tests/acceptance-private/authentication.js b/frontend/tests/acceptance-private/authentication.js deleted file mode 100644 index e263e12fb..000000000 --- a/frontend/tests/acceptance-private/authentication.js +++ /dev/null @@ -1,147 +0,0 @@ -import { Selector } from "testcafe"; -import testcafeconfig from "../acceptance/testcafeconfig"; -import Page from "../page-model/page"; -import Account from "../page-model/account"; -import Settings from "../page-model/settings"; -import Menu from "../page-model/menu"; - -fixture`Test authentication`.page`${testcafeconfig.url}`; - -const page = new Page(); -const account = new Account(); -const menu = new Menu(); -const settings = new Settings(); - -test.meta("testID", "authentication-001").meta({ type: "smoke" })("Login and Logout", async (t) => { - await t.navigateTo("/browse"); - - await t - .expect(page.nameInput.visible) - .ok() - .expect(Selector(".input-search input").visible) - .notOk(); - - await t.typeText(page.nameInput, "admin", { replace: true }); - - await t.expect(page.loginAction.hasAttribute("disabled", "disabled")).ok(); - - await t.typeText(page.passwordInput, "photoprism", { replace: true }); - - await t.expect(page.passwordInput.hasAttribute("type", "password")).ok(); - - await t.click(page.togglePasswordMode); - - await t.expect(page.passwordInput.hasAttribute("type", "text")).ok(); - - await t.click(page.togglePasswordMode); - - await t.expect(page.passwordInput.hasAttribute("type", "password")).ok(); - - await t.click(page.loginAction); - - await t.expect(Selector(".input-search input", { timeout: 7000 }).visible).ok(); - - await page.logout(); - - await t - .expect(page.nameInput.visible) - .ok() - .expect(Selector(".input-search input").visible) - .notOk(); - - await t.navigateTo("/settings"); - await t - .expect(page.nameInput.visible) - .ok() - .expect(Selector(".input-search input").visible) - .notOk(); -}); - -test.meta("testID", "authentication-002").meta({ type: "smoke" })( - "Login with wrong credentials", - async (t) => { - await page.login("wrong", "photoprism"); - await t.navigateTo("/favorites"); - - await t - .expect(page.nameInput.visible) - .ok() - .expect(Selector(".input-search input").visible) - .notOk(); - - await page.login("admin", "abcdefg"); - await t.navigateTo("/archive"); - - await t - .expect(page.nameInput.visible) - .ok() - .expect(Selector(".input-search input").visible) - .notOk(); - } -); - -test.meta("testID", "authentication-003").meta({ type: "smoke" })("Change password", async (t) => { - await t.navigateTo("/browse"); - await page.login("admin", "photoprism"); - await t.expect(Selector(".input-search input", { timeout: 15000 }).visible).ok(); - await menu.openPage("settings"); - - await t - .click(settings.accountTab) - .typeText(account.currentPassword, "wrong", { replace: true }) - .typeText(account.newPassword, "photoprism", { replace: true }); - - await t.expect(account.confirm.hasAttribute("disabled", "disabled")).ok(); - - await t.typeText(account.retypePassword, "photoprism", { replace: true }); - - await t.expect(account.confirm.hasAttribute("disabled", "disabled")).notOk(); - - await t - .click(account.confirm) - .typeText(account.currentPassword, "photoprism", { replace: true }) - .typeText(account.newPassword, "1234567", { replace: true }) - .typeText(account.retypePassword, "1234567", { replace: true }); - - await t.expect(account.confirm.hasAttribute("disabled", "disabled")).ok(); - - await t - .typeText(account.currentPassword, "photoprism", { replace: true }) - .typeText(account.newPassword, "photoprism123", { replace: true }); - - await t.expect(account.confirm.hasAttribute("disabled", "disabled")).ok(); - - await t.typeText(account.retypePassword, "photoprism123", { replace: true }); - - await t.expect(account.confirm.hasAttribute("disabled", "disabled")).notOk(); - - await t.click(account.confirm); - await page.logout(); - if (t.browser.platform === "mobile") { - await t.wait(7000); - } - await page.login("admin", "photoprism"); - await t.navigateTo("/archive"); - - await t - .expect(page.nameInput.visible) - .ok() - .expect(Selector(".input-search input").visible) - .notOk(); - - await page.login("admin", "photoprism123"); - await t.expect(Selector(".input-search input").visible).ok(); - await menu.openPage("settings"); - - await t - .click(settings.accountTab) - .typeText(account.currentPassword, "photoprism123", { replace: true }) - .typeText(account.newPassword, "photoprism", { replace: true }) - .typeText(account.retypePassword, "photoprism", { replace: true }) - .click(account.confirm); - await page.logout(); - await page.login("admin", "photoprism"); - - await t.expect(Selector(".input-search input").visible).ok(); - await page.logout(); -}); diff --git a/frontend/tests/acceptance-private/sharing.js b/frontend/tests/acceptance-private/sharing.js deleted file mode 100644 index 3ae8f7859..000000000 --- a/frontend/tests/acceptance-private/sharing.js +++ /dev/null @@ -1,196 +0,0 @@ -import { Selector } from "testcafe"; -import { Role } from "testcafe"; -import testcafeconfig from "../acceptance/testcafeconfig"; -import Page from "../page-model/page"; -import Menu from "../page-model/menu"; -import Toolbar from "../page-model/toolbar"; -import ContextMenu from "../page-model/context-menu"; -import Album from "../page-model/album"; -import PhotoViewer from "../page-model/photoviewer"; -import ShareDialog from "../page-model/dialog-share"; -import Photo from "../page-model/photo"; - -fixture`Test link sharing`.page`${testcafeconfig.url}`; - -const page = new Page(); -const menu = new Menu(); -const toolbar = new Toolbar(); -const contextmenu = new ContextMenu(); -const album = new Album(); -const photoviewer = new PhotoViewer(); -const sharedialog = new ShareDialog(); -const photo = new Photo(); - -test.skip.meta("testID", "authentication-000")( - "Time to start instance (will be marked as unstable)", - async (t) => { - await t.wait(5000); - } -); - -test.meta("testID", "sharing-001")("Create, view, delete shared albums", async (t) => { - await page.login("admin", "photoprism"); - await menu.openPage("albums"); - const FirstAlbumUid = await album.getNthAlbumUid("all", 0); - await album.triggerHoverAction("uid", FirstAlbumUid, "select"); - await contextmenu.checkContextMenuCount("1"); - await contextmenu.triggerContextMenuAction("share", ""); - await t.click(sharedialog.expandLink.nth(0)); - await t - .typeText(sharedialog.linkSecretInput, "secretForTesting", { replace: true }) - .click(sharedialog.linkExpireInput) - .click(Selector("div").withText("After 1 day").parent('div[role="listitem"]')) - .click(sharedialog.dialogSave); - const Url = await sharedialog.linkUrl.innerText; - const Expire = await Selector("div.v-select__selections").innerText; - - await t.expect(Url).contains("secretfortesting").expect(Expire).contains("After 1 day"); - let url = "http://localhost:2343/s/secretfortesting/christmas"; - await t.click(sharedialog.dialogClose); - await contextmenu.clearSelection(); - await album.openAlbumWithUid(FirstAlbumUid); - const photoCount = await photo.getPhotoCount("all"); - await t.expect(photoCount).eql(2); - await menu.openPage("folders"); - const FirstFolderUid = await album.getNthAlbumUid("all", 0); - await album.triggerHoverAction("uid", FirstFolderUid, "select"); - await contextmenu.checkContextMenuCount("1"); - await contextmenu.triggerContextMenuAction("share", ""); - await t.click(sharedialog.expandLink.nth(0)); - await t - .typeText(sharedialog.linkSecretInput, "secretForTesting", { replace: true }) - .click(sharedialog.linkExpireInput) - .click(Selector("div").withText("After 1 day").parent('div[role="listitem"]')) - .click(sharedialog.dialogSave) - .click(sharedialog.dialogSave); - await contextmenu.clearSelection(); - await t.navigateTo(url); - - await t.expect(toolbar.toolbarSecondTitle.withText("Christmas").visible).ok(); - - await t.click(Selector("button").withText("@photoprism_app")); - - await t.expect(toolbar.toolbarSecondTitle.withText("Albums").visible).ok(); - - const AlbumCount = await album.getAlbumCount("all"); - - await t.expect(AlbumCount).gte(40); - - await t.useRole(Role.anonymous()); - await t.navigateTo(url); - - await t.expect(toolbar.toolbarSecondTitle.withText("Christmas").visible).ok(); - const photoCountShared = await photo.getPhotoCount("all"); - //don't show private photo - await t.expect(photoCountShared).eql(1); - - await t.click(Selector("button").withText("@photoprism_app")); - - await t.expect(toolbar.toolbarSecondTitle.withText("Albums").visible).ok(); - - const AlbumCountAnonymous = await Selector("a.is-album").count; - - await t.expect(AlbumCountAnonymous).eql(2); - - await t.navigateTo("http://localhost:2343/browse"); - await page.login("admin", "photoprism"); - await menu.openPage("albums"); - await album.openAlbumWithUid(FirstAlbumUid); - await toolbar.triggerToolbarAction("share"); - await t - .click(sharedialog.expandLink.nth(0)) - .click(sharedialog.deleteLink) - .useRole(Role.anonymous()); - - await t.expect(Selector(".input-name input").visible).ok(); - - await t.navigateTo("http://localhost:2343/s/secretfortesting"); - - await t.expect(toolbar.toolbarSecondTitle.withText("Albums").visible).ok(); - - const AlbumCountAnonymousAfterDelete = await album.getAlbumCount("all"); - - await t.expect(AlbumCountAnonymousAfterDelete).eql(1); - - await t.navigateTo("http://localhost:2343/browse"); - await page.login("admin", "photoprism"); - await menu.openPage("folders"); - await album.openAlbumWithUid(FirstFolderUid); - await toolbar.triggerToolbarAction("share"); - await t - .click(sharedialog.expandLink.nth(0)) - .click(sharedialog.deleteLink) - .useRole(Role.anonymous()); - - await t.expect(Selector(".input-name input").visible).ok(); - - await t.navigateTo("http://localhost:2343/s/secretfortesting"); - - await t - .expect(toolbar.toolbarSecondTitle.withText("Christmas").visible) - .notOk() - .expect(toolbar.toolbarSecondTitle.withText("Albums").visible) - .notOk() - .expect(Selector(".input-name input").visible) - .ok(); -}); - -test.meta("testID", "sharing-002").meta({ type: "smoke" })( - "Verify anonymous user has limited options", - async (t) => { - await t.navigateTo("http://localhost:2343/s/jxoux5ub1e/british-columbia-canada"); - await t.expect(toolbar.toolbarSecondTitle.withText("British Columbia").visible).ok(); - - await toolbar.checkToolbarActionAvailability("edit", false); - await toolbar.checkToolbarActionAvailability("share", false); - await toolbar.checkToolbarActionAvailability("upload", false); - await toolbar.checkToolbarActionAvailability("reload", true); - await toolbar.checkToolbarActionAvailability("download", true); - - await photo.triggerHoverAction("nth", 0, "select"); - - await contextmenu.checkContextMenuActionAvailability("download", true); - await contextmenu.checkContextMenuActionAvailability("archive", false); - await contextmenu.checkContextMenuActionAvailability("private", false); - await contextmenu.checkContextMenuActionAvailability("edit", false); - await contextmenu.checkContextMenuActionAvailability("share", false); - await contextmenu.checkContextMenuActionAvailability("album", false); - - await contextmenu.clearSelection(); - - await photoviewer.openPhotoViewer("nth", 0); - - await photoviewer.checkPhotoViewerActionAvailability("download", true); - await photoviewer.checkPhotoViewerActionAvailability("select", true); - await photoviewer.checkPhotoViewerActionAvailability("toggle-fullscreen", true); - await photoviewer.checkPhotoViewerActionAvailability("slideshow", true); - await photoviewer.checkPhotoViewerActionAvailability("like", false); - await photoviewer.checkPhotoViewerActionAvailability("edit", false); - - await photoviewer.triggerPhotoViewerAction("close"); - - await photo.checkHoverActionAvailability("nth", 0, "favorite", false); - await photo.checkHoverActionAvailability("nth", 0, "select", true); - - await toolbar.triggerToolbarAction("view-list"); - - await t - .expect(Selector(`td button.input-private`).visible) - .notOk() - .expect(Selector(`td button.input-favorite`).visible) - .notOk() - .click(Selector("button").withText("@photoprism_app")) - .expect(toolbar.toolbarSecondTitle.withText("Albums").visible) - .ok(); - - const AlbumUid = await album.getNthAlbumUid("all", 0); - await album.triggerHoverAction("uid", AlbumUid, "select"); - - await contextmenu.checkContextMenuActionAvailability("download", true); - await contextmenu.checkContextMenuActionAvailability("delete", false); - await contextmenu.checkContextMenuActionAvailability("album", false); - await contextmenu.checkContextMenuActionAvailability("edit", false); - await contextmenu.checkContextMenuActionAvailability("share", false); - await contextmenu.clearSelection(); - } -); diff --git a/frontend/tests/acceptance/acceptance-private/authentication.js b/frontend/tests/acceptance/acceptance-private/authentication.js new file mode 100644 index 000000000..53e4785ea --- /dev/null +++ b/frontend/tests/acceptance/acceptance-private/authentication.js @@ -0,0 +1,153 @@ +import { Selector } from "testcafe"; +import testcafeconfig from "../acceptance-public/testcafeconfig"; +import Page from "../page-model/page"; +import Account from "../page-model/account"; +import Settings from "../page-model/settings"; +import Menu from "../page-model/menu"; + +fixture`Test authentication`.page`${testcafeconfig.url}`; + +const page = new Page(); +const account = new Account(); +const menu = new Menu(); +const settings = new Settings(); + +test.meta("testID", "authentication-001").meta({ type: "short", mode: "auth" })( + "Common: Login and Logout", + async (t) => { + await t.navigateTo("/browse"); + + await t + .expect(page.nameInput.visible) + .ok() + .expect(Selector(".input-search input").visible) + .notOk(); + + await t.typeText(page.nameInput, "admin", { replace: true }); + + await t.expect(page.loginAction.hasAttribute("disabled", "disabled")).ok(); + + await t.typeText(page.passwordInput, "photoprism", { replace: true }); + + await t.expect(page.passwordInput.hasAttribute("type", "password")).ok(); + + await t.click(page.togglePasswordMode); + + await t.expect(page.passwordInput.hasAttribute("type", "text")).ok(); + + await t.click(page.togglePasswordMode); + + await t.expect(page.passwordInput.hasAttribute("type", "password")).ok(); + + await t.click(page.loginAction); + + await t.expect(Selector(".input-search input", { timeout: 7000 }).visible).ok(); + + await page.logout(); + + await t + .expect(page.nameInput.visible) + .ok() + .expect(Selector(".input-search input").visible) + .notOk(); + + await t.navigateTo("/settings"); + await t + .expect(page.nameInput.visible) + .ok() + .expect(Selector(".input-search input").visible) + .notOk(); + } +); + +test.meta("testID", "authentication-002").meta({ type: "short", mode: "auth" })( + "Common: Login with wrong credentials", + async (t) => { + await page.login("wrong", "photoprism"); + await t.navigateTo("/favorites"); + + await t + .expect(page.nameInput.visible) + .ok() + .expect(Selector(".input-search input").visible) + .notOk(); + + await page.login("admin", "abcdefg"); + await t.navigateTo("/archive"); + + await t + .expect(page.nameInput.visible) + .ok() + .expect(Selector(".input-search input").visible) + .notOk(); + } +); + +test.meta("testID", "authentication-003").meta({ type: "short", mode: "auth" })( + "Common: Change password", + async (t) => { + await t.navigateTo("/browse"); + await page.login("admin", "photoprism"); + await t.expect(Selector(".input-search input", { timeout: 15000 }).visible).ok(); + await menu.openPage("settings"); + + await t + .click(settings.accountTab) + .typeText(account.currentPassword, "wrong", { replace: true }) + .typeText(account.newPassword, "photoprism", { replace: true }); + + await t.expect(account.confirm.hasAttribute("disabled", "disabled")).ok(); + + await t.typeText(account.retypePassword, "photoprism", { replace: true }); + + await t.expect(account.confirm.hasAttribute("disabled", "disabled")).notOk(); + + await t + .click(account.confirm) + .typeText(account.currentPassword, "photoprism", { replace: true }) + .typeText(account.newPassword, "1234567", { replace: true }) + .typeText(account.retypePassword, "1234567", { replace: true }); + + await t.expect(account.confirm.hasAttribute("disabled", "disabled")).ok(); + + await t + .typeText(account.currentPassword, "photoprism", { replace: true }) + .typeText(account.newPassword, "photoprism123", { replace: true }); + + await t.expect(account.confirm.hasAttribute("disabled", "disabled")).ok(); + + await t.typeText(account.retypePassword, "photoprism123", { replace: true }); + + await t.expect(account.confirm.hasAttribute("disabled", "disabled")).notOk(); + + await t.click(account.confirm); + await page.logout(); + if (t.browser.platform === "mobile") { + await t.wait(7000); + } + await page.login("admin", "photoprism"); + await t.navigateTo("/archive"); + + await t + .expect(page.nameInput.visible) + .ok() + .expect(Selector(".input-search input").visible) + .notOk(); + + await page.login("admin", "photoprism123"); + await t.expect(Selector(".input-search input").visible).ok(); + await menu.openPage("settings"); + + await t + .click(settings.accountTab) + .typeText(account.currentPassword, "photoprism123", { replace: true }) + .typeText(account.newPassword, "photoprism", { replace: true }) + .typeText(account.retypePassword, "photoprism", { replace: true }) + .click(account.confirm); + await page.logout(); + await page.login("admin", "photoprism"); + + await t.expect(Selector(".input-search input").visible).ok(); + await page.logout(); + } +); diff --git a/frontend/tests/acceptance/acceptance-private/sharing.js b/frontend/tests/acceptance/acceptance-private/sharing.js new file mode 100644 index 000000000..8f0f7a072 --- /dev/null +++ b/frontend/tests/acceptance/acceptance-private/sharing.js @@ -0,0 +1,199 @@ +import { Selector } from "testcafe"; +import { Role } from "testcafe"; +import testcafeconfig from "../acceptance-public/testcafeconfig"; +import Page from "../page-model/page"; +import Menu from "../page-model/menu"; +import Toolbar from "../page-model/toolbar"; +import ContextMenu from "../page-model/context-menu"; +import Album from "../page-model/album"; +import PhotoViewer from "../page-model/photoviewer"; +import ShareDialog from "../page-model/dialog-share"; +import Photo from "../page-model/photo"; + +fixture`Test link sharing`.page`${testcafeconfig.url}`; + +const page = new Page(); +const menu = new Menu(); +const toolbar = new Toolbar(); +const contextmenu = new ContextMenu(); +const album = new Album(); +const photoviewer = new PhotoViewer(); +const sharedialog = new ShareDialog(); +const photo = new Photo(); + +test.skip.meta("testID", "authentication-000")( + "Time to start instance (will be marked as unstable)", + async (t) => { + await t.wait(5000); + } +); + +test.meta("testID", "sharing-001").meta({ mode: "auth" })( + "Common: Create, view, delete shared albums", + async (t) => { + await page.login("admin", "photoprism"); + await menu.openPage("albums"); + const FirstAlbumUid = await album.getNthAlbumUid("all", 0); + await album.triggerHoverAction("uid", FirstAlbumUid, "select"); + await contextmenu.checkContextMenuCount("1"); + await contextmenu.triggerContextMenuAction("share", ""); + await t.click(sharedialog.expandLink.nth(0)); + await t + .typeText(sharedialog.linkSecretInput, "secretForTesting", { replace: true }) + .click(sharedialog.linkExpireInput) + .click(Selector("div").withText("After 1 day").parent('div[role="listitem"]')) + .click(sharedialog.dialogSave); + const Url = await sharedialog.linkUrl.innerText; + const Expire = await Selector("div.v-select__selections").innerText; + + await t.expect(Url).contains("secretfortesting").expect(Expire).contains("After 1 day"); + let url = "http://localhost:2343/s/secretfortesting/christmas"; + await t.click(sharedialog.dialogClose); + await contextmenu.clearSelection(); + await album.openAlbumWithUid(FirstAlbumUid); + const photoCount = await photo.getPhotoCount("all"); + await t.expect(photoCount).eql(2); + await menu.openPage("folders"); + const FirstFolderUid = await album.getNthAlbumUid("all", 0); + await album.triggerHoverAction("uid", FirstFolderUid, "select"); + await contextmenu.checkContextMenuCount("1"); + await contextmenu.triggerContextMenuAction("share", ""); + await t.click(sharedialog.expandLink.nth(0)); + await t + .typeText(sharedialog.linkSecretInput, "secretForTesting", { replace: true }) + .click(sharedialog.linkExpireInput) + .click(Selector("div").withText("After 1 day").parent('div[role="listitem"]')) + .click(sharedialog.dialogSave) + .click(sharedialog.dialogSave); + await contextmenu.clearSelection(); + await t.navigateTo(url); + + await t.expect(toolbar.toolbarSecondTitle.withText("Christmas").visible).ok(); + + await t.click(Selector("button").withText("@photoprism_app")); + + await t.expect(toolbar.toolbarSecondTitle.withText("Albums").visible).ok(); + + const AlbumCount = await album.getAlbumCount("all"); + + await t.expect(AlbumCount).gte(40); + + await t.useRole(Role.anonymous()); + await t.navigateTo(url); + + await t.expect(toolbar.toolbarSecondTitle.withText("Christmas").visible).ok(); + const photoCountShared = await photo.getPhotoCount("all"); + //don't show private photo + await t.expect(photoCountShared).eql(1); + + await t.click(Selector("button").withText("@photoprism_app")); + + await t.expect(toolbar.toolbarSecondTitle.withText("Albums").visible).ok(); + + const AlbumCountAnonymous = await Selector("a.is-album").count; + + await t.expect(AlbumCountAnonymous).eql(2); + + await t.navigateTo("http://localhost:2343/browse"); + await page.login("admin", "photoprism"); + await menu.openPage("albums"); + await album.openAlbumWithUid(FirstAlbumUid); + await toolbar.triggerToolbarAction("share"); + await t + .click(sharedialog.expandLink.nth(0)) + .click(sharedialog.deleteLink) + .useRole(Role.anonymous()); + + await t.expect(Selector(".input-name input").visible).ok(); + + await t.navigateTo("http://localhost:2343/s/secretfortesting"); + + await t.expect(toolbar.toolbarSecondTitle.withText("Albums").visible).ok(); + + const AlbumCountAnonymousAfterDelete = await album.getAlbumCount("all"); + + await t.expect(AlbumCountAnonymousAfterDelete).eql(1); + + await t.navigateTo("http://localhost:2343/browse"); + await page.login("admin", "photoprism"); + await menu.openPage("folders"); + await album.openAlbumWithUid(FirstFolderUid); + await toolbar.triggerToolbarAction("share"); + await t + .click(sharedialog.expandLink.nth(0)) + .click(sharedialog.deleteLink) + .useRole(Role.anonymous()); + + await t.expect(Selector(".input-name input").visible).ok(); + + await t.navigateTo("http://localhost:2343/s/secretfortesting"); + + await t + .expect(toolbar.toolbarSecondTitle.withText("Christmas").visible) + .notOk() + .expect(toolbar.toolbarSecondTitle.withText("Albums").visible) + .notOk() + .expect(Selector(".input-name input").visible) + .ok(); + } +); + +test.meta("testID", "sharing-002").meta({ type: "short", mode: "auth" })( + "Common: Verify anonymous user has limited options", + async (t) => { + await t.navigateTo("http://localhost:2343/s/jxoux5ub1e/british-columbia-canada"); + await t.expect(toolbar.toolbarSecondTitle.withText("British Columbia").visible).ok(); + + await toolbar.checkToolbarActionAvailability("edit", false); + await toolbar.checkToolbarActionAvailability("share", false); + await toolbar.checkToolbarActionAvailability("upload", false); + await toolbar.checkToolbarActionAvailability("reload", true); + await toolbar.checkToolbarActionAvailability("download", true); + + await photo.triggerHoverAction("nth", 0, "select"); + + await contextmenu.checkContextMenuActionAvailability("download", true); + await contextmenu.checkContextMenuActionAvailability("archive", false); + await contextmenu.checkContextMenuActionAvailability("private", false); + await contextmenu.checkContextMenuActionAvailability("edit", false); + await contextmenu.checkContextMenuActionAvailability("share", false); + await contextmenu.checkContextMenuActionAvailability("album", false); + + await contextmenu.clearSelection(); + + await photoviewer.openPhotoViewer("nth", 0); + + await photoviewer.checkPhotoViewerActionAvailability("download", true); + await photoviewer.checkPhotoViewerActionAvailability("select", true); + await photoviewer.checkPhotoViewerActionAvailability("toggle-fullscreen", true); + await photoviewer.checkPhotoViewerActionAvailability("slideshow", true); + await photoviewer.checkPhotoViewerActionAvailability("like", false); + await photoviewer.checkPhotoViewerActionAvailability("edit", false); + + await photoviewer.triggerPhotoViewerAction("close"); + + await photo.checkHoverActionAvailability("nth", 0, "favorite", false); + await photo.checkHoverActionAvailability("nth", 0, "select", true); + + await toolbar.triggerToolbarAction("view-list"); + + await t + .expect(Selector(`td button.input-private`).visible) + .notOk() + .expect(Selector(`td button.input-favorite`).visible) + .notOk() + .click(Selector("button").withText("@photoprism_app")) + .expect(toolbar.toolbarSecondTitle.withText("Albums").visible) + .ok(); + + const AlbumUid = await album.getNthAlbumUid("all", 0); + await album.triggerHoverAction("uid", AlbumUid, "select"); + + await contextmenu.checkContextMenuActionAvailability("download", true); + await contextmenu.checkContextMenuActionAvailability("delete", false); + await contextmenu.checkContextMenuActionAvailability("album", false); + await contextmenu.checkContextMenuActionAvailability("edit", false); + await contextmenu.checkContextMenuActionAvailability("share", false); + await contextmenu.clearSelection(); + } +); diff --git a/frontend/tests/acceptance-private/testcafeconfig.json b/frontend/tests/acceptance/acceptance-private/testcafeconfig.json similarity index 100% rename from frontend/tests/acceptance-private/testcafeconfig.json rename to frontend/tests/acceptance/acceptance-private/testcafeconfig.json diff --git a/frontend/tests/acceptance/acceptance-public/albums.js b/frontend/tests/acceptance/acceptance-public/albums.js new file mode 100644 index 000000000..7b4b45751 --- /dev/null +++ b/frontend/tests/acceptance/acceptance-public/albums.js @@ -0,0 +1,221 @@ +import { Selector } from "testcafe"; +import testcafeconfig from "./testcafeconfig"; +import Menu from "../page-model/menu"; +import Album from "../page-model/album"; +import Toolbar from "../page-model/toolbar"; +import ContextMenu from "../page-model/context-menu"; +import Photo from "../page-model/photo"; +import PhotoViewer from "../page-model/photoviewer"; +import Page from "../page-model/page"; +import AlbumDialog from "../page-model/dialog-album"; + +fixture`Test albums`.page`${testcafeconfig.url}`; + +const menu = new Menu(); +const album = new Album(); +const toolbar = new Toolbar(); +const contextmenu = new ContextMenu(); +const photo = new Photo(); +const photoviewer = new PhotoViewer(); +const page = new Page(); +const albumdialog = new AlbumDialog(); + +test.meta("testID", "authentication-000").meta({ type: "short", mode: "public" })( + "Common: Time to start instance (will be marked as unstable)", + async (t) => { + await t.wait(5000); + } +); + +test.meta("testID", "albums-001").meta({ type: "short", mode: "public" })( + "Common: Create/delete album on /albums", + async (t) => { + await menu.openPage("albums"); + const AlbumCount = await album.getAlbumCount("all"); + await toolbar.triggerToolbarAction("add"); + const AlbumCountAfterCreate = await album.getAlbumCount("all"); + const NewAlbumUid = await album.getNthAlbumUid("all", 0); + + await t.expect(AlbumCountAfterCreate).eql(AlbumCount + 1); + + await album.selectAlbumFromUID(NewAlbumUid); + await contextmenu.triggerContextMenuAction("delete", ""); + const AlbumCountAfterDelete = await album.getAlbumCount("all"); + + await t.expect(AlbumCountAfterDelete).eql(AlbumCountAfterCreate - 1); + } +); + +test.meta("testID", "albums-002").meta({ type: "short", mode: "public" })( + "Common: Create/delete album during add to album", + async (t) => { + await menu.openPage("albums"); + const AlbumCount = await album.getAlbumCount("all"); + await menu.openPage("browse"); + await toolbar.search("photo:true"); + const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); + const SecondPhotoUid = await photo.getNthPhotoUid("image", 1); + await photo.selectPhotoFromUID(SecondPhotoUid); + await photo.selectPhotoFromUID(FirstPhotoUid); + await contextmenu.triggerContextMenuAction("album", "NotYetExistingAlbum"); + await menu.openPage("albums"); + const AlbumCountAfterCreation = await album.getAlbumCount("all"); + + await t.expect(AlbumCountAfterCreation).eql(AlbumCount + 1); + + await toolbar.search("NotYetExistingAlbum"); + const AlbumUid = await album.getNthAlbumUid("all", 0); + await album.selectAlbumFromUID(AlbumUid); + await contextmenu.triggerContextMenuAction("delete", ""); + await menu.openPage("albums"); + const AlbumCountAfterDelete = await album.getAlbumCount("all"); + + await t.expect(AlbumCountAfterDelete).eql(AlbumCount); + } +); + +test.meta("testID", "albums-003").meta({ type: "short", mode: "public" })( + "Common: Update album details", + async (t) => { + await menu.openPage("albums"); + await toolbar.search("Holiday"); + const AlbumUid = await album.getNthAlbumUid("all", 0); + + await t.expect(page.cardTitle.nth(0).innerText).contains("Holiday"); + + await t.click(page.cardTitle.nth(0)).typeText(albumdialog.title, "Animals", { replace: true }); + + await t + .expect(albumdialog.description.value) + .eql("") + .expect(albumdialog.category.value) + .eql(""); + + await t + .typeText(albumdialog.description, "All my animals") + .typeText(albumdialog.category, "Pets") + .pressKey("enter") + .click(albumdialog.dialogSave); + + await t.expect(page.cardTitle.nth(0).innerText).contains("Animals"); + + await album.openAlbumWithUid(AlbumUid); + await toolbar.triggerToolbarAction("edit"); + await t.typeText(albumdialog.title, "Holiday", { replace: true }); + + await t + .expect(albumdialog.description.value) + .eql("All my animals") + .expect(albumdialog.category.value) + .eql("Pets"); + + await t + .click(albumdialog.description) + .pressKey("ctrl+a delete") + .pressKey("enter") + .click(albumdialog.category) + .pressKey("ctrl+a delete") + .pressKey("enter") + .click(albumdialog.dialogSave); + await menu.openPage("albums"); + + await t + .expect(Selector("div").withText("Holiday").visible) + .ok() + .expect(Selector("div").withText("Animals").exists) + .notOk(); + } +); + +test.meta("testID", "albums-004").meta({ type: "short", mode: "public" })( + "Common: Add/Remove Photos to/from album", + async (t) => { + await menu.openPage("albums"); + await toolbar.search("Holiday"); + const AlbumUid = await album.getNthAlbumUid("all", 0); + await album.openAlbumWithUid(AlbumUid); + const PhotoCount = await photo.getPhotoCount("all"); + await menu.openPage("browse"); + await toolbar.search("photo:true"); + const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); + const SecondPhotoUid = await photo.getNthPhotoUid("image", 1); + await photo.selectPhotoFromUID(SecondPhotoUid); + await photoviewer.openPhotoViewer("uid", FirstPhotoUid); + await photoviewer.triggerPhotoViewerAction("select"); + await photoviewer.triggerPhotoViewerAction("close"); + await contextmenu.triggerContextMenuAction("album", "Holiday"); + await menu.openPage("albums"); + await album.openAlbumWithUid(AlbumUid); + const PhotoCountAfterAdd = await photo.getPhotoCount("all"); + + await t.expect(PhotoCountAfterAdd).eql(PhotoCount + 2); + + await photo.selectPhotoFromUID(FirstPhotoUid); + await photo.selectPhotoFromUID(SecondPhotoUid); + await contextmenu.triggerContextMenuAction("remove", ""); + const PhotoCountAfterRemove = await photo.getPhotoCount("all"); + + await t.expect(PhotoCountAfterRemove).eql(PhotoCountAfterAdd - 2); + } +); + +test.meta("testID", "albums-005").meta({ mode: "public" })( + "Common: Use album search and filters", + async (t) => { + await menu.openPage("albums"); + if (t.browser.platform === "mobile") { + await toolbar.search("category:Family"); + } else { + await toolbar.setFilter("category", "Family"); + } + + await t.expect(page.cardTitle.nth(0).innerText).contains("Christmas"); + const AlbumCount = await album.getAlbumCount("all"); + await t.expect(AlbumCount).eql(1); + + if (t.browser.platform === "mobile") { + } else { + await toolbar.setFilter("category", "All Categories"); + } + + await toolbar.search("Holiday"); + + await t.expect(page.cardTitle.nth(0).innerText).contains("Holiday"); + const AlbumCount2 = await album.getAlbumCount("all"); + await t.expect(AlbumCount2).eql(1); + } +); + +test.meta("testID", "albums-006").meta({ mode: "public" })( + "Common: Test album autocomplete", + async (t) => { + await toolbar.search("photo:true"); + const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); + await photo.selectPhotoFromUID(FirstPhotoUid); + await contextmenu.openContextMenu(); + await t.click(Selector("button.action-album")).click(Selector(".input-album input")); + + await t + .expect(page.selectOption.withText("Holiday").visible) + .ok() + .expect(page.selectOption.withText("Christmas").visible) + .ok(); + + await t.typeText(Selector(".input-album input"), "C", { replace: true }); + + await t + .expect(page.selectOption.withText("Holiday").visible) + .notOk() + .expect(page.selectOption.withText("Christmas").visible) + .ok() + .expect(page.selectOption.withText("C").visible) + .ok(); + } +); + +test.meta("testID", "albums-007").meta({ type: "short", mode: "public" })( + "Common: Create, Edit, delete sharing link", + async (t) => { + await page.testCreateEditDeleteSharingLink("albums"); + } +); diff --git a/frontend/tests/acceptance/acceptance-public/calendar.js b/frontend/tests/acceptance/acceptance-public/calendar.js new file mode 100644 index 000000000..bf1a94453 --- /dev/null +++ b/frontend/tests/acceptance/acceptance-public/calendar.js @@ -0,0 +1,163 @@ +import { Selector } from "testcafe"; +import testcafeconfig from "./testcafeconfig"; +import Menu from "../page-model/menu"; +import Album from "../page-model/album"; +import Toolbar from "../page-model/toolbar"; +import ContextMenu from "../page-model/context-menu"; +import Photo from "../page-model/photo"; +import Page from "../page-model/page"; +import AlbumDialog from "../page-model/dialog-album"; + +fixture`Test calendar`.page`${testcafeconfig.url}`; + +const menu = new Menu(); +const album = new Album(); +const toolbar = new Toolbar(); +const contextmenu = new ContextMenu(); +const photo = new Photo(); +const page = new Page(); +const albumdialog = new AlbumDialog(); + +test.meta("testID", "calendar-001").meta({ type: "short", mode: "public" })( + "Common: View calendar", + async (t) => { + await menu.openPage("calendar"); + + await t + .expect(Selector("a").withText("May 2019").visible) + .ok() + .expect(Selector("a").withText("October 2019").visible) + .ok(); + } +); + +test.meta("testID", "calendar-002").meta({ mode: "public" })( + "Common: Update calendar details", + async (t) => { + await menu.openPage("calendar"); + await toolbar.search("March 2014"); + const AlbumUid = await album.getNthAlbumUid("all", 0); + + await t.expect(page.cardTitle.nth(0).innerText).contains("March 2014"); + + await t.click(page.cardTitle.nth(0)).typeText(albumdialog.location, "Snow", { replace: true }); + + await t + .expect(albumdialog.description.value) + .eql("") + .expect(albumdialog.category.value) + .eql(""); + + await t + .typeText(albumdialog.description, "We went to ski") + .typeText(albumdialog.category, "Mountains") + .pressKey("enter") + .click(albumdialog.dialogSave); + + await t + .expect(page.cardTitle.nth(0).innerText) + .contains("March 2014") + .expect(page.cardDescription.nth(0).innerText) + .contains("We went to ski") + .expect(Selector("div.caption").nth(1).innerText) + .contains("Mountains") + .expect(Selector("div.caption").nth(2).innerText) + .contains("Snow"); + + await album.openNthAlbum(0); + + await t.expect(toolbar.toolbarSecondTitle.innerText).contains("March 2014"); + await t.expect(toolbar.toolbarDescription.innerText).contains("We went to ski"); + await menu.openPage("calendar"); + if (t.browser.platform === "mobile") { + await toolbar.search("category:Mountains"); + } else { + await toolbar.setFilter("category", "Mountains"); + } + + await t.expect(page.cardTitle.nth(0).innerText).contains("March 2014"); + + await album.openAlbumWithUid(AlbumUid); + await toolbar.triggerToolbarAction("edit"); + + await t + .expect(albumdialog.description.value) + .eql("We went to ski") + .expect(albumdialog.category.value) + .eql("Mountains") + .expect(albumdialog.location.value) + .eql("Snow"); + + await t + .click(albumdialog.category) + .pressKey("ctrl+a delete") + .pressKey("enter") + .click(albumdialog.description) + .pressKey("ctrl+a delete") + .pressKey("enter") + .click(albumdialog.location) + .pressKey("ctrl+a delete") + .pressKey("enter") + .click(albumdialog.dialogSave); + await menu.openPage("calendar"); + await toolbar.search("March 2014"); + + await t + .expect(page.cardDescription.innerText) + .notContains("We went to ski") + .expect(Selector("div.caption").nth(0).innerText) + .notContains("Snow"); + } +); + +test.meta("testID", "calendar-003").meta({ mode: "public" })( + "Common: Create, Edit, delete sharing link for calendar", + async (t) => { + await page.testCreateEditDeleteSharingLink("calendar"); + } +); + +test.meta("testID", "calendar-004").meta({ type: "short", mode: "public" })( + "Common: Create/delete album-clone from calendar", + async (t) => { + await menu.openPage("albums"); + const AlbumCount = await album.getAlbumCount("all"); + await menu.openPage("calendar"); + const SecondCalendarUid = await album.getNthAlbumUid("all", 1); + await album.openAlbumWithUid(SecondCalendarUid); + const PhotoCountInCalendar = await photo.getPhotoCount("all"); + const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); + const SecondPhotoUid = await photo.getNthPhotoUid("image", 1); + await menu.openPage("calendar"); + await album.selectAlbumFromUID(SecondCalendarUid); + await contextmenu.triggerContextMenuAction("clone", "NotYetExistingAlbumForCalendar"); + await menu.openPage("albums"); + const AlbumCountAfterCreation = await album.getAlbumCount("all"); + + await t.expect(AlbumCountAfterCreation).eql(AlbumCount + 1); + + await toolbar.search("NotYetExistingAlbumForCalendar"); + const AlbumUid = await album.getNthAlbumUid("all", 0); + await album.openAlbumWithUid(AlbumUid); + const PhotoCountInAlbum = await photo.getPhotoCount("all"); + + await t.expect(PhotoCountInAlbum).eql(PhotoCountInCalendar); + + await photo.checkPhotoVisibility(FirstPhotoUid, true); + await photo.checkPhotoVisibility(SecondPhotoUid, true); + await menu.openPage("albums"); + await album.selectAlbumFromUID(AlbumUid); + await contextmenu.triggerContextMenuAction("delete", ""); + if (t.browser.platform === "mobile") { + await t.eval(() => location.reload()); + } else { + await toolbar.triggerToolbarAction("reload"); + } + const AlbumCountAfterDelete = await album.getAlbumCount("all"); + await t.expect(AlbumCountAfterDelete).eql(AlbumCount); + await menu.openPage("calendar"); + await album.openAlbumWithUid(SecondCalendarUid); + await photo.checkPhotoVisibility(FirstPhotoUid, true); + await photo.checkPhotoVisibility(SecondPhotoUid, true); + } +); diff --git a/frontend/tests/acceptance/acceptance-public/components.js b/frontend/tests/acceptance/acceptance-public/components.js new file mode 100644 index 000000000..5af829242 --- /dev/null +++ b/frontend/tests/acceptance/acceptance-public/components.js @@ -0,0 +1,73 @@ +import { Selector } from "testcafe"; +import testcafeconfig from "./testcafeconfig"; +import Toolbar from "../page-model/toolbar"; + +fixture`Test components`.page`${testcafeconfig.url}`; + +const toolbar = new Toolbar(); + +test.meta("testID", "components-001").meta({ type: "short", mode: "public" })( + "Common: Test filter options", + async (t) => { + await t.expect(Selector("body").withText("object Object").exists).notOk(); + } +); + +test.meta("testID", "components-002").meta({ type: "short", mode: "public" })( + "Common: Fullscreen mode", + async (t) => { + await t.click(Selector("div.type-image div.image.clickable").nth(0)); + + if (await Selector("#photo-viewer").visible) { + await t + .expect(Selector("#photo-viewer").visible) + .ok() + .expect(Selector("img.pswp__img").visible) + .ok(); + } else { + await t.expect(Selector("div.video-viewer").visible).ok(); + } + } +); + +test.meta("testID", "components-003").meta({ type: "short", mode: "public" })( + "Common: Mosaic view", + async (t) => { + await toolbar.setFilter("view", "Mosaic"); + + await t + .expect(Selector("div.type-image.image.clickable").visible) + .ok() + .expect(Selector("div.p-photo-mosaic").visible) + .ok() + .expect(Selector("div.is-photo div.caption").exists) + .notOk() + .expect(Selector("#photo-viewer").visible) + .notOk(); + } +); + +test.meta("testID", "components-004").meta({ mode: "public" })("Common: List view", async (t) => { + await toolbar.setFilter("view", "List"); + + await t + .expect(Selector("table.v-datatable").visible) + .ok() + .expect(Selector("div.list-view").visible) + .ok(); +}); + +test.meta("testID", "components-005").meta({ type: "short", mode: "public" })( + "Common: Card view", + async (t) => { + await toolbar.setFilter("view", "Cards"); + + await t + .expect(Selector("div.type-image div.image.clickable").visible) + .ok() + .expect(Selector("div.is-photo div.caption").visible) + .ok() + .expect(Selector("#photo-viewer").visible) + .notOk(); + } +); diff --git a/frontend/tests/acceptance/acceptance-public/folders.js b/frontend/tests/acceptance/acceptance-public/folders.js new file mode 100644 index 000000000..e74c99cc6 --- /dev/null +++ b/frontend/tests/acceptance/acceptance-public/folders.js @@ -0,0 +1,171 @@ +import { Selector } from "testcafe"; +import testcafeconfig from "./testcafeconfig"; +import Menu from "../page-model/menu"; +import Album from "../page-model/album"; +import Toolbar from "../page-model/toolbar"; +import ContextMenu from "../page-model/context-menu"; +import Photo from "../page-model/photo"; +import Page from "../page-model/page"; +import AlbumDialog from "../page-model/dialog-album"; + +fixture`Test folders`.page`${testcafeconfig.url}`; + +const menu = new Menu(); +const album = new Album(); +const toolbar = new Toolbar(); +const contextmenu = new ContextMenu(); +const photo = new Photo(); +const page = new Page(); +const albumdialog = new AlbumDialog(); + +test.meta("testID", "folders-001").meta({ type: "short", mode: "public" })( + "Common: View folders", + async (t) => { + await menu.openPage("folders"); + + await t + .expect(Selector("a").withText("BotanicalGarden").visible) + .ok() + .expect(Selector("a").withText("Kanada").visible) + .ok() + .expect(Selector("a").withText("KorsikaAdventure").visible) + .ok(); + } +); + +test.meta("testID", "folders-002").meta({ mode: "public" })( + "Common: Update folder details", + async (t) => { + await menu.openPage("folders"); + await toolbar.search("Kanada"); + const AlbumUid = await album.getNthAlbumUid("all", 0); + await t.expect(page.cardTitle.nth(0).innerText).contains("Kanada"); + + await t.click(page.cardTitle.nth(0)); + + await t + .expect(albumdialog.title.value) + .eql("Kanada") + .expect(albumdialog.location.value) + .eql("") + .expect(albumdialog.description.value) + .eql("") + .expect(albumdialog.category.value) + .eql(""); + + await t + .typeText(albumdialog.title, "MyFolder", { replace: true }) + .typeText(albumdialog.location, "USA", { replace: true }) + .typeText(albumdialog.description, "Last holiday") + .typeText(albumdialog.category, "Mountains") + .pressKey("enter") + .click(albumdialog.dialogSave); + + await t + .expect(page.cardTitle.nth(0).innerText) + .contains("MyFolder") + .expect(page.cardDescription.nth(0).innerText) + .contains("Last holiday") + .expect(Selector("div.caption").nth(1).innerText) + .contains("Mountains") + .expect(Selector("div.caption").nth(2).innerText) + .contains("USA"); + + await album.openNthAlbum(0); + + await t + .expect(toolbar.toolbarDescription.nth(0).innerText) + .contains("Last holiday") + .expect(toolbar.toolbarSecondTitle.innerText) + .contains("MyFolder"); + + await menu.openPage("folders"); + if (t.browser.platform === "mobile") { + await toolbar.search("category:Mountains"); + } else { + await toolbar.setFilter("category", "Mountains"); + } + + await t.expect(page.cardTitle.nth(0).innerText).contains("MyFolder"); + + await album.openAlbumWithUid(AlbumUid); + await toolbar.triggerToolbarAction("edit"); + + await t + .expect(albumdialog.description.value) + .eql("Last holiday") + .expect(albumdialog.category.value) + .eql("Mountains") + .expect(albumdialog.location.value) + .eql("USA"); + + await t + .typeText(albumdialog.title, "Kanada", { replace: true }) + .click(albumdialog.category) + .pressKey("ctrl+a delete") + .pressKey("enter") + .click(albumdialog.description) + .pressKey("ctrl+a delete") + .pressKey("enter") + .click(albumdialog.location) + .pressKey("ctrl+a delete") + .pressKey("enter") + .click(albumdialog.dialogSave); + await menu.openPage("folders"); + await toolbar.search("Kanada"); + + await t + .expect(page.cardTitle.nth(0).innerText) + .contains("Kanada") + .expect(page.cardDescription.nth(0).innerText) + .notContains("We went to ski") + .expect(Selector("div.caption").nth(0).innerText) + .notContains("USA"); + } +); + +test.meta("testID", "folders-003").meta({ mode: "public" })( + "Common: Create, Edit, delete sharing link", + async (t) => { + await page.testCreateEditDeleteSharingLink("folders"); + } +); + +test.meta("testID", "folders-004").meta({ mode: "public" })( + "Common: Create/delete album-clone from folder", + async (t) => { + await menu.openPage("albums"); + const AlbumCount = await album.getAlbumCount("all"); + await menu.openPage("folders"); + const ThirdFolderUid = await album.getNthAlbumUid("all", 2); + await album.openAlbumWithUid(ThirdFolderUid); + const PhotoCountInFolder = await photo.getPhotoCount("all"); + const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); + await menu.openPage("folders"); + await album.selectAlbumFromUID(ThirdFolderUid); + await contextmenu.triggerContextMenuAction("clone", "NotYetExistingAlbumForFolder"); + await menu.openPage("albums"); + const AlbumCountAfterCreation = await album.getAlbumCount("all"); + + await t.expect(AlbumCountAfterCreation).eql(AlbumCount + 1); + + await toolbar.search("NotYetExistingAlbumForFolder"); + const AlbumUid = await album.getNthAlbumUid("all", 0); + await album.openAlbumWithUid(AlbumUid); + const PhotoCountInAlbum = await photo.getPhotoCount("all"); + + await t.expect(PhotoCountInAlbum).eql(PhotoCountInFolder); + + await photo.checkPhotoVisibility(FirstPhotoUid, true); + await menu.openPage("albums"); + await album.selectAlbumFromUID(AlbumUid); + await contextmenu.triggerContextMenuAction("delete", ""); + const AlbumCountAfterDelete = await album.getAlbumCount("all"); + + await t.expect(AlbumCountAfterDelete).eql(AlbumCount); + + await menu.openPage("folders"); + await album.openAlbumWithUid(ThirdFolderUid); + await photo.checkPhotoVisibility(FirstPhotoUid, true); + } +); diff --git a/frontend/tests/acceptance/labels.js b/frontend/tests/acceptance/acceptance-public/labels.js similarity index 65% rename from frontend/tests/acceptance/labels.js rename to frontend/tests/acceptance/acceptance-public/labels.js index caffeb99b..8796ae570 100644 --- a/frontend/tests/acceptance/labels.js +++ b/frontend/tests/acceptance/acceptance-public/labels.js @@ -20,8 +20,8 @@ const page = new Page(); const label = new Label(); const photoedit = new PhotoEdit(); -test.meta("testID", "labels-001").meta({ type: "smoke" })( - "Remove/Activate Add/Delete Label from photo", +test.meta("testID", "labels-001").meta({ type: "short", mode: "public" })( + "Common: Remove/Activate Add/Delete Label from photo", async (t) => { await menu.openPage("labels"); await toolbar.search("beacon"); @@ -83,21 +83,24 @@ test.meta("testID", "labels-001").meta({ type: "smoke" })( } ); -test.meta("testID", "labels-002")("Toggle between important and all labels", async (t) => { - await menu.openPage("labels"); - const ImportantLabelsCount = await label.getLabelCount(); - await toolbar.triggerToolbarAction("show-all"); - const AllLabelsCount = await label.getLabelCount(); +test.meta("testID", "labels-002").meta({ mode: "public" })( + "Common: Toggle between important and all labels", + async (t) => { + await menu.openPage("labels"); + const ImportantLabelsCount = await label.getLabelCount(); + await toolbar.triggerToolbarAction("show-all"); + const AllLabelsCount = await label.getLabelCount(); - await t.expect(AllLabelsCount).gt(ImportantLabelsCount); + await t.expect(AllLabelsCount).gt(ImportantLabelsCount); - await toolbar.triggerToolbarAction("show-important"); - const ImportantLabelsCount2 = await label.getLabelCount(); + await toolbar.triggerToolbarAction("show-important"); + const ImportantLabelsCount2 = await label.getLabelCount(); - await t.expect(ImportantLabelsCount).eql(ImportantLabelsCount2); -}); + await t.expect(ImportantLabelsCount).eql(ImportantLabelsCount2); + } +); -test.meta("testID", "labels-003")("Rename Label", async (t) => { +test.meta("testID", "labels-003").meta({ mode: "public" })("Common: Rename Label", async (t) => { await menu.openPage("labels"); await toolbar.search("zebra"); const LabelZebraUid = await label.getNthLabeltUid(0); @@ -147,45 +150,48 @@ test.meta("testID", "labels-003")("Rename Label", async (t) => { await t.expect(Selector("div.no-results").visible).ok(); }); -test.meta("testID", "labels-003")("Add label to album", async (t) => { - await menu.openPage("albums"); - await toolbar.search("Christmas"); - const AlbumUid = await album.getNthAlbumUid("all", 0); - await album.openAlbumWithUid(AlbumUid); - const PhotoCount = await photo.getPhotoCount("all"); - await menu.openPage("labels"); - await toolbar.search("landscape"); - const LabelLandscape = await label.getNthLabeltUid(1); - await label.openLabelWithUid(LabelLandscape); - const FirstPhotoLandscape = await photo.getNthPhotoUid("all", 0); - const SecondPhotoLandscape = await photo.getNthPhotoUid("all", 1); - const ThirdPhotoLandscape = await photo.getNthPhotoUid("all", 2); - const FourthPhotoLandscape = await photo.getNthPhotoUid("all", 3); - const FifthPhotoLandscape = await photo.getNthPhotoUid("all", 4); - const SixthPhotoLandscape = await photo.getNthPhotoUid("all", 5); - await menu.openPage("labels"); - await label.triggerHoverAction("uid", LabelLandscape, "select"); - await contextmenu.checkContextMenuCount("1"); - await contextmenu.triggerContextMenuAction("album", "Christmas"); - await menu.openPage("albums"); - await album.openAlbumWithUid(AlbumUid); - const PhotoCountAfterAdd = await photo.getPhotoCount("all"); +test.meta("testID", "labels-003").meta({ mode: "public" })( + "Common: Add label to album", + async (t) => { + await menu.openPage("albums"); + await toolbar.search("Christmas"); + const AlbumUid = await album.getNthAlbumUid("all", 0); + await album.openAlbumWithUid(AlbumUid); + const PhotoCount = await photo.getPhotoCount("all"); + await menu.openPage("labels"); + await toolbar.search("landscape"); + const LabelLandscape = await label.getNthLabeltUid(1); + await label.openLabelWithUid(LabelLandscape); + const FirstPhotoLandscape = await photo.getNthPhotoUid("all", 0); + const SecondPhotoLandscape = await photo.getNthPhotoUid("all", 1); + const ThirdPhotoLandscape = await photo.getNthPhotoUid("all", 2); + const FourthPhotoLandscape = await photo.getNthPhotoUid("all", 3); + const FifthPhotoLandscape = await photo.getNthPhotoUid("all", 4); + const SixthPhotoLandscape = await photo.getNthPhotoUid("all", 5); + await menu.openPage("labels"); + await label.triggerHoverAction("uid", LabelLandscape, "select"); + await contextmenu.checkContextMenuCount("1"); + await contextmenu.triggerContextMenuAction("album", "Christmas"); + await menu.openPage("albums"); + await album.openAlbumWithUid(AlbumUid); + const PhotoCountAfterAdd = await photo.getPhotoCount("all"); - await t.expect(PhotoCountAfterAdd).eql(PhotoCount + 6); + await t.expect(PhotoCountAfterAdd).eql(PhotoCount + 6); - await photo.triggerHoverAction("uid", FirstPhotoLandscape, "select"); - await photo.triggerHoverAction("uid", SecondPhotoLandscape, "select"); - await photo.triggerHoverAction("uid", ThirdPhotoLandscape, "select"); - await photo.triggerHoverAction("uid", FourthPhotoLandscape, "select"); - await photo.triggerHoverAction("uid", FifthPhotoLandscape, "select"); - await photo.triggerHoverAction("uid", SixthPhotoLandscape, "select"); - await contextmenu.triggerContextMenuAction("remove", ""); - const PhotoCountAfterDelete = await photo.getPhotoCount("all"); + await photo.triggerHoverAction("uid", FirstPhotoLandscape, "select"); + await photo.triggerHoverAction("uid", SecondPhotoLandscape, "select"); + await photo.triggerHoverAction("uid", ThirdPhotoLandscape, "select"); + await photo.triggerHoverAction("uid", FourthPhotoLandscape, "select"); + await photo.triggerHoverAction("uid", FifthPhotoLandscape, "select"); + await photo.triggerHoverAction("uid", SixthPhotoLandscape, "select"); + await contextmenu.triggerContextMenuAction("remove", ""); + const PhotoCountAfterDelete = await photo.getPhotoCount("all"); - await t.expect(PhotoCountAfterDelete).eql(PhotoCountAfterAdd - 6); -}); + await t.expect(PhotoCountAfterDelete).eql(PhotoCountAfterAdd - 6); + } +); -test.meta("testID", "labels-004")("Delete label", async (t) => { +test.meta("testID", "labels-004").meta({ mode: "public" })("Common: Delete label", async (t) => { await menu.openPage("labels"); await toolbar.search("dome"); const LabelDomeUid = await label.getNthLabeltUid(0); diff --git a/frontend/tests/acceptance/library/import.js b/frontend/tests/acceptance/acceptance-public/library/import.js similarity index 89% rename from frontend/tests/acceptance/library/import.js rename to frontend/tests/acceptance/acceptance-public/library/import.js index 645cd4621..e5126cea7 100644 --- a/frontend/tests/acceptance/library/import.js +++ b/frontend/tests/acceptance/acceptance-public/library/import.js @@ -12,8 +12,8 @@ const toolbar = new Toolbar(); const page = new Page(); const library = new Library(); -test.meta("testID", "library-import-001").meta({ type: "smoke" })( - "Import files from folder using copy", +test.meta("testID", "library-import-001").meta({ type: "short", mode: "public" })( + "Common: Import files from folder using copy", async (t) => { await menu.openPage("labels"); await toolbar.search("bakery"); diff --git a/frontend/tests/acceptance/library/index.js b/frontend/tests/acceptance/acceptance-public/library/index.js similarity index 97% rename from frontend/tests/acceptance/library/index.js rename to frontend/tests/acceptance/acceptance-public/library/index.js index e08c7e61e..ed7d0b532 100644 --- a/frontend/tests/acceptance/library/index.js +++ b/frontend/tests/acceptance/acceptance-public/library/index.js @@ -16,8 +16,8 @@ const page = new Page(); const library = new Library(); const album = new Album(); -test.meta("testID", "library-index-001").meta({ type: "smoke" })( - "Index files from folder", +test.meta("testID", "library-index-001").meta({ type: "short", mode: "public" })( + "Common: Index files from folder", async (t) => { await menu.openPage("labels"); await toolbar.search("cheetah"); diff --git a/frontend/tests/acceptance/acceptance-public/moment.js b/frontend/tests/acceptance/acceptance-public/moment.js new file mode 100644 index 000000000..88e76b966 --- /dev/null +++ b/frontend/tests/acceptance/acceptance-public/moment.js @@ -0,0 +1,157 @@ +import { Selector } from "testcafe"; +import testcafeconfig from "./testcafeconfig"; +import Menu from "../page-model/menu"; +import Album from "../page-model/album"; +import Toolbar from "../page-model/toolbar"; +import ContextMenu from "../page-model/context-menu"; +import Photo from "../page-model/photo"; +import Page from "../page-model/page"; +import AlbumDialog from "../page-model/dialog-album"; + +fixture`Test moments`.page`${testcafeconfig.url}`; + +const menu = new Menu(); +const album = new Album(); +const toolbar = new Toolbar(); +const contextmenu = new ContextMenu(); +const photo = new Photo(); +const page = new Page(); +const albumdialog = new AlbumDialog(); + +test.meta("testID", "moments-001").meta({ mode: "public" })( + "Common: Update moment details", + async (t) => { + await menu.openPage("moments"); + await toolbar.search("Nature"); + const AlbumUid = await album.getNthAlbumUid("all", 0); + + await t.expect(page.cardTitle.nth(0).innerText).contains("Nature"); + + await t.click(page.cardTitle.nth(0)); + + await t + .expect(albumdialog.title.value) + .eql("Nature & Landscape") + .expect(albumdialog.location.value) + .eql("") + .expect(albumdialog.description.value) + .eql("") + .expect(albumdialog.category.value) + .eql(""); + + await t + .typeText(albumdialog.title, "Winter", { replace: true }) + .typeText(albumdialog.location, "Snow-Land", { replace: true }) + .typeText(albumdialog.description, "We went to ski") + .typeText(albumdialog.category, "Mountains") + .pressKey("enter") + .click(albumdialog.dialogSave); + + await t + .expect(page.cardTitle.nth(0).innerText) + .contains("Winter") + .expect(page.cardDescription.nth(0).innerText) + .contains("We went to ski") + .expect(Selector("div.caption").nth(1).innerText) + .contains("Mountains") + .expect(Selector("div.caption").nth(2).innerText) + .contains("Snow-Land"); + + await album.openNthAlbum(0); + + await t.expect(toolbar.toolbarSecondTitle.innerText).contains("Winter"); + await t.expect(toolbar.toolbarDescription.innerText).contains("We went to ski"); + + await menu.openPage("moments"); + if (t.browser.platform === "mobile") { + await toolbar.search("category:Mountains"); + } else { + await toolbar.setFilter("category", "Mountains"); + } + + await t.expect(page.cardTitle.nth(0).innerText).contains("Winter"); + + await album.openAlbumWithUid(AlbumUid); + await toolbar.triggerToolbarAction("edit"); + + await t + .expect(albumdialog.description.value) + .eql("We went to ski") + .expect(albumdialog.category.value) + .eql("Mountains") + .expect(albumdialog.location.value) + .eql("Snow-Land"); + + await t + .typeText(albumdialog.title, "Nature & Landscape", { replace: true }) + .click(albumdialog.category) + .pressKey("ctrl+a delete") + .pressKey("enter") + .click(albumdialog.description) + .pressKey("ctrl+a delete") + .pressKey("enter") + .click(albumdialog.location) + .pressKey("ctrl+a delete") + .pressKey("enter") + .click(albumdialog.dialogSave); + await menu.openPage("moments"); + await toolbar.search("Nature"); + + await t + .expect(page.cardTitle.nth(0).innerText) + .contains("Nature & Landscape") + .expect(page.cardDescription.innerText) + .notContains("We went to ski") + .expect(Selector("div.caption").nth(0).innerText) + .notContains("Snow-Land"); + } +); + +test.meta("testID", "moments-002").meta({ mode: "public" })( + "Common: Create, Edit, delete sharing link for moment", + async (t) => { + await page.testCreateEditDeleteSharingLink("moments"); + } +); + +test.meta("testID", "moments-003").meta({ mode: "public" })( + "Common: Create/delete album-clone from moment", + async (t) => { + await menu.openPage("albums"); + const AlbumCount = await album.getAlbumCount("all"); + await menu.openPage("moments"); + const FirstMomentUid = await album.getNthAlbumUid("all", 0); + await album.openAlbumWithUid(FirstMomentUid); + const PhotoCountInMoment = await photo.getPhotoCount("all"); + const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); + const SecondPhotoUid = await photo.getNthPhotoUid("image", 1); + await menu.openPage("moments"); + await album.selectAlbumFromUID(FirstMomentUid); + await contextmenu.triggerContextMenuAction("clone", "NotYetExistingAlbumForMoment"); + await menu.openPage("albums"); + const AlbumCountAfterCreation = await album.getAlbumCount("all"); + + await t.expect(AlbumCountAfterCreation).eql(AlbumCount + 1); + + await toolbar.search("NotYetExistingAlbumForMoment"); + const AlbumUid = await album.getNthAlbumUid("all", 0); + await album.openAlbumWithUid(AlbumUid); + const PhotoCountInAlbum = await photo.getPhotoCount("all"); + + await t.expect(PhotoCountInAlbum).eql(PhotoCountInMoment); + + await photo.checkPhotoVisibility(FirstPhotoUid, true); + await photo.checkPhotoVisibility(SecondPhotoUid, true); + await menu.openPage("albums"); + await album.selectAlbumFromUID(AlbumUid); + await contextmenu.triggerContextMenuAction("delete", ""); + const AlbumCountAfterDelete = await album.getAlbumCount("all"); + + await t.expect(AlbumCountAfterDelete).eql(AlbumCount); + + await menu.openPage("moments"); + await album.openAlbumWithUid(FirstMomentUid); + await photo.checkPhotoVisibility(FirstPhotoUid, true); + await photo.checkPhotoVisibility(SecondPhotoUid, true); + } +); diff --git a/frontend/tests/acceptance/acceptance-public/originals.js b/frontend/tests/acceptance/acceptance-public/originals.js new file mode 100644 index 000000000..97f735238 --- /dev/null +++ b/frontend/tests/acceptance/acceptance-public/originals.js @@ -0,0 +1,106 @@ +import { Selector } from "testcafe"; +import testcafeconfig from "./testcafeconfig"; +import Menu from "../page-model/menu"; +import Photo from "../page-model/photo"; +import Toolbar from "../page-model/toolbar"; +import ContextMenu from "../page-model/context-menu"; +import Album from "../page-model/album"; +import Originals from "../page-model/originals"; + +fixture`Test files`.page`${testcafeconfig.url}`; + +const menu = new Menu(); +const photo = new Photo(); +const toolbar = new Toolbar(); +const contextmenu = new ContextMenu(); +const album = new Album(); +const originals = new Originals(); + +test.meta("testID", "originals-001").meta({ type: "short", mode: "public" })( + "Common: Navigate in originals", + async (t) => { + await menu.openPage("originals"); + await t.click(Selector("button").withText("Vacation")); + const FirstItemInVacationName = await Selector("div.result", { timeout: 15000 }).nth(0) + .innerText; + const KanadaFolderUid = await originals.getNthFolderUid(0); + const SecondItemInVacationName = await Selector("div.result").nth(1).innerText; + + await t + .expect(FirstItemInVacationName) + .contains("Kanada") + .expect(SecondItemInVacationName) + .contains("Korsika"); + + await originals.openFolderWithUid(KanadaFolderUid); + + const FirstItemInKanadaName = await Selector("div.result").nth(0).innerText; + const SecondItemInKanadaName = await Selector("div.result").nth(1).innerText; + + await t + .expect(FirstItemInKanadaName) + .contains("BotanicalGarden") + .expect(SecondItemInKanadaName) + .contains("originals-001_2.jpg"); + + await t.click(Selector("button").withText("BotanicalGarden")); + const FirstItemInBotanicalGardenName = await Selector("div.result", { timeout: 15000 }).nth(0) + .innerText; + await t.expect(FirstItemInBotanicalGardenName).contains("originals-001_1.jpg"); + await t.click(Selector('a[href="/library/files/Vacation"]')); + const FolderCount = await originals.getFolderCount(); + + await t.expect(FolderCount).eql(2); + } +); + +test.meta("testID", "originals-002").meta({ type: "short", mode: "public" })( + "Common: Add original files to album", + async (t) => { + await menu.openPage("albums"); + await toolbar.search("KanadaVacation"); + + await t.expect(Selector("div.no-results").visible).ok(); + + await menu.openPage("originals"); + await t.click(Selector("button").withText("Vacation")); + const KanadaFolderUid = await originals.getNthFolderUid(0); + await originals.openFolderWithUid(KanadaFolderUid); + const FilesCountInKanada = await originals.getFileCount(); + await t.click(Selector("button").withText("BotanicalGarden")); + const FilesCountInKanadaSubfolder = await originals.getFileCount(); + await t.navigateTo("/library/files/Vacation"); + await originals.triggerHoverAction("is-folder", "uid", KanadaFolderUid, "select"); + await contextmenu.checkContextMenuCount("1"); + await contextmenu.triggerContextMenuAction("album", "KanadaVacation"); + await menu.openPage("albums"); + await toolbar.search("KanadaVacation"); + const AlbumUid = await album.getNthAlbumUid("all", 0); + await album.openAlbumWithUid(AlbumUid); + const PhotoCountAfterAdd = await photo.getPhotoCount("all"); + + await t.expect(PhotoCountAfterAdd).eql(FilesCountInKanada + FilesCountInKanadaSubfolder); + + await menu.openPage("albums"); + await album.triggerHoverAction("uid", AlbumUid, "select"); + await contextmenu.checkContextMenuCount("1"); + await contextmenu.triggerContextMenuAction("delete", ""); + } +); + +test.meta("testID", "originals-003").meta({ mode: "public" })( + "Common: Download available in originals", + async (t) => { + await menu.openPage("originals"); + const FirstFile = await originals.getNthFileUid(0); + await originals.triggerHoverAction("is-file", "uid", FirstFile, "select"); + await contextmenu.checkContextMenuCount("1"); + await contextmenu.checkContextMenuActionAvailability("download", true); + await contextmenu.clearSelection(); + const FirstFolder = await originals.getNthFolderUid(0); + await originals.triggerHoverAction("is-folder", "uid", FirstFolder, "select"); + await contextmenu.checkContextMenuCount("1"); + await contextmenu.checkContextMenuActionAvailability("download", true); + await contextmenu.clearSelection(); + } +); diff --git a/frontend/tests/acceptance/people.js b/frontend/tests/acceptance/acceptance-public/people.js similarity index 81% rename from frontend/tests/acceptance/people.js rename to frontend/tests/acceptance/acceptance-public/people.js index 186d556ec..6e4769c59 100644 --- a/frontend/tests/acceptance/people.js +++ b/frontend/tests/acceptance/acceptance-public/people.js @@ -16,8 +16,8 @@ const photo = new Photo(); const subject = new Subject(); const photoedit = new PhotoEdit(); -test.meta("testID", "people-001").meta({ type: "smoke" })( - "Add name to new face and rename subject", +test.meta("testID", "people-001").meta({ type: "short", mode: "public" })( + "Common: Add name to new face and rename subject", async (t) => { await menu.openPage("people"); await t.click(subject.newTab); @@ -98,8 +98,8 @@ test.meta("testID", "people-001").meta({ type: "smoke" })( } ); -test.meta("testID", "people-002").meta({ type: "smoke" })( - "Add + Reject name on people tab", +test.meta("testID", "people-002").meta({ type: "short", mode: "public" })( + "Common: Add + Reject name on people tab", async (t) => { await menu.openPage("people"); await t.click(subject.newTab); @@ -141,39 +141,45 @@ test.meta("testID", "people-002").meta({ type: "smoke" })( } ); -test.meta("testID", "people-003")("Test mark subject as favorite", async (t) => { - await menu.openPage("people"); - const FirstSubjectUid = await subject.getNthSubjectUid(0); - const SecondSubjectUid = await subject.getNthSubjectUid(1); - await subject.triggerHoverAction("uid", SecondSubjectUid, "favorite"); - await subject.triggerToolbarAction("reload"); - const FirstSubjectUidAfterFavorite = await subject.getNthSubjectUid(0); +test.meta("testID", "people-003").meta({ mode: "public" })( + "Common: Test mark subject as favorite", + async (t) => { + await menu.openPage("people"); + const FirstSubjectUid = await subject.getNthSubjectUid(0); + const SecondSubjectUid = await subject.getNthSubjectUid(1); + await subject.triggerHoverAction("uid", SecondSubjectUid, "favorite"); + await subject.triggerToolbarAction("reload"); + const FirstSubjectUidAfterFavorite = await subject.getNthSubjectUid(0); - await t.expect(FirstSubjectUid).notEql(FirstSubjectUidAfterFavorite); - await t.expect(SecondSubjectUid).eql(FirstSubjectUidAfterFavorite); + await t.expect(FirstSubjectUid).notEql(FirstSubjectUidAfterFavorite); + await t.expect(SecondSubjectUid).eql(FirstSubjectUidAfterFavorite); - await subject.checkHoverActionState("uid", SecondSubjectUid, "favorite", true); - await subject.triggerHoverAction("uid", SecondSubjectUid, "favorite"); - await subject.checkHoverActionState("uid", SecondSubjectUid, "favorite", false); -}); + await subject.checkHoverActionState("uid", SecondSubjectUid, "favorite", true); + await subject.triggerHoverAction("uid", SecondSubjectUid, "favorite"); + await subject.checkHoverActionState("uid", SecondSubjectUid, "favorite", false); + } +); -test.meta("testID", "people-004")("Test new face autocomplete", async (t) => { - await menu.openPage("people"); - await t.click(subject.newTab); - await subject.triggerToolbarAction("reload"); - const FirstFaceID = await subject.getNthFaceUid(0); - await t - .expect(Selector("div.menuable__content__active").nth(0).visible) - .notOk() - .click(Selector("div[data-id=" + FirstFaceID + "] div.input-name input")) - .typeText(Selector("div[data-id=" + FirstFaceID + "] div.input-name input"), "Otto"); +test.meta("testID", "people-004").meta({ mode: "public" })( + "Common: Test new face autocomplete", + async (t) => { + await menu.openPage("people"); + await t.click(subject.newTab); + await subject.triggerToolbarAction("reload"); + const FirstFaceID = await subject.getNthFaceUid(0); + await t + .expect(Selector("div.menuable__content__active").nth(0).visible) + .notOk() + .click(Selector("div[data-id=" + FirstFaceID + "] div.input-name input")) + .typeText(Selector("div[data-id=" + FirstFaceID + "] div.input-name input"), "Otto"); - await t - .expect(Selector("div.menuable__content__active").nth(0).withText("Otto Visible").visible) - .ok(); -}); + await t + .expect(Selector("div.menuable__content__active").nth(0).withText("Otto Visible").visible) + .ok(); + } +); -test.meta("testID", "people-005")("Remove face", async (t) => { +test.meta("testID", "people-005").meta({ mode: "public" })("Common: Remove face", async (t) => { await toolbar.search("face:new"); const FirstPhotoUid = await photo.getNthPhotoUid("all", 0); await photo.triggerHoverAction("nth", 0, "select"); @@ -238,7 +244,7 @@ test.meta("testID", "people-005")("Remove face", async (t) => { await t.expect(MarkerCountAfterRemove).eql(MarkerCount - 1); }); -test.meta("testID", "people-006")("Hide face", async (t) => { +test.meta("testID", "people-006").meta({ mode: "public" })("Common: Hide face", async (t) => { await menu.openPage("people"); await t.click(subject.newTab); await subject.triggerToolbarAction("reload"); @@ -259,7 +265,7 @@ test.meta("testID", "people-006")("Hide face", async (t) => { await subject.checkFaceVisibility(FirstFaceID, true); }); -test.meta("testID", "people-007")("Hide person", async (t) => { +test.meta("testID", "people-007").meta({ mode: "public" })("Common: Hide person", async (t) => { await menu.openPage("people"); await t.click(subject.recognizedTab); const FirstPersonUid = await subject.getNthSubjectUid(0); diff --git a/frontend/tests/acceptance/photos-archive-private.js b/frontend/tests/acceptance/acceptance-public/photos-archive-private.js similarity index 97% rename from frontend/tests/acceptance/photos-archive-private.js rename to frontend/tests/acceptance/acceptance-public/photos-archive-private.js index b2d6fe72a..695997aec 100644 --- a/frontend/tests/acceptance/photos-archive-private.js +++ b/frontend/tests/acceptance/acceptance-public/photos-archive-private.js @@ -20,8 +20,8 @@ const album = new Album(); const label = new Label(); const subject = new Subject(); -test.meta("testID", "photos-archive-private-001").meta({ type: "smoke" })( - "Private/unprivate photo/video using clipboard and list", +test.meta("testID", "photos-archive-private-001").meta({ type: "short", mode: "public" })( + "Common: Private/unprivate photo/video using clipboard and list", async (t) => { await toolbar.setFilter("view", "Mosaic"); const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); @@ -114,8 +114,8 @@ test.meta("testID", "photos-archive-private-001").meta({ type: "smoke" })( } ); -test.meta("testID", "photos-archive-private-002").meta({ type: "smoke" })( - "Archive/restore video, photos, private photos and review photos using clipboard", +test.meta("testID", "photos-archive-private-002").meta({ type: "short", mode: "public" })( + "Common: Archive/restore video, photos, private photos and review photos using clipboard", async (t) => { await toolbar.setFilter("view", "Mosaic"); const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); @@ -216,8 +216,8 @@ test.meta("testID", "photos-archive-private-002").meta({ type: "smoke" })( } ); -test.meta("testID", "photos-archive-private-003")( - "Check that archived files are not shown in monochrome/panoramas/stacks/scans/review/albums/favorites/private/videos/calendar/moments/states/labels/folders/originals", +test.meta("testID", "photos-archive-private-003").meta({ mode: "public"})( + "Common: Check that archived files are not shown in monochrome/panoramas/stacks/scans/review/albums/favorites/private/videos/calendar/moments/states/labels/folders/originals", async (t) => { await menu.openPage("archive"); await toolbar.setFilter("view", "Mosaic"); @@ -347,8 +347,8 @@ test.meta("testID", "photos-archive-private-003")( } ); -test.meta("testID", "photos-archive-private-004").meta({ type: "smoke" })( - "Check that private files are not shown in monochrome/panoramas/stacks/scans/review/albums/favorites/archive/videos/calendar/moments/states/labels/folders/originals", +test.meta("testID", "photos-archive-private-004").meta({ type: "short", mode: "public" })( + "Common: Check that private files are not shown in monochrome/panoramas/stacks/scans/review/albums/favorites/archive/videos/calendar/moments/states/labels/folders/originals", async (t) => { await menu.openPage("private"); await toolbar.setFilter("view", "Mosaic"); diff --git a/frontend/tests/acceptance/photos-download.js b/frontend/tests/acceptance/acceptance-public/photos-download.js similarity index 88% rename from frontend/tests/acceptance/photos-download.js rename to frontend/tests/acceptance/acceptance-public/photos-download.js index 89e710395..4025eeb73 100644 --- a/frontend/tests/acceptance/photos-download.js +++ b/frontend/tests/acceptance/acceptance-public/photos-download.js @@ -22,8 +22,8 @@ const photo = new Photo(); const photoviewer = new PhotoViewer(); const page = new Page(); -test.meta("testID", "photos-download-001").meta({ type: "smoke" })( - "Test download jpg file from context menu and fullscreen", +test.meta("testID", "photos-download-001").meta({ type: "short", mode: "public" })( + "Common: Test download jpg file from context menu and fullscreen", async (t) => { await toolbar.search("name:monochrome-2.jpg"); const PhotoUid = await photo.getNthPhotoUid("all", 0); @@ -50,8 +50,8 @@ test.meta("testID", "photos-download-001").meta({ type: "smoke" })( } ); -test.meta("testID", "photos-download-002").meta({ type: "smoke" })( - "Test download video from context menu", +test.meta("testID", "photos-download-002").meta({ type: "short", mode: "public" })( + "Common: Test download video from context menu", async (t) => { await toolbar.search("name:Mohn.mp4"); const PhotoUid = await photo.getNthPhotoUid("all", 0); @@ -70,8 +70,8 @@ test.meta("testID", "photos-download-002").meta({ type: "smoke" })( } ); -test.meta("testID", "photos-download-003")( - "Test download multiple jpg files from context menu", +test.meta("testID", "photos-download-003").meta({ mode: "public" })( + "Common: Test download multiple jpg files from context menu", async (t) => { await toolbar.search("name:panorama_2.jpg"); const PhotoUid = await photo.getNthPhotoUid("all", 0); @@ -92,8 +92,8 @@ test.meta("testID", "photos-download-003")( ); //TODO Check RAW files as well -test.meta("testID", "photos-download-004")( - "Test raw file from context menu and fullscreen mode", +test.meta("testID", "photos-download-004").meta({ mode: "public" })( + "Common: Test raw file from context menu and fullscreen mode", async (t) => { await toolbar.search("name:elephantRAW"); const PhotoUid = await photo.getNthPhotoUid("all", 0); diff --git a/frontend/tests/acceptance/acceptance-public/photos-upload-delete.js b/frontend/tests/acceptance/acceptance-public/photos-upload-delete.js new file mode 100644 index 000000000..28850a239 --- /dev/null +++ b/frontend/tests/acceptance/acceptance-public/photos-upload-delete.js @@ -0,0 +1,291 @@ +import { Selector } from "testcafe"; +import testcafeconfig from "./testcafeconfig"; +import fs from "fs"; +import Menu from "../page-model/menu"; +import Toolbar from "../page-model/toolbar"; +import ContextMenu from "../page-model/context-menu"; +import Photo from "../page-model/photo"; +import Page from "../page-model/page"; +import PhotoEdit from "../page-model/photo-edit"; +import Originals from "../page-model/originals"; +import Album from "../page-model/album"; +import Library from "../page-model/library"; + +fixture`Test photos upload and delete`.page`${testcafeconfig.url}`; + +const menu = new Menu(); +const album = new Album(); +const toolbar = new Toolbar(); +const contextmenu = new ContextMenu(); +const photo = new Photo(); +const page = new Page(); +const photoedit = new PhotoEdit(); +const originals = new Originals(); +const library = new Library(); + +test.meta("testID", "photos-upload-delete-001").meta({ type: "short", mode: "public" })( + "Common: Upload + Delete jpg/json", + async (t) => { + await menu.openNav(); + const InitialOriginalsCount = await Selector(".nav-originals .nav-count", { timeout: 5000 }) + .innerText; + await t.expect(fs.existsSync("../storage/acceptance/originals/2020/10")).notOk(); + await toolbar.search("digikam"); + const PhotoCount = await photo.getPhotoCount("all"); + + await t.expect(PhotoCount).eql(0); + + await toolbar.triggerToolbarAction("upload"); + await t + .setFilesToUpload(Selector(".input-upload"), [ + "./upload-files/digikam.jpg", + "./upload-files/digikam.json", + ]) + .wait(15000); + const PhotoCountAfterUpload = await photo.getPhotoCount("all"); + + await t.expect(PhotoCountAfterUpload).eql(1); + + const UploadedPhoto = await photo.getNthPhotoUid("all", 0); + await t.navigateTo("/library/files/2020/10"); + const FileCount = await originals.getFileCount(); + + await t.expect(FileCount).eql(2); + + await menu.openNav(); + const OriginalsCountAfterUpload = await Selector(".nav-originals .nav-count", { timeout: 5000 }) + .innerText; + await t.expect(parseInt(InitialOriginalsCount) + 2).eql(parseInt(OriginalsCountAfterUpload)); + + await menu.openPage("browse"); + await toolbar.search("digikam"); + await photo.triggerHoverAction("uid", UploadedPhoto, "select"); + await contextmenu.triggerContextMenuAction("edit", ""); + await t.click(photoedit.filesTab); + + await t + .expect(Selector("div.caption").withText(".json").visible) + .ok() + .expect(Selector("div.caption").withText(".jpg").visible) + .ok(); + + await t.click(photoedit.dialogClose); + + if (t.browser.platform !== "mobile") { + await t.expect(fs.existsSync("../storage/acceptance/originals/2020/10")).ok(); + const originalsLength = fs.readdirSync("../storage/acceptance/originals/2020/10").length; + await t.expect(originalsLength).eql(2); + } + + await contextmenu.triggerContextMenuAction("archive", ""); + await menu.openPage("archive"); + await photo.triggerHoverAction("uid", UploadedPhoto, "select"); + await contextmenu.triggerContextMenuAction("delete", ""); + await menu.openPage("browse"); + await toolbar.search("digikam"); + await photo.checkPhotoVisibility(UploadedPhoto, false); + await t.navigateTo("/library/files/2020/10"); + const FileCountAfterDelete = await originals.getFileCount(); + + await t.expect(FileCountAfterDelete).eql(0); + if (t.browser.platform !== "mobile") { + const originalsLengthAfterDelete = fs.readdirSync( + "../storage/acceptance/originals/2020/10" + ).length; + await t.expect(originalsLengthAfterDelete).eql(0); + } + } +); + +test.meta("testID", "photos-upload-delete-002").meta({ mode: "public" })( + "Common: Upload + Delete video", + async (t) => { + await t.expect(fs.existsSync("../storage/acceptance/originals/2020/06")).notOk(); + await toolbar.search("korn"); + const PhotoCount = await photo.getPhotoCount("all"); + + await t.expect(PhotoCount).eql(0); + + await toolbar.triggerToolbarAction("upload"); + await t.setFilesToUpload(Selector(".input-upload"), ["./upload-files/korn.mp4"]).wait(15000); + const PhotoCountAfterUpload = await photo.getPhotoCount("all"); + + await t.expect(PhotoCountAfterUpload).eql(1); + + const UploadedPhoto = await photo.getNthPhotoUid("all", 0); + await t.navigateTo("/library/files/2020/06"); + const FileCount = await originals.getFileCount(); + + await t.expect(FileCount).eql(1); + + await menu.openPage("browse"); + await toolbar.search("korn"); + await photo.triggerHoverAction("uid", UploadedPhoto, "select"); + await contextmenu.triggerContextMenuAction("edit", ""); + await t.click(photoedit.filesTab); + + await t + .expect(Selector("div.caption").withText(".mp4").visible) + .ok() + .expect(Selector("div.caption").withText(".jpg").visible) + .ok(); + + await t.click(photoedit.dialogClose); + + if (t.browser.platform !== "mobile") { + await t.expect(fs.existsSync("../storage/acceptance/originals/2020/06")).ok(); + const originalsLength = fs.readdirSync("../storage/acceptance/originals/2020/06").length; + await t.expect(originalsLength).eql(1); + const sidecarLength = fs.readdirSync("../storage/acceptance/originals/2020/06").length; + await t.expect(sidecarLength).eql(1); + } + + await contextmenu.triggerContextMenuAction("archive", ""); + await menu.openPage("archive"); + await photo.triggerHoverAction("uid", UploadedPhoto, "select"); + await contextmenu.triggerContextMenuAction("delete", ""); + await menu.openPage("browse"); + await toolbar.search("korn"); + await photo.checkPhotoVisibility(UploadedPhoto, false); + await t.navigateTo("/library/files/2020/06"); + const FileCountAfterDelete = await originals.getFileCount(); + + await t.expect(FileCountAfterDelete).eql(0); + if (t.browser.platform !== "mobile") { + const originalsLengthAfterDelete = fs.readdirSync( + "../storage/acceptance/originals/2020/06" + ).length; + await t.expect(originalsLengthAfterDelete).eql(0); + const sidecarLengthAfterDelete = fs.readdirSync( + "../storage/acceptance/originals/2020/06" + ).length; + await t.expect(sidecarLengthAfterDelete).eql(0); + } + } +); + +test.meta("testID", "photos-upload-delete-003").meta({ mode: "public" })( + "Common: Upload to existing Album + Delete", + async (t) => { + await menu.openPage("albums"); + await toolbar.search("Christmas"); + const AlbumUid = await album.getNthAlbumUid("all", 0); + await album.openAlbumWithUid(AlbumUid); + const PhotoCount = await photo.getPhotoCount("all"); + await toolbar.triggerToolbarAction("upload"); + await t + .click(Selector(".input-albums")) + .click(page.selectOption.withText("Christmas")) + .setFilesToUpload(Selector(".input-upload"), ["./upload-files/ladybug.jpg"]) + .wait(15000); + const PhotoCountAfterUpload = await photo.getPhotoCount("all"); + + await t.expect(PhotoCountAfterUpload).eql(PhotoCount + 1); + + await menu.openPage("browse"); + await toolbar.search("ladybug"); + const UploadedPhotoUid = await photo.getNthPhotoUid("all", 0); + await photo.triggerHoverAction("uid", UploadedPhotoUid, "select"); + await contextmenu.triggerContextMenuAction("archive", ""); + await menu.openPage("archive"); + await photo.triggerHoverAction("uid", UploadedPhotoUid, "select"); + await contextmenu.triggerContextMenuAction("delete", ""); + await menu.openPage("browse"); + await toolbar.search("ladybug"); + await photo.checkPhotoVisibility(UploadedPhotoUid, false); + await menu.openPage("albums"); + await album.openAlbumWithUid(AlbumUid); + await photo.checkPhotoVisibility(UploadedPhotoUid, false); + const PhotoCountAfterDelete = await photo.getPhotoCount("all"); + + await t.expect(PhotoCountAfterDelete).eql(PhotoCount); + } +); + +test.meta("testID", "photos-upload-delete-004").meta({ mode: "public" })( + "Common: Upload jpg to new Album + Delete", + async (t) => { + await menu.openPage("albums"); + const AlbumCount = await album.getAlbumCount("all"); + await toolbar.triggerToolbarAction("upload"); + await t + .click(Selector(".input-albums")) + .typeText(Selector(".input-albums input"), "NewCreatedAlbum") + .pressKey("enter") + .setFilesToUpload(Selector(".input-upload"), ["./upload-files/digikam.jpg"]) + .wait(15000); + if (t.browser.platform === "mobile") { + await t.eval(() => location.reload()); + } else { + await toolbar.triggerToolbarAction("reload"); + } + const AlbumCountAfterUpload = await album.getAlbumCount("all"); + + await t.expect(AlbumCountAfterUpload).eql(AlbumCount + 1); + + await toolbar.search("NewCreatedAlbum"); + await album.openNthAlbum(0); + const PhotoCount = await photo.getPhotoCount("all"); + + await t.expect(PhotoCount).eql(1); + + await menu.openPage("browse"); + await toolbar.search("digikam"); + const UploadedPhotoUid = await photo.getNthPhotoUid("all", 0); + await photo.triggerHoverAction("uid", UploadedPhotoUid, "select"); + await contextmenu.triggerContextMenuAction("archive", ""); + await menu.openPage("archive"); + await photo.triggerHoverAction("uid", UploadedPhotoUid, "select"); + await contextmenu.triggerContextMenuAction("delete", ""); + await menu.openPage("browse"); + await toolbar.search("digikam"); + await photo.checkPhotoVisibility(UploadedPhotoUid, false); + await menu.openPage("albums"); + await toolbar.search("NewCreatedAlbum"); + await album.openNthAlbum(0); + await photo.checkPhotoVisibility(UploadedPhotoUid, false); + const PhotoCountAfterDelete = await photo.getPhotoCount("all"); + + await t.expect(PhotoCountAfterDelete).eql(0); + + await menu.openPage("albums"); + await toolbar.search("NewCreatedAlbum"); + await album.triggerHoverAction("nth", 0, "select"); + await contextmenu.checkContextMenuCount("1"); + await contextmenu.triggerContextMenuAction("delete", ""); + } +); + +test.meta("testID", "photos-upload-delete-005").meta({ type: "short", mode: "public" })( + "Common: Try uploading nsfw file", + async (t) => { + await toolbar.triggerToolbarAction("upload"); + await t + .setFilesToUpload(Selector(".input-upload"), ["./upload-files/hentai_2.jpg"]) + .wait(15000); + await menu.openPage("library"); + await t.click(library.logsTab); + + await t.expect(Selector("p").withText("hentai_2.jpg might be offensive").visible).ok(); + } +); + +test.meta("testID", "photos-upload-delete-006").meta({ type: "short", mode: "public" })( + "Common: Try uploading txt file", + async (t) => { + await menu.openNav(); + const InitialOriginalsCount = await Selector(".nav-originals .nav-count", { + timeout: 10000, + }).innerText; + await menu.openPage("browse"); + + await toolbar.triggerToolbarAction("upload"); + await t.setFilesToUpload(Selector(".input-upload"), ["./upload-files/foo.txt"]).wait(15000); + await menu.openNav(); + const OriginalsCountAfterUpload = await Selector(".nav-originals .nav-count", { + timeout: 10000, + }).innerText; + + await t.expect(parseInt(InitialOriginalsCount)).eql(parseInt(OriginalsCountAfterUpload)); + } +); diff --git a/frontend/tests/acceptance/acceptance-public/photos.js b/frontend/tests/acceptance/acceptance-public/photos.js new file mode 100644 index 000000000..cdc346f1f --- /dev/null +++ b/frontend/tests/acceptance/acceptance-public/photos.js @@ -0,0 +1,394 @@ +import { Selector } from "testcafe"; +import testcafeconfig from "./testcafeconfig"; +import { ClientFunction } from "testcafe"; +import Menu from "../page-model/menu"; +import Toolbar from "../page-model/toolbar"; +import ContextMenu from "../page-model/context-menu"; +import Photo from "../page-model/photo"; +import PhotoViewer from "../page-model/photoviewer"; +import Page from "../page-model/page"; +import PhotoEdit from "../page-model/photo-edit"; + +const scroll = ClientFunction((x, y) => window.scrollTo(x, y)); +const getcurrentPosition = ClientFunction(() => window.pageYOffset); + +fixture`Test photos`.page`${testcafeconfig.url}`; + +const menu = new Menu(); +const toolbar = new Toolbar(); +const contextmenu = new ContextMenu(); +const photo = new Photo(); +const photoviewer = new PhotoViewer(); +const page = new Page(); +const photoedit = new PhotoEdit(); + +test.meta("testID", "photos-001").meta({ mode: "public" })("Common: Scroll to top", async (t) => { + await toolbar.setFilter("view", "Cards"); + + await t + .expect(Selector("button.is-photo-scroll-top").exists) + .notOk() + .expect(getcurrentPosition()) + .eql(0) + .expect(Selector("div.image.clickable").nth(0).visible) + .ok(); + + await scroll(0, 1400); + await scroll(0, 900); + + await t.click(Selector("button.p-scroll-top")).expect(getcurrentPosition()).eql(0); +}); + +//TODO Covered by admin role test +test.meta("testID", "photos-002").meta({ mode: "public" })( + "Common: Download single photo/video using clipboard and fullscreen mode", + async (t) => { + const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); + const SecondPhotoUid = await photo.getNthPhotoUid("image", 1); + const FirstVideoUid = await photo.getNthPhotoUid("video", 0); + await photoviewer.openPhotoViewer("uid", SecondPhotoUid); + + await photoviewer.checkPhotoViewerActionAvailability("download", true); + + await photoviewer.triggerPhotoViewerAction("close"); + await photo.triggerHoverAction("uid", FirstPhotoUid, "select"); + await photo.triggerHoverAction("uid", FirstVideoUid, "select"); + await contextmenu.checkContextMenuCount("2"); + + await contextmenu.checkContextMenuActionAvailability("download", true); + } +); + +test.meta("testID", "photos-003").meta({ type: "short", mode: "public" })( + "Common: Approve photo using approve and by adding location", + async (t) => { + await menu.openPage("review"); + const FirstPhotoUid = await photo.getNthPhotoUid("all", 0); + const SecondPhotoUid = await photo.getNthPhotoUid("all", 1); + const ThirdPhotoUid = await photo.getNthPhotoUid("all", 2); + await menu.openPage("browse"); + + await photo.checkPhotoVisibility(FirstPhotoUid, false); + await photo.checkPhotoVisibility(SecondPhotoUid, false); + + await menu.openPage("review"); + await photo.triggerHoverAction("uid", FirstPhotoUid, "select"); + await contextmenu.triggerContextMenuAction("edit", ""); + await t.click(photoedit.detailsClose); + if (t.browser.platform === "mobile") { + await t.eval(() => location.reload()); + } else { + await toolbar.triggerToolbarAction("reload"); + } + + await photo.checkPhotoVisibility(FirstPhotoUid, true); + + await contextmenu.triggerContextMenuAction("edit", ""); + await t.click(photoedit.detailsApprove); + if (t.browser.platform === "mobile") { + await t.click(photoedit.detailsApply).click(photoedit.detailsClose); + } else { + await t.click(photoedit.detailsDone); + } + await photo.triggerHoverAction("uid", SecondPhotoUid, "select"); + await contextmenu.triggerContextMenuAction("edit", ""); + await t + .typeText(photoedit.latitude, "9.999", { replace: true }) + .typeText(photoedit.longitude, "9.999", { replace: true }); + if (t.browser.platform === "mobile") { + await t.click(photoedit.detailsApply).click(photoedit.detailsClose); + } else { + await t.click(photoedit.detailsDone); + } + await toolbar.setFilter("view", "Cards"); + const ApproveButtonThirdPhoto = + 'div.is-photo[data-uid="' + ThirdPhotoUid + '"] button.action-approve'; + await t.click(Selector(ApproveButtonThirdPhoto)); + if (t.browser.platform === "mobile") { + await t.eval(() => location.reload()); + } else { + await toolbar.triggerToolbarAction("reload"); + } + + await photo.checkPhotoVisibility(FirstPhotoUid, false); + await photo.checkPhotoVisibility(SecondPhotoUid, false); + await photo.checkPhotoVisibility(ThirdPhotoUid, false); + await menu.openPage("browse"); + await photo.checkPhotoVisibility(FirstPhotoUid, true); + await photo.checkPhotoVisibility(SecondPhotoUid, true); + await photo.checkPhotoVisibility(ThirdPhotoUid, true); + } +); + +test.meta("testID", "photos-004").meta({ type: "short", mode: "public" })( + "Common: Like/dislike photo/video", + async (t) => { + const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); + const SecondPhotoUid = await photo.getNthPhotoUid("image", 1); + const FirstVideoUid = await photo.getNthPhotoUid("video", 0); + await menu.openPage("favorites"); + + await photo.checkPhotoVisibility(FirstPhotoUid, false); + await photo.checkPhotoVisibility(SecondPhotoUid, false); + await photo.checkPhotoVisibility(FirstVideoUid, false); + + await menu.openPage("browse"); + await photo.triggerHoverAction("uid", FirstPhotoUid, "favorite"); + await photo.triggerHoverAction("uid", FirstVideoUid, "favorite"); + await photo.triggerHoverAction("uid", SecondPhotoUid, "select"); + await contextmenu.triggerContextMenuAction("edit", ""); + await photoedit.turnSwitchOn("favorite"); + await t.click(photoedit.dialogClose); + await contextmenu.clearSelection(); + + await photo.checkPhotoVisibility(FirstPhotoUid, true); + await photo.checkPhotoVisibility(FirstVideoUid, true); + await photo.checkPhotoVisibility(SecondPhotoUid, true); + + await menu.openPage("favorites"); + + await photo.checkPhotoVisibility(FirstPhotoUid, true); + await photo.checkPhotoVisibility(FirstVideoUid, true); + await photo.checkPhotoVisibility(SecondPhotoUid, true); + + await photo.triggerHoverAction("uid", SecondPhotoUid, "favorite"); + await photo.triggerHoverAction("uid", FirstVideoUid, "select"); + await contextmenu.triggerContextMenuAction("edit", ""); + await photoedit.turnSwitchOff("favorite"); + await t.click(photoedit.dialogClose); + await contextmenu.clearSelection(); + await photoviewer.openPhotoViewer("uid", FirstPhotoUid); + await photoviewer.triggerPhotoViewerAction("like"); + await photoviewer.triggerPhotoViewerAction("close"); + if (t.browser.platform === "mobile") { + await t.eval(() => location.reload()); + } else { + await toolbar.triggerToolbarAction("reload"); + } + + await photo.checkPhotoVisibility(FirstPhotoUid, false); + await photo.checkPhotoVisibility(FirstVideoUid, false); + await photo.checkPhotoVisibility(SecondPhotoUid, false); + } +); + +test.meta("testID", "photos-005").meta({ type: "short", mode: "public" })( + "Common: Edit photo/video", + async (t) => { + await toolbar.setFilter("view", "Cards"); + const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); + await t.click(page.cardTitle.withAttribute("data-uid", FirstPhotoUid)); + + await t.expect(photoedit.latitude.visible).ok(); + + await t.click(photoedit.dialogNext); + + await t.expect(photoedit.dialogPrevious.getAttribute("disabled")).notEql("disabled"); + + await t.click(photoedit.dialogPrevious).click(photoedit.dialogClose); + await photoviewer.openPhotoViewer("uid", FirstPhotoUid); + await photoviewer.triggerPhotoViewerAction("edit"); + const FirstPhotoTitle = await photoedit.title.value; + const FirstPhotoLocalTime = await photoedit.localTime.value; + const FirstPhotoDay = await photoedit.day.value; + const FirstPhotoMonth = await photoedit.month.value; + const FirstPhotoYear = await photoedit.year.value; + const FirstPhotoTimezone = await photoedit.timezone.value; + const FirstPhotoLatitude = await photoedit.latitude.value; + const FirstPhotoLongitude = await photoedit.longitude.value; + const FirstPhotoAltitude = await photoedit.altitude.value; + const FirstPhotoCountry = await photoedit.country.value; + const FirstPhotoCamera = await photoedit.camera.innerText; + const FirstPhotoIso = await photoedit.iso.value; + const FirstPhotoExposure = await photoedit.exposure.value; + const FirstPhotoLens = await photoedit.lens.innerText; + const FirstPhotoFnumber = await photoedit.fnumber.value; + const FirstPhotoFocalLength = await photoedit.focallength.value; + const FirstPhotoSubject = await photoedit.subject.value; + const FirstPhotoArtist = await photoedit.artist.value; + const FirstPhotoCopyright = await photoedit.copyright.value; + const FirstPhotoLicense = await photoedit.license.value; + const FirstPhotoDescription = await photoedit.description.value; + const FirstPhotoKeywords = await photoedit.keywords.value; + const FirstPhotoNotes = await photoedit.notes.value; + + await t + .typeText(photoedit.title, "Not saved photo title", { replace: true }) + .click(photoedit.detailsClose) + .click(Selector("button.action-date-edit").withAttribute("data-uid", FirstPhotoUid)); + + await t.expect(photoedit.title.value).eql(FirstPhotoTitle); + + await photoedit.editPhoto( + "New Photo Title", + "Europe/Moscow", + "15", + "07", + "2019", + "04:30:30", + "-1", + "41.15333", + "20.168331", + "32", + "1/32", + "29", + "33", + "Super nice edited photo", + "Happy", + "Happy2020", + "Super nice cat license", + "Description of a nice image :)", + ", cat, love", + "Some notes" + ); + if (t.browser.platform === "mobile") { + await t.eval(() => location.reload()); + } else { + await toolbar.triggerToolbarAction("reload"); + } + await toolbar.search("uid:" + FirstPhotoUid); + + await t + .expect(page.cardTitle.withAttribute("data-uid", FirstPhotoUid).innerText) + .eql("New Photo Title"); + + await photo.triggerHoverAction("uid", FirstPhotoUid, "select"); + await contextmenu.triggerContextMenuAction("edit", ""); + + //const expectedValues = [{ FirstPhotoTitle: photoedit.title }, { "bluh bla": photoedit.day }]; + /*const expectedValues = [ + [FirstPhotoTitle, photoedit.title], + ["blah", photoedit.day], + ]; + await photoedit.checkEditFormValuesNewNew(expectedValues);*/ + + await photoedit.checkEditFormValues( + "New Photo Title", + "15", + "07", + "2019", + "04:30:30", + "Europe/Moscow", + "Albania", + "-1", + "", + "", + "", + "32", + "1/32", + "", + "29", + "33", + "Super nice edited photo", + "Happy", + "Happy2020", + "Super nice cat license", + "Description of a nice image :)", + "cat", + "Some notes" + ); + + await photoedit.undoPhotoEdit( + FirstPhotoTitle, + FirstPhotoTimezone, + FirstPhotoDay, + FirstPhotoMonth, + FirstPhotoYear, + FirstPhotoLocalTime, + FirstPhotoAltitude, + FirstPhotoLatitude, + FirstPhotoLongitude, + FirstPhotoCountry, + FirstPhotoIso, + FirstPhotoExposure, + FirstPhotoFnumber, + FirstPhotoFocalLength, + FirstPhotoSubject, + FirstPhotoArtist, + FirstPhotoCopyright, + FirstPhotoLicense, + FirstPhotoDescription, + FirstPhotoKeywords, + FirstPhotoNotes + ); + await contextmenu.checkContextMenuCount("1"); + await contextmenu.clearSelection(); + } +); + +test.skip.meta("testID", "photos-006").meta({ mode: "public" })( + "Common: Navigate from card view to place", + async (t) => { + await toolbar.setFilter("view", "Cards"); + await t.click(page.cardLocation.nth(0)); + + await t + .expect(Selector("#map").exists, { timeout: 15000 }) + .ok() + .expect(Selector("div.p-map-control").visible) + .ok() + .expect(Selector(".input-search input").value) + .notEql(""); + } +); + +test.meta("testID", "photos-007").meta({ mode: "public" })( + "Common: Mark photos/videos as panorama/scan", + async (t) => { + const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); + const FirstVideoUid = await photo.getNthPhotoUid("video", 1); + await menu.openPage("scans"); + + await photo.checkPhotoVisibility(FirstPhotoUid, false); + await photo.checkPhotoVisibility(FirstVideoUid, false); + + await menu.openPage("panoramas"); + + await photo.checkPhotoVisibility(FirstPhotoUid, false); + await photo.checkPhotoVisibility(FirstVideoUid, false); + + await menu.openPage("browse"); + await photo.triggerHoverAction("uid", FirstPhotoUid, "select"); + await photo.triggerHoverAction("uid", FirstVideoUid, "select"); + await contextmenu.triggerContextMenuAction("edit", ""); + await photoedit.turnSwitchOn("scan"); + await photoedit.turnSwitchOn("panorama"); + await t.click(photoedit.dialogNext); + await photoedit.turnSwitchOn("scan"); + await photoedit.turnSwitchOn("panorama"); + await t.click(photoedit.dialogClose); + await contextmenu.clearSelection(); + + await photo.checkPhotoVisibility(FirstPhotoUid, true); + await photo.checkPhotoVisibility(FirstVideoUid, true); + + await menu.openPage("scans"); + + await photo.checkPhotoVisibility(FirstPhotoUid, true); + await photo.checkPhotoVisibility(FirstVideoUid, false); + + await menu.openPage("panoramas"); + + await photo.checkPhotoVisibility(FirstPhotoUid, true); + await photo.checkPhotoVisibility(FirstVideoUid, true); + + await photo.triggerHoverAction("uid", FirstPhotoUid, "select"); + await photo.triggerHoverAction("uid", FirstVideoUid, "select"); + await contextmenu.triggerContextMenuAction("edit", ""); + await photoedit.turnSwitchOff("scan"); + await photoedit.turnSwitchOff("panorama"); + await t.click(photoedit.dialogNext); + await photoedit.turnSwitchOff("scan"); + await photoedit.turnSwitchOff("panorama"); + await t.click(photoedit.dialogClose); + await contextmenu.clearSelection(); + if (t.browser.platform === "mobile") { + await t.eval(() => location.reload()); + } else { + await toolbar.triggerToolbarAction("reload"); + } + + await photo.checkPhotoVisibility(FirstPhotoUid, false); + await photo.checkPhotoVisibility(FirstVideoUid, false); + } +); diff --git a/frontend/tests/acceptance/places.js b/frontend/tests/acceptance/acceptance-public/places.js similarity index 93% rename from frontend/tests/acceptance/places.js rename to frontend/tests/acceptance/acceptance-public/places.js index 7b042bb8e..f91b43968 100644 --- a/frontend/tests/acceptance/places.js +++ b/frontend/tests/acceptance/acceptance-public/places.js @@ -11,7 +11,7 @@ fixture`Search and open photo from places`.page`${testcafeconfig.url}`.skip( const menu = new Menu(); -test.meta("testID", "places-001")("Test places", async (t) => { +test.meta("testID", "places-001").meta({ mode: "public" })("Common: Test places", async (t) => { await menu.openPage("places"); await t diff --git a/frontend/tests/acceptance/acceptance-public/settings/about.js b/frontend/tests/acceptance/acceptance-public/settings/about.js new file mode 100644 index 000000000..0edd35771 --- /dev/null +++ b/frontend/tests/acceptance/acceptance-public/settings/about.js @@ -0,0 +1,31 @@ +import { Selector } from "testcafe"; +import testcafeconfig from "../testcafeconfig"; +import Menu from "../../page-model/menu"; + +fixture`Test about`.page`${testcafeconfig.url}`; + +const menu = new Menu(); + +test.meta("testID", "about-001").meta({ mode: "public" })( + "Core: About page is displayed with all links", + async (t) => { + await menu.openPage("about"); + await t + .expect(Selector('a[href="https://photoprism.app/"]').visible) + .ok() + .expect(Selector('a[href="https://photoprism.app/membership"]').visible) + .ok(); + } +); + +test.meta("testID", "about-002").meta({ type: "short", mode: "public" })( + "Core: License page is displayed with all links", + async (t) => { + await menu.openPage("license"); + await t + .expect(Selector("h3").withText("GNU AFFERO GENERAL PUBLIC LICENSE").visible) + .ok() + .expect(Selector('a[href="https://www.gnu.org/licenses/agpl-3.0.en.html"]').visible) + .ok(); + } +); diff --git a/frontend/tests/acceptance/settings/general.js b/frontend/tests/acceptance/acceptance-public/settings/general.js similarity index 87% rename from frontend/tests/acceptance/settings/general.js rename to frontend/tests/acceptance/acceptance-public/settings/general.js index c4853ac75..ae6f58a11 100644 --- a/frontend/tests/acceptance/settings/general.js +++ b/frontend/tests/acceptance/acceptance-public/settings/general.js @@ -24,37 +24,40 @@ const album = new Album(); const settings = new Settings(); const library = new Library(); -test.meta("testID", "settings-general-001").meta({ type: "smoke" })("Disable delete", async (t) => { - await menu.openPage("archive"); - await photo.triggerHoverAction("nth", 0, "select"); - await contextmenu.checkContextMenuActionAvailability("delete", true); - await contextmenu.clearSelection(); - await menu.openPage("settings"); - await t.click(settings.deleteCheckbox); - await menu.openPage("archive"); - await photo.triggerHoverAction("nth", 0, "select"); +test.meta("testID", "settings-general-001").meta({ type: "short", mode: "public" })( + "Common: Disable delete", + async (t) => { + await menu.openPage("archive"); + await photo.triggerHoverAction("nth", 0, "select"); + await contextmenu.checkContextMenuActionAvailability("delete", true); + await contextmenu.clearSelection(); + await menu.openPage("settings"); + await t.click(settings.deleteCheckbox); + await menu.openPage("archive"); + await photo.triggerHoverAction("nth", 0, "select"); - await contextmenu.checkContextMenuActionAvailability("restore", true); - await contextmenu.checkContextMenuActionAvailability("delete", false); - await contextmenu.clearSelection(); + await contextmenu.checkContextMenuActionAvailability("restore", true); + await contextmenu.checkContextMenuActionAvailability("delete", false); + await contextmenu.clearSelection(); - await menu.openPage("browse"); - await toolbar.search("stack:true"); - await photo.triggerHoverAction("nth", 0, "select"); - await contextmenu.triggerContextMenuAction("edit", ""); - await t.click(photoedit.filesTab); - await t.click(photoedit.toggleExpandFile.nth(1)); + await menu.openPage("browse"); + await toolbar.search("stack:true"); + await photo.triggerHoverAction("nth", 0, "select"); + await contextmenu.triggerContextMenuAction("edit", ""); + await t.click(photoedit.filesTab); + await t.click(photoedit.toggleExpandFile.nth(1)); - await t.expect(photoedit.deleteFile.visible).notOk(); + await t.expect(photoedit.deleteFile.visible).notOk(); - await t.click(photoedit.dialogClose); - await contextmenu.clearSelection(); - await menu.openPage("settings"); - await t.click(settings.deleteCheckbox); -}); + await t.click(photoedit.dialogClose); + await contextmenu.clearSelection(); + await menu.openPage("settings"); + await t.click(settings.deleteCheckbox); + } +); -test.meta("testID", "settings-general-002").meta({ type: "smoke" })( - "Change language", +test.meta("testID", "settings-general-002").meta({ type: "short", mode: "public" })( + "Common: Change language", async (t) => { await t.expect(Selector(".nav-browse").innerText).contains("Search"); @@ -76,8 +79,8 @@ test.meta("testID", "settings-general-002").meta({ type: "smoke" })( } ); -test.meta("testID", "settings-general-003").meta({ type: "smoke" })( - "Disable pages: import, originals, logs, moments, places, library", +test.meta("testID", "settings-general-003").meta({ type: "short", mode: "public" })( + "Common: Disable pages: import, originals, logs, moments, places, library", async (t) => { await toolbar.setFilter("view", "Cards"); @@ -150,8 +153,8 @@ test.meta("testID", "settings-general-003").meta({ type: "smoke" })( } ); -test.meta("testID", "settings-general-004").meta({ type: "smoke" })( - "Disable people and labels", +test.meta("testID", "settings-general-004").meta({ type: "short", mode: "public" })( + "Common: Disable people and labels", async (t) => { await toolbar.setFilter("view", "Cards"); await t.click(page.cardTitle.nth(0)); @@ -193,8 +196,8 @@ test.meta("testID", "settings-general-004").meta({ type: "smoke" })( } ); -test.meta("testID", "settings-general-005").meta({ type: "smoke" })( - "Disable private, archive and quality filter", +test.meta("testID", "settings-general-005").meta({ type: "short", mode: "public" })( + "Common: Disable private, archive and quality filter", async (t) => { await menu.checkMenuItemAvailability("archive", true); await menu.checkMenuItemAvailability("review", true); @@ -279,8 +282,8 @@ test.meta("testID", "settings-general-005").meta({ type: "smoke" })( } ); -test.meta("testID", "settings-general-006").meta({ type: "smoke" })( - "Disable upload, download, edit and share", +test.meta("testID", "settings-general-006").meta({ type: "short", mode: "public" })( + "Common: Disable upload, download, edit and share", async (t) => { await toolbar.checkToolbarActionAvailability("upload", true); diff --git a/frontend/tests/acceptance/acceptance-public/stacks.js b/frontend/tests/acceptance/acceptance-public/stacks.js new file mode 100644 index 000000000..7cface40e --- /dev/null +++ b/frontend/tests/acceptance/acceptance-public/stacks.js @@ -0,0 +1,133 @@ +import { Selector } from "testcafe"; +import testcafeconfig from "./testcafeconfig"; +import Menu from "../page-model/menu"; +import Toolbar from "../page-model/toolbar"; +import Photo from "../page-model/photo"; +import PhotoViewer from "../page-model/photoviewer"; +import Page from "../page-model/page"; +import PhotoEdit from "../page-model/photo-edit"; +import Library from "../page-model/library"; + +fixture`Test stacks`.page`${testcafeconfig.url}`; + +const menu = new Menu(); +const toolbar = new Toolbar(); +const photo = new Photo(); +const photoviewer = new PhotoViewer(); +const page = new Page(); +const photoedit = new PhotoEdit(); +const library = new Library(); + +test.meta("testID", "stacks-001").meta({ type: "short", mode: "public" })( + "Common: View all files of a stack", + async (t) => { + await toolbar.search("ski"); + const SequentialPhotoUid = await photo.getNthPhotoUid("all", 0); + await photo.checkHoverActionAvailability("uid", SequentialPhotoUid, "open", true); + if (t.browser.platform === "desktop") { + console.log(t.browser.platform); + await photo.triggerHoverAction("nth", 0, "open"); + await photoviewer.triggerPhotoViewerAction("next"); + await photoviewer.triggerPhotoViewerAction("previous"); + await photoviewer.triggerPhotoViewerAction("close"); + } + await photo.checkHoverActionAvailability("uid", SequentialPhotoUid, "open", true); + } +); + +test.meta("testID", "stacks-002").meta({ type: "short", mode: "public" })( + "Common: Change primary file", + async (t) => { + await toolbar.search("ski"); + const SequentialPhotoUid = await photo.getNthPhotoUid("all", 0); + await toolbar.setFilter("view", "Cards"); + await t + .click(page.cardTitle.withAttribute("data-uid", SequentialPhotoUid)) + .click(photoedit.filesTab); + const FirstFileName = await Selector("div.caption").nth(0).innerText; + + await t.expect(FirstFileName).contains("photos8_1_ski.jpg"); + + await t + .click(photoedit.toggleExpandFile.nth(1)) + .click(photoedit.makeFilePrimary) + .click(photoedit.dialogClose) + .click(page.cardTitle.withAttribute("data-uid", SequentialPhotoUid)); + const FirstFileNameAfterChange = await Selector("div.caption").nth(0).innerText; + + await t + .expect(FirstFileNameAfterChange) + .notContains("photos8_1_ski.jpg") + .expect(FirstFileNameAfterChange) + .contains("photos8_2_ski.jpg"); + } +); + +test.meta("testID", "stacks-003").meta({ type: "short", mode: "public" })( + "Common: Ungroup files", + async (t) => { + await toolbar.search("group"); + await toolbar.setFilter("view", "Cards"); + const PhotoCount = await photo.getPhotoCount("all"); + const SequentialPhotoUid = await photo.getNthPhotoUid("all", 0); + + await t.expect(PhotoCount).eql(1); + + await menu.openPage("stacks"); + await photo.checkHoverActionAvailability("uid", SequentialPhotoUid, "open", true); + await toolbar.setFilter("view", "Cards"); + await t + .click(page.cardTitle.withAttribute("data-uid", SequentialPhotoUid)) + .click(photoedit.filesTab) + .click(photoedit.toggleExpandFile.nth(0)) + .click(photoedit.toggleExpandFile.nth(1)) + .click(photoedit.unstackFile) + .wait(12000) + .click(photoedit.dialogClose); + await menu.openPage("browse"); + await toolbar.search("group"); + if (t.browser.platform === "mobile") { + await t.eval(() => location.reload()); + } else { + await toolbar.triggerToolbarAction("reload"); + } + const PhotoCountAfterUngroup = await photo.getPhotoCount("all"); + + await t.expect(PhotoCountAfterUngroup).eql(2); + await photo.checkHoverActionAvailability("uid", SequentialPhotoUid, "open", false); + } +); + +test.meta("testID", "stacks-004").meta({ mode: "public" })( + "Common: Delete non primary file", + async (t) => { + await menu.openPage("library"); + await t + .click(library.importTab) + .click(library.openImportFolderSelect, { timeout: 5000 }) + .click(page.selectOption.withText("/pizza")) + .click(library.import) + .wait(10000); + await menu.openPage("browse"); + await toolbar.search("pizza"); + await toolbar.setFilter("view", "Cards"); + const PhotoCount = await photo.getPhotoCount("all"); + const PhotoUid = await photo.getNthPhotoUid("all", 0); + + await t.expect(PhotoCount).eql(1); + + await t.click(page.cardTitle.withAttribute("data-uid", PhotoUid)).click(photoedit.filesTab); + const FileCount = await photoedit.getFileCount(); + + await t.expect(FileCount).eql(2); + + await t + .click(photoedit.toggleExpandFile.nth(1)) + .click(Selector(photoedit.deleteFile)) + .click(Selector(".action-confirm")) + .wait(10000); + const FileCountAfterDeletion = await photoedit.getFileCount(); + + await t.expect(FileCountAfterDeletion).eql(1); + } +); diff --git a/frontend/tests/acceptance/acceptance-public/states.js b/frontend/tests/acceptance/acceptance-public/states.js new file mode 100644 index 000000000..502df8031 --- /dev/null +++ b/frontend/tests/acceptance/acceptance-public/states.js @@ -0,0 +1,156 @@ +import { Selector } from "testcafe"; +import testcafeconfig from "./testcafeconfig"; +import Menu from "../page-model/menu"; +import Album from "../page-model/album"; +import Toolbar from "../page-model/toolbar"; +import ContextMenu from "../page-model/context-menu"; +import Photo from "../page-model/photo"; +import Page from "../page-model/page"; +import AlbumDialog from "../page-model/dialog-album"; + +fixture`Test states`.page`${testcafeconfig.url}`; + +const menu = new Menu(); +const album = new Album(); +const toolbar = new Toolbar(); +const contextmenu = new ContextMenu(); +const photo = new Photo(); +const page = new Page(); +const albumdialog = new AlbumDialog(); + +test.meta("testID", "states-001").meta({ mode: "public" })( + "Common: Update state details", + async (t) => { + await menu.openPage("states"); + await toolbar.search("Canada"); + const AlbumUid = await album.getNthAlbumUid("all", 0); + + await t.expect(page.cardTitle.nth(0).innerText).contains("British Columbia"); + + await t.click(page.cardTitle.nth(0)); + + await t + .expect(albumdialog.title.value) + .eql("British Columbia") + .expect(albumdialog.location.value) + .eql("Canada") + .expect(albumdialog.description.value) + .eql("") + .expect(albumdialog.category.value) + .eql(""); + + await t + .typeText(albumdialog.title, "Wonderland", { replace: true }) + .typeText(albumdialog.location, "Earth", { replace: true }) + .typeText(albumdialog.description, "We love earth") + .typeText(albumdialog.category, "Mountains") + .pressKey("enter") + .click(albumdialog.dialogSave); + + await t + .expect(page.cardTitle.nth(0).innerText) + .contains("Wonderland") + .expect(page.cardDescription.nth(0).innerText) + .contains("We love earth") + .expect(Selector("div.caption").nth(1).innerText) + .contains("Mountains") + .expect(Selector("div.caption").nth(2).innerText) + .contains("Earth"); + + await album.openNthAlbum(0); + + await t.expect(toolbar.toolbarSecondTitle.innerText).contains("Wonderland"); + await t.expect(toolbar.toolbarDescription.innerText).contains("We love earth"); + + await menu.openPage("states"); + if (t.browser.platform === "mobile") { + await toolbar.search("category:Mountains"); + } else { + await toolbar.setFilter("category", "Mountains"); + } + + await t.expect(page.cardTitle.nth(0).innerText).contains("Wonderland"); + + await album.openAlbumWithUid(AlbumUid); + await toolbar.triggerToolbarAction("edit"); + + await t + .expect(albumdialog.description.value) + .eql("We love earth") + .expect(albumdialog.category.value) + .eql("Mountains") + .expect(albumdialog.location.value) + .eql("Earth"); + + await t + .typeText(albumdialog.title, "British Columbia / Canada", { replace: true }) + .click(albumdialog.category) + .pressKey("ctrl+a delete") + .pressKey("enter") + .click(albumdialog.description) + .pressKey("ctrl+a delete") + .pressKey("enter") + .typeText(albumdialog.location, "Canada", { replace: true }) + .click(albumdialog.dialogSave); + await menu.openPage("states"); + await toolbar.search("Canada"); + + await t + .expect(page.cardTitle.nth(0).innerText) + .contains("British Columbia / Canada") + .expect(page.cardDescription.innerText) + .notContains("We love earth") + .expect(Selector("div.caption").nth(0).innerText) + .notContains("Earth"); + } +); + +test.meta("testID", "states-002").meta({ mode: "public" })( + "Common: Create, Edit, delete sharing link for state", + async (t) => { + await page.testCreateEditDeleteSharingLink("states"); + } +); + +test.meta("testID", "states-003").meta({ mode: "public" })( + "Common: Create/delete album-clone from state", + async (t) => { + await menu.openPage("albums"); + const AlbumCount = await album.getAlbumCount("all"); + await menu.openPage("states"); + await toolbar.search("Canada"); + const FirstStateUid = await album.getNthAlbumUid("all", 0); + await album.openAlbumWithUid(FirstStateUid); + const PhotoCountInState = await photo.getPhotoCount("all"); + const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); + const SecondPhotoUid = await photo.getNthPhotoUid("image", 1); + await menu.openPage("states"); + await album.selectAlbumFromUID(FirstStateUid); + await contextmenu.triggerContextMenuAction("clone", "NotYetExistingAlbumForState"); + await menu.openPage("albums"); + const AlbumCountAfterCreation = await album.getAlbumCount("all"); + + await t.expect(AlbumCountAfterCreation).eql(AlbumCount + 1); + + await toolbar.search("NotYetExistingAlbumForState"); + const AlbumUid = await album.getNthAlbumUid("all", 0); + await album.openAlbumWithUid(AlbumUid); + const PhotoCountInAlbum = await photo.getPhotoCount("all"); + + await t.expect(PhotoCountInAlbum).eql(PhotoCountInState); + + await photo.checkPhotoVisibility(FirstPhotoUid, true); + await photo.checkPhotoVisibility(SecondPhotoUid, true); + await menu.openPage("albums"); + await album.selectAlbumFromUID(AlbumUid); + await contextmenu.triggerContextMenuAction("delete", ""); + const AlbumCountAfterDelete = await album.getAlbumCount("all"); + + await t.expect(AlbumCountAfterDelete).eql(AlbumCount); + + await menu.openPage("states"); + await album.openAlbumWithUid(FirstStateUid); + await photo.checkPhotoVisibility(FirstPhotoUid, true); + await photo.checkPhotoVisibility(SecondPhotoUid, true); + } +); diff --git a/frontend/tests/acceptance/testcafeconfig.json b/frontend/tests/acceptance/acceptance-public/testcafeconfig.json similarity index 100% rename from frontend/tests/acceptance/testcafeconfig.json rename to frontend/tests/acceptance/acceptance-public/testcafeconfig.json diff --git a/frontend/tests/acceptance/upload-files/digikam.jpg b/frontend/tests/acceptance/acceptance-public/upload-files/digikam.jpg similarity index 100% rename from frontend/tests/acceptance/upload-files/digikam.jpg rename to frontend/tests/acceptance/acceptance-public/upload-files/digikam.jpg diff --git a/frontend/tests/acceptance/upload-files/digikam.json b/frontend/tests/acceptance/acceptance-public/upload-files/digikam.json similarity index 100% rename from frontend/tests/acceptance/upload-files/digikam.json rename to frontend/tests/acceptance/acceptance-public/upload-files/digikam.json diff --git a/frontend/tests/acceptance/upload-files/foo.txt b/frontend/tests/acceptance/acceptance-public/upload-files/foo.txt similarity index 100% rename from frontend/tests/acceptance/upload-files/foo.txt rename to frontend/tests/acceptance/acceptance-public/upload-files/foo.txt diff --git a/frontend/tests/acceptance/upload-files/hentai_2.jpg b/frontend/tests/acceptance/acceptance-public/upload-files/hentai_2.jpg similarity index 100% rename from frontend/tests/acceptance/upload-files/hentai_2.jpg rename to frontend/tests/acceptance/acceptance-public/upload-files/hentai_2.jpg diff --git a/frontend/tests/acceptance/upload-files/korn.mp4 b/frontend/tests/acceptance/acceptance-public/upload-files/korn.mp4 similarity index 100% rename from frontend/tests/acceptance/upload-files/korn.mp4 rename to frontend/tests/acceptance/acceptance-public/upload-files/korn.mp4 diff --git a/frontend/tests/acceptance/upload-files/ladybug.jpg b/frontend/tests/acceptance/acceptance-public/upload-files/ladybug.jpg similarity index 100% rename from frontend/tests/acceptance/upload-files/ladybug.jpg rename to frontend/tests/acceptance/acceptance-public/upload-files/ladybug.jpg diff --git a/frontend/tests/acceptance/albums.js b/frontend/tests/acceptance/albums.js deleted file mode 100644 index 3afb3ec25..000000000 --- a/frontend/tests/acceptance/albums.js +++ /dev/null @@ -1,208 +0,0 @@ -import { Selector } from "testcafe"; -import testcafeconfig from "./testcafeconfig"; -import Menu from "../page-model/menu"; -import Album from "../page-model/album"; -import Toolbar from "../page-model/toolbar"; -import ContextMenu from "../page-model/context-menu"; -import Photo from "../page-model/photo"; -import PhotoViewer from "../page-model/photoviewer"; -import Page from "../page-model/page"; -import AlbumDialog from "../page-model/dialog-album"; - -fixture`Test albums`.page`${testcafeconfig.url}`; - -const menu = new Menu(); -const album = new Album(); -const toolbar = new Toolbar(); -const contextmenu = new ContextMenu(); -const photo = new Photo(); -const photoviewer = new PhotoViewer(); -const page = new Page(); -const albumdialog = new AlbumDialog(); - -test.meta("testID", "authentication-000")( - "Time to start instance (will be marked as unstable)", - async (t) => { - await t.wait(5000); - } -); - -test.meta("testID", "albums-001").meta({ type: "smoke" })( - "Create/delete album on /albums", - async (t) => { - await menu.openPage("albums"); - const AlbumCount = await album.getAlbumCount("all"); - await toolbar.triggerToolbarAction("add"); - const AlbumCountAfterCreate = await album.getAlbumCount("all"); - const NewAlbumUid = await album.getNthAlbumUid("all", 0); - - await t.expect(AlbumCountAfterCreate).eql(AlbumCount + 1); - - await album.selectAlbumFromUID(NewAlbumUid); - await contextmenu.triggerContextMenuAction("delete", ""); - const AlbumCountAfterDelete = await album.getAlbumCount("all"); - - await t.expect(AlbumCountAfterDelete).eql(AlbumCountAfterCreate - 1); - } -); - -test.meta("testID", "albums-002").meta({ type: "smoke" })( - "Create/delete album during add to album", - async (t) => { - await menu.openPage("albums"); - const AlbumCount = await album.getAlbumCount("all"); - await menu.openPage("browse"); - await toolbar.search("photo:true"); - const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); - const SecondPhotoUid = await photo.getNthPhotoUid("image", 1); - await photo.selectPhotoFromUID(SecondPhotoUid); - await photo.selectPhotoFromUID(FirstPhotoUid); - await contextmenu.triggerContextMenuAction("album", "NotYetExistingAlbum"); - await menu.openPage("albums"); - const AlbumCountAfterCreation = await album.getAlbumCount("all"); - - await t.expect(AlbumCountAfterCreation).eql(AlbumCount + 1); - - await toolbar.search("NotYetExistingAlbum"); - const AlbumUid = await album.getNthAlbumUid("all", 0); - await album.selectAlbumFromUID(AlbumUid); - await contextmenu.triggerContextMenuAction("delete", ""); - await menu.openPage("albums"); - const AlbumCountAfterDelete = await album.getAlbumCount("all"); - - await t.expect(AlbumCountAfterDelete).eql(AlbumCount); - } -); - -test.meta("testID", "albums-003").meta({ type: "smoke" })("Update album details", async (t) => { - await menu.openPage("albums"); - await toolbar.search("Holiday"); - const AlbumUid = await album.getNthAlbumUid("all", 0); - - await t.expect(page.cardTitle.nth(0).innerText).contains("Holiday"); - - await t.click(page.cardTitle.nth(0)).typeText(albumdialog.title, "Animals", { replace: true }); - - await t.expect(albumdialog.description.value).eql("").expect(albumdialog.category.value).eql(""); - - await t - .typeText(albumdialog.description, "All my animals") - .typeText(albumdialog.category, "Pets") - .pressKey("enter") - .click(albumdialog.dialogSave); - - await t.expect(page.cardTitle.nth(0).innerText).contains("Animals"); - - await album.openAlbumWithUid(AlbumUid); - await toolbar.triggerToolbarAction("edit"); - await t.typeText(albumdialog.title, "Holiday", { replace: true }); - - await t - .expect(albumdialog.description.value) - .eql("All my animals") - .expect(albumdialog.category.value) - .eql("Pets"); - - await t - .click(albumdialog.description) - .pressKey("ctrl+a delete") - .pressKey("enter") - .click(albumdialog.category) - .pressKey("ctrl+a delete") - .pressKey("enter") - .click(albumdialog.dialogSave); - await menu.openPage("albums"); - - await t - .expect(Selector("div").withText("Holiday").visible) - .ok() - .expect(Selector("div").withText("Animals").exists) - .notOk(); -}); - -test.meta("testID", "albums-004").meta({ type: "smoke" })( - "Add/Remove Photos to/from album", - async (t) => { - await menu.openPage("albums"); - await toolbar.search("Holiday"); - const AlbumUid = await album.getNthAlbumUid("all", 0); - await album.openAlbumWithUid(AlbumUid); - const PhotoCount = await photo.getPhotoCount("all"); - await menu.openPage("browse"); - await toolbar.search("photo:true"); - const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); - const SecondPhotoUid = await photo.getNthPhotoUid("image", 1); - await photo.selectPhotoFromUID(SecondPhotoUid); - await photoviewer.openPhotoViewer("uid", FirstPhotoUid); - await photoviewer.triggerPhotoViewerAction("select"); - await photoviewer.triggerPhotoViewerAction("close"); - await contextmenu.triggerContextMenuAction("album", "Holiday"); - await menu.openPage("albums"); - await album.openAlbumWithUid(AlbumUid); - const PhotoCountAfterAdd = await photo.getPhotoCount("all"); - - await t.expect(PhotoCountAfterAdd).eql(PhotoCount + 2); - - await photo.selectPhotoFromUID(FirstPhotoUid); - await photo.selectPhotoFromUID(SecondPhotoUid); - await contextmenu.triggerContextMenuAction("remove", ""); - const PhotoCountAfterRemove = await photo.getPhotoCount("all"); - - await t.expect(PhotoCountAfterRemove).eql(PhotoCountAfterAdd - 2); - } -); - -test.meta("testID", "albums-005")("Use album search and filters", async (t) => { - await menu.openPage("albums"); - if (t.browser.platform === "mobile") { - await toolbar.search("category:Family"); - } else { - await toolbar.setFilter("category", "Family"); - } - - await t.expect(page.cardTitle.nth(0).innerText).contains("Christmas"); - const AlbumCount = await album.getAlbumCount("all"); - await t.expect(AlbumCount).eql(1); - - if (t.browser.platform === "mobile") { - } else { - await toolbar.setFilter("category", "All Categories"); - } - - await toolbar.search("Holiday"); - - await t.expect(page.cardTitle.nth(0).innerText).contains("Holiday"); - const AlbumCount2 = await album.getAlbumCount("all"); - await t.expect(AlbumCount2).eql(1); -}); - -test.meta("testID", "albums-006")("Test album autocomplete", async (t) => { - await toolbar.search("photo:true"); - const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); - await photo.selectPhotoFromUID(FirstPhotoUid); - await contextmenu.openContextMenu(); - await t.click(Selector("button.action-album")).click(Selector(".input-album input")); - - await t - .expect(page.selectOption.withText("Holiday").visible) - .ok() - .expect(page.selectOption.withText("Christmas").visible) - .ok(); - - await t.typeText(Selector(".input-album input"), "C", { replace: true }); - - await t - .expect(page.selectOption.withText("Holiday").visible) - .notOk() - .expect(page.selectOption.withText("Christmas").visible) - .ok() - .expect(page.selectOption.withText("C").visible) - .ok(); -}); - -test.meta("testID", "albums-007").meta({ type: "smoke" })( - "Create, Edit, delete sharing link", - async (t) => { - await page.testCreateEditDeleteSharingLink("albums"); - } -); diff --git a/frontend/tests/acceptance/calendar.js b/frontend/tests/acceptance/calendar.js deleted file mode 100644 index 07a0b8483..000000000 --- a/frontend/tests/acceptance/calendar.js +++ /dev/null @@ -1,150 +0,0 @@ -import { Selector } from "testcafe"; -import testcafeconfig from "./testcafeconfig"; -import Menu from "../page-model/menu"; -import Album from "../page-model/album"; -import Toolbar from "../page-model/toolbar"; -import ContextMenu from "../page-model/context-menu"; -import Photo from "../page-model/photo"; -import Page from "../page-model/page"; -import AlbumDialog from "../page-model/dialog-album"; - -fixture`Test calendar`.page`${testcafeconfig.url}`; - -const menu = new Menu(); -const album = new Album(); -const toolbar = new Toolbar(); -const contextmenu = new ContextMenu(); -const photo = new Photo(); -const page = new Page(); -const albumdialog = new AlbumDialog(); - -test.meta("testID", "calendar-001").meta({ type: "smoke" })("View calendar", async (t) => { - await menu.openPage("calendar"); - - await t - .expect(Selector("a").withText("May 2019").visible) - .ok() - .expect(Selector("a").withText("October 2019").visible) - .ok(); -}); - -test.meta("testID", "calendar-002")("Update calendar details", async (t) => { - await menu.openPage("calendar"); - await toolbar.search("March 2014"); - const AlbumUid = await album.getNthAlbumUid("all", 0); - - await t.expect(page.cardTitle.nth(0).innerText).contains("March 2014"); - - await t.click(page.cardTitle.nth(0)).typeText(albumdialog.location, "Snow", { replace: true }); - - await t.expect(albumdialog.description.value).eql("").expect(albumdialog.category.value).eql(""); - - await t - .typeText(albumdialog.description, "We went to ski") - .typeText(albumdialog.category, "Mountains") - .pressKey("enter") - .click(albumdialog.dialogSave); - - await t - .expect(page.cardTitle.nth(0).innerText) - .contains("March 2014") - .expect(page.cardDescription.nth(0).innerText) - .contains("We went to ski") - .expect(Selector("div.caption").nth(1).innerText) - .contains("Mountains") - .expect(Selector("div.caption").nth(2).innerText) - .contains("Snow"); - - await album.openNthAlbum(0); - - await t.expect(toolbar.toolbarSecondTitle.innerText).contains("March 2014"); - await t.expect(toolbar.toolbarDescription.innerText).contains("We went to ski"); - await menu.openPage("calendar"); - if (t.browser.platform === "mobile") { - await toolbar.search("category:Mountains"); - } else { - await toolbar.setFilter("category", "Mountains"); - } - - await t.expect(page.cardTitle.nth(0).innerText).contains("March 2014"); - - await album.openAlbumWithUid(AlbumUid); - await toolbar.triggerToolbarAction("edit"); - - await t - .expect(albumdialog.description.value) - .eql("We went to ski") - .expect(albumdialog.category.value) - .eql("Mountains") - .expect(albumdialog.location.value) - .eql("Snow"); - - await t - .click(albumdialog.category) - .pressKey("ctrl+a delete") - .pressKey("enter") - .click(albumdialog.description) - .pressKey("ctrl+a delete") - .pressKey("enter") - .click(albumdialog.location) - .pressKey("ctrl+a delete") - .pressKey("enter") - .click(albumdialog.dialogSave); - await menu.openPage("calendar"); - await toolbar.search("March 2014"); - - await t - .expect(page.cardDescription.innerText) - .notContains("We went to ski") - .expect(Selector("div.caption").nth(0).innerText) - .notContains("Snow"); -}); - -test.meta("testID", "calendar-003")("Create, Edit, delete sharing link for calendar", async (t) => { - await page.testCreateEditDeleteSharingLink("calendar"); -}); - -test.meta("testID", "calendar-004").meta({ type: "smoke" })( - "Create/delete album-clone from calendar", - async (t) => { - await menu.openPage("albums"); - const AlbumCount = await album.getAlbumCount("all"); - await menu.openPage("calendar"); - const SecondCalendarUid = await album.getNthAlbumUid("all", 1); - await album.openAlbumWithUid(SecondCalendarUid); - const PhotoCountInCalendar = await photo.getPhotoCount("all"); - const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); - const SecondPhotoUid = await photo.getNthPhotoUid("image", 1); - await menu.openPage("calendar"); - await album.selectAlbumFromUID(SecondCalendarUid); - await contextmenu.triggerContextMenuAction("clone", "NotYetExistingAlbumForCalendar"); - await menu.openPage("albums"); - const AlbumCountAfterCreation = await album.getAlbumCount("all"); - - await t.expect(AlbumCountAfterCreation).eql(AlbumCount + 1); - - await toolbar.search("NotYetExistingAlbumForCalendar"); - const AlbumUid = await album.getNthAlbumUid("all", 0); - await album.openAlbumWithUid(AlbumUid); - const PhotoCountInAlbum = await photo.getPhotoCount("all"); - - await t.expect(PhotoCountInAlbum).eql(PhotoCountInCalendar); - - await photo.checkPhotoVisibility(FirstPhotoUid, true); - await photo.checkPhotoVisibility(SecondPhotoUid, true); - await menu.openPage("albums"); - await album.selectAlbumFromUID(AlbumUid); - await contextmenu.triggerContextMenuAction("delete", ""); - if (t.browser.platform === "mobile") { - await t.eval(() => location.reload()); - } else { - await toolbar.triggerToolbarAction("reload"); - } - const AlbumCountAfterDelete = await album.getAlbumCount("all"); - await t.expect(AlbumCountAfterDelete).eql(AlbumCount); - await menu.openPage("calendar"); - await album.openAlbumWithUid(SecondCalendarUid); - await photo.checkPhotoVisibility(FirstPhotoUid, true); - await photo.checkPhotoVisibility(SecondPhotoUid, true); - } -); diff --git a/frontend/tests/acceptance/components.js b/frontend/tests/acceptance/components.js deleted file mode 100644 index 30c8dc5bb..000000000 --- a/frontend/tests/acceptance/components.js +++ /dev/null @@ -1,61 +0,0 @@ -import { Selector } from "testcafe"; -import testcafeconfig from "./testcafeconfig"; -import Toolbar from "../page-model/toolbar"; - -fixture`Test components`.page`${testcafeconfig.url}`; - -const toolbar = new Toolbar(); - -test.meta("testID", "components-001").meta({ type: "smoke" })("Test filter options", async (t) => { - await t.expect(Selector("body").withText("object Object").exists).notOk(); -}); - -test.meta("testID", "components-002").meta({ type: "smoke" })("Fullscreen mode", async (t) => { - await t.click(Selector("div.type-image div.image.clickable").nth(0)); - - if (await Selector("#photo-viewer").visible) { - await t - .expect(Selector("#photo-viewer").visible) - .ok() - .expect(Selector("img.pswp__img").visible) - .ok(); - } else { - await t.expect(Selector("div.video-viewer").visible).ok(); - } -}); - -test.meta("testID", "components-003").meta({ type: "smoke" })("Mosaic view", async (t) => { - await toolbar.setFilter("view", "Mosaic"); - - await t - .expect(Selector("div.type-image.image.clickable").visible) - .ok() - .expect(Selector("div.p-photo-mosaic").visible) - .ok() - .expect(Selector("div.is-photo div.caption").exists) - .notOk() - .expect(Selector("#photo-viewer").visible) - .notOk(); -}); - -test.meta("testID", "components-004")("List view", async (t) => { - await toolbar.setFilter("view", "List"); - - await t - .expect(Selector("table.v-datatable").visible) - .ok() - .expect(Selector("div.list-view").visible) - .ok(); -}); - -test.meta("testID", "components-005").meta({ type: "smoke" })("Card view", async (t) => { - await toolbar.setFilter("view", "Cards"); - - await t - .expect(Selector("div.type-image div.image.clickable").visible) - .ok() - .expect(Selector("div.is-photo div.caption").visible) - .ok() - .expect(Selector("#photo-viewer").visible) - .notOk(); -}); diff --git a/frontend/tests/acceptance/folders.js b/frontend/tests/acceptance/folders.js deleted file mode 100644 index 9e365e7db..000000000 --- a/frontend/tests/acceptance/folders.js +++ /dev/null @@ -1,159 +0,0 @@ -import { Selector } from "testcafe"; -import testcafeconfig from "./testcafeconfig"; -import Menu from "../page-model/menu"; -import Album from "../page-model/album"; -import Toolbar from "../page-model/toolbar"; -import ContextMenu from "../page-model/context-menu"; -import Photo from "../page-model/photo"; -import Page from "../page-model/page"; -import AlbumDialog from "../page-model/dialog-album"; - -fixture`Test folders`.page`${testcafeconfig.url}`; - -const menu = new Menu(); -const album = new Album(); -const toolbar = new Toolbar(); -const contextmenu = new ContextMenu(); -const photo = new Photo(); -const page = new Page(); -const albumdialog = new AlbumDialog(); - -test.meta("testID", "folders-001").meta({ type: "smoke" })("View folders", async (t) => { - await menu.openPage("folders"); - - await t - .expect(Selector("a").withText("BotanicalGarden").visible) - .ok() - .expect(Selector("a").withText("Kanada").visible) - .ok() - .expect(Selector("a").withText("KorsikaAdventure").visible) - .ok(); -}); - -test.meta("testID", "folders-002")("Update folder details", async (t) => { - await menu.openPage("folders"); - await toolbar.search("Kanada"); - const AlbumUid = await album.getNthAlbumUid("all", 0); - await t.expect(page.cardTitle.nth(0).innerText).contains("Kanada"); - - await t.click(page.cardTitle.nth(0)); - - await t - .expect(albumdialog.title.value) - .eql("Kanada") - .expect(albumdialog.location.value) - .eql("") - .expect(albumdialog.description.value) - .eql("") - .expect(albumdialog.category.value) - .eql(""); - - await t - .typeText(albumdialog.title, "MyFolder", { replace: true }) - .typeText(albumdialog.location, "USA", { replace: true }) - .typeText(albumdialog.description, "Last holiday") - .typeText(albumdialog.category, "Mountains") - .pressKey("enter") - .click(albumdialog.dialogSave); - - await t - .expect(page.cardTitle.nth(0).innerText) - .contains("MyFolder") - .expect(page.cardDescription.nth(0).innerText) - .contains("Last holiday") - .expect(Selector("div.caption").nth(1).innerText) - .contains("Mountains") - .expect(Selector("div.caption").nth(2).innerText) - .contains("USA"); - - await album.openNthAlbum(0); - - await t - .expect(toolbar.toolbarDescription.nth(0).innerText) - .contains("Last holiday") - .expect(toolbar.toolbarSecondTitle.innerText) - .contains("MyFolder"); - - await menu.openPage("folders"); - if (t.browser.platform === "mobile") { - await toolbar.search("category:Mountains"); - } else { - await toolbar.setFilter("category", "Mountains"); - } - - await t.expect(page.cardTitle.nth(0).innerText).contains("MyFolder"); - - await album.openAlbumWithUid(AlbumUid); - await toolbar.triggerToolbarAction("edit"); - - await t - .expect(albumdialog.description.value) - .eql("Last holiday") - .expect(albumdialog.category.value) - .eql("Mountains") - .expect(albumdialog.location.value) - .eql("USA"); - - await t - .typeText(albumdialog.title, "Kanada", { replace: true }) - .click(albumdialog.category) - .pressKey("ctrl+a delete") - .pressKey("enter") - .click(albumdialog.description) - .pressKey("ctrl+a delete") - .pressKey("enter") - .click(albumdialog.location) - .pressKey("ctrl+a delete") - .pressKey("enter") - .click(albumdialog.dialogSave); - await menu.openPage("folders"); - await toolbar.search("Kanada"); - - await t - .expect(page.cardTitle.nth(0).innerText) - .contains("Kanada") - .expect(page.cardDescription.nth(0).innerText) - .notContains("We went to ski") - .expect(Selector("div.caption").nth(0).innerText) - .notContains("USA"); -}); - -test.meta("testID", "folders-003")("Create, Edit, delete sharing link", async (t) => { - await page.testCreateEditDeleteSharingLink("folders"); -}); - -test.meta("testID", "folders-004")("Create/delete album-clone from folder", async (t) => { - await menu.openPage("albums"); - const AlbumCount = await album.getAlbumCount("all"); - await menu.openPage("folders"); - const ThirdFolderUid = await album.getNthAlbumUid("all", 2); - await album.openAlbumWithUid(ThirdFolderUid); - const PhotoCountInFolder = await photo.getPhotoCount("all"); - const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); - await menu.openPage("folders"); - await album.selectAlbumFromUID(ThirdFolderUid); - await contextmenu.triggerContextMenuAction("clone", "NotYetExistingAlbumForFolder"); - await menu.openPage("albums"); - const AlbumCountAfterCreation = await album.getAlbumCount("all"); - - await t.expect(AlbumCountAfterCreation).eql(AlbumCount + 1); - - await toolbar.search("NotYetExistingAlbumForFolder"); - const AlbumUid = await album.getNthAlbumUid("all", 0); - await album.openAlbumWithUid(AlbumUid); - const PhotoCountInAlbum = await photo.getPhotoCount("all"); - - await t.expect(PhotoCountInAlbum).eql(PhotoCountInFolder); - - await photo.checkPhotoVisibility(FirstPhotoUid, true); - await menu.openPage("albums"); - await album.selectAlbumFromUID(AlbumUid); - await contextmenu.triggerContextMenuAction("delete", ""); - const AlbumCountAfterDelete = await album.getAlbumCount("all"); - - await t.expect(AlbumCountAfterDelete).eql(AlbumCount); - - await menu.openPage("folders"); - await album.openAlbumWithUid(ThirdFolderUid); - await photo.checkPhotoVisibility(FirstPhotoUid, true); -}); diff --git a/frontend/tests/acceptance/moment.js b/frontend/tests/acceptance/moment.js deleted file mode 100644 index fc0e3ebf6..000000000 --- a/frontend/tests/acceptance/moment.js +++ /dev/null @@ -1,148 +0,0 @@ -import { Selector } from "testcafe"; -import testcafeconfig from "./testcafeconfig"; -import Menu from "../page-model/menu"; -import Album from "../page-model/album"; -import Toolbar from "../page-model/toolbar"; -import ContextMenu from "../page-model/context-menu"; -import Photo from "../page-model/photo"; -import Page from "../page-model/page"; -import AlbumDialog from "../page-model/dialog-album"; - -fixture`Test moments`.page`${testcafeconfig.url}`; - -const menu = new Menu(); -const album = new Album(); -const toolbar = new Toolbar(); -const contextmenu = new ContextMenu(); -const photo = new Photo(); -const page = new Page(); -const albumdialog = new AlbumDialog(); - -test.meta("testID", "moments-001")("Update moment details", async (t) => { - await menu.openPage("moments"); - await toolbar.search("Nature"); - const AlbumUid = await album.getNthAlbumUid("all", 0); - - await t.expect(page.cardTitle.nth(0).innerText).contains("Nature"); - - await t.click(page.cardTitle.nth(0)); - - await t - .expect(albumdialog.title.value) - .eql("Nature & Landscape") - .expect(albumdialog.location.value) - .eql("") - .expect(albumdialog.description.value) - .eql("") - .expect(albumdialog.category.value) - .eql(""); - - await t - .typeText(albumdialog.title, "Winter", { replace: true }) - .typeText(albumdialog.location, "Snow-Land", { replace: true }) - .typeText(albumdialog.description, "We went to ski") - .typeText(albumdialog.category, "Mountains") - .pressKey("enter") - .click(albumdialog.dialogSave); - - await t - .expect(page.cardTitle.nth(0).innerText) - .contains("Winter") - .expect(page.cardDescription.nth(0).innerText) - .contains("We went to ski") - .expect(Selector("div.caption").nth(1).innerText) - .contains("Mountains") - .expect(Selector("div.caption").nth(2).innerText) - .contains("Snow-Land"); - - await album.openNthAlbum(0); - - await t.expect(toolbar.toolbarSecondTitle.innerText).contains("Winter"); - await t.expect(toolbar.toolbarDescription.innerText).contains("We went to ski"); - - await menu.openPage("moments"); - if (t.browser.platform === "mobile") { - await toolbar.search("category:Mountains"); - } else { - await toolbar.setFilter("category", "Mountains"); - } - - await t.expect(page.cardTitle.nth(0).innerText).contains("Winter"); - - await album.openAlbumWithUid(AlbumUid); - await toolbar.triggerToolbarAction("edit"); - - await t - .expect(albumdialog.description.value) - .eql("We went to ski") - .expect(albumdialog.category.value) - .eql("Mountains") - .expect(albumdialog.location.value) - .eql("Snow-Land"); - - await t - .typeText(albumdialog.title, "Nature & Landscape", { replace: true }) - .click(albumdialog.category) - .pressKey("ctrl+a delete") - .pressKey("enter") - .click(albumdialog.description) - .pressKey("ctrl+a delete") - .pressKey("enter") - .click(albumdialog.location) - .pressKey("ctrl+a delete") - .pressKey("enter") - .click(albumdialog.dialogSave); - await menu.openPage("moments"); - await toolbar.search("Nature"); - - await t - .expect(page.cardTitle.nth(0).innerText) - .contains("Nature & Landscape") - .expect(page.cardDescription.innerText) - .notContains("We went to ski") - .expect(Selector("div.caption").nth(0).innerText) - .notContains("Snow-Land"); -}); - -test.meta("testID", "moments-002")("Create, Edit, delete sharing link for moment", async (t) => { - await page.testCreateEditDeleteSharingLink("moments"); -}); - -test.meta("testID", "moments-003")("Create/delete album-clone from moment", async (t) => { - await menu.openPage("albums"); - const AlbumCount = await album.getAlbumCount("all"); - await menu.openPage("moments"); - const FirstMomentUid = await album.getNthAlbumUid("all", 0); - await album.openAlbumWithUid(FirstMomentUid); - const PhotoCountInMoment = await photo.getPhotoCount("all"); - const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); - const SecondPhotoUid = await photo.getNthPhotoUid("image", 1); - await menu.openPage("moments"); - await album.selectAlbumFromUID(FirstMomentUid); - await contextmenu.triggerContextMenuAction("clone", "NotYetExistingAlbumForMoment"); - await menu.openPage("albums"); - const AlbumCountAfterCreation = await album.getAlbumCount("all"); - - await t.expect(AlbumCountAfterCreation).eql(AlbumCount + 1); - - await toolbar.search("NotYetExistingAlbumForMoment"); - const AlbumUid = await album.getNthAlbumUid("all", 0); - await album.openAlbumWithUid(AlbumUid); - const PhotoCountInAlbum = await photo.getPhotoCount("all"); - - await t.expect(PhotoCountInAlbum).eql(PhotoCountInMoment); - - await photo.checkPhotoVisibility(FirstPhotoUid, true); - await photo.checkPhotoVisibility(SecondPhotoUid, true); - await menu.openPage("albums"); - await album.selectAlbumFromUID(AlbumUid); - await contextmenu.triggerContextMenuAction("delete", ""); - const AlbumCountAfterDelete = await album.getAlbumCount("all"); - - await t.expect(AlbumCountAfterDelete).eql(AlbumCount); - - await menu.openPage("moments"); - await album.openAlbumWithUid(FirstMomentUid); - await photo.checkPhotoVisibility(FirstPhotoUid, true); - await photo.checkPhotoVisibility(SecondPhotoUid, true); -}); diff --git a/frontend/tests/acceptance/originals.js b/frontend/tests/acceptance/originals.js deleted file mode 100644 index e48793bea..000000000 --- a/frontend/tests/acceptance/originals.js +++ /dev/null @@ -1,99 +0,0 @@ -import { Selector } from "testcafe"; -import testcafeconfig from "./testcafeconfig"; -import Menu from "../page-model/menu"; -import Photo from "../page-model/photo"; -import Toolbar from "../page-model/toolbar"; -import ContextMenu from "../page-model/context-menu"; -import Album from "../page-model/album"; -import Originals from "../page-model/originals"; - -fixture`Test files`.page`${testcafeconfig.url}`; - -const menu = new Menu(); -const photo = new Photo(); -const toolbar = new Toolbar(); -const contextmenu = new ContextMenu(); -const album = new Album(); -const originals = new Originals(); - -test.meta("testID", "originals-001").meta({ type: "smoke" })("Navigate in originals", async (t) => { - await menu.openPage("originals"); - await t.click(Selector("button").withText("Vacation")); - const FirstItemInVacationName = await Selector("div.result", { timeout: 15000 }).nth(0).innerText; - const KanadaFolderUid = await originals.getNthFolderUid(0); - const SecondItemInVacationName = await Selector("div.result").nth(1).innerText; - - await t - .expect(FirstItemInVacationName) - .contains("Kanada") - .expect(SecondItemInVacationName) - .contains("Korsika"); - - await originals.openFolderWithUid(KanadaFolderUid); - - const FirstItemInKanadaName = await Selector("div.result").nth(0).innerText; - const SecondItemInKanadaName = await Selector("div.result").nth(1).innerText; - - await t - .expect(FirstItemInKanadaName) - .contains("BotanicalGarden") - .expect(SecondItemInKanadaName) - .contains("originals-001_2.jpg"); - - await t.click(Selector("button").withText("BotanicalGarden")); - const FirstItemInBotanicalGardenName = await Selector("div.result", { timeout: 15000 }).nth(0) - .innerText; - await t.expect(FirstItemInBotanicalGardenName).contains("originals-001_1.jpg"); - await t.click(Selector('a[href="/library/files/Vacation"]')); - const FolderCount = await originals.getFolderCount(); - - await t.expect(FolderCount).eql(2); -}); - -test.meta("testID", "originals-002").meta({ type: "smoke" })( - "Add original files to album", - async (t) => { - await menu.openPage("albums"); - await toolbar.search("KanadaVacation"); - - await t.expect(Selector("div.no-results").visible).ok(); - - await menu.openPage("originals"); - await t.click(Selector("button").withText("Vacation")); - const KanadaFolderUid = await originals.getNthFolderUid(0); - await originals.openFolderWithUid(KanadaFolderUid); - const FilesCountInKanada = await originals.getFileCount(); - await t.click(Selector("button").withText("BotanicalGarden")); - const FilesCountInKanadaSubfolder = await originals.getFileCount(); - await t.navigateTo("/library/files/Vacation"); - await originals.triggerHoverAction("is-folder", "uid", KanadaFolderUid, "select"); - await contextmenu.checkContextMenuCount("1"); - await contextmenu.triggerContextMenuAction("album", "KanadaVacation"); - await menu.openPage("albums"); - await toolbar.search("KanadaVacation"); - const AlbumUid = await album.getNthAlbumUid("all", 0); - await album.openAlbumWithUid(AlbumUid); - const PhotoCountAfterAdd = await photo.getPhotoCount("all"); - - await t.expect(PhotoCountAfterAdd).eql(FilesCountInKanada + FilesCountInKanadaSubfolder); - - await menu.openPage("albums"); - await album.triggerHoverAction("uid", AlbumUid, "select"); - await contextmenu.checkContextMenuCount("1"); - await contextmenu.triggerContextMenuAction("delete", ""); - } -); - -test.meta("testID", "originals-003")("Download available in originals", async (t) => { - await menu.openPage("originals"); - const FirstFile = await originals.getNthFileUid(0); - await originals.triggerHoverAction("is-file", "uid", FirstFile, "select"); - await contextmenu.checkContextMenuCount("1"); - await contextmenu.checkContextMenuActionAvailability("download", true); - await contextmenu.clearSelection(); - const FirstFolder = await originals.getNthFolderUid(0); - await originals.triggerHoverAction("is-folder", "uid", FirstFolder, "select"); - await contextmenu.checkContextMenuCount("1"); - await contextmenu.checkContextMenuActionAvailability("download", true); - await contextmenu.clearSelection(); -}); diff --git a/frontend/tests/page-model/account.js b/frontend/tests/acceptance/page-model/account.js similarity index 100% rename from frontend/tests/page-model/account.js rename to frontend/tests/acceptance/page-model/account.js diff --git a/frontend/tests/page-model/album.js b/frontend/tests/acceptance/page-model/album.js similarity index 100% rename from frontend/tests/page-model/album.js rename to frontend/tests/acceptance/page-model/album.js diff --git a/frontend/tests/page-model/context-menu.js b/frontend/tests/acceptance/page-model/context-menu.js similarity index 100% rename from frontend/tests/page-model/context-menu.js rename to frontend/tests/acceptance/page-model/context-menu.js diff --git a/frontend/tests/page-model/dialog-album.js b/frontend/tests/acceptance/page-model/dialog-album.js similarity index 100% rename from frontend/tests/page-model/dialog-album.js rename to frontend/tests/acceptance/page-model/dialog-album.js diff --git a/frontend/tests/page-model/dialog-share.js b/frontend/tests/acceptance/page-model/dialog-share.js similarity index 100% rename from frontend/tests/page-model/dialog-share.js rename to frontend/tests/acceptance/page-model/dialog-share.js diff --git a/frontend/tests/page-model/label.js b/frontend/tests/acceptance/page-model/label.js similarity index 100% rename from frontend/tests/page-model/label.js rename to frontend/tests/acceptance/page-model/label.js diff --git a/frontend/tests/page-model/library.js b/frontend/tests/acceptance/page-model/library.js similarity index 100% rename from frontend/tests/page-model/library.js rename to frontend/tests/acceptance/page-model/library.js diff --git a/frontend/tests/page-model/menu.js b/frontend/tests/acceptance/page-model/menu.js similarity index 100% rename from frontend/tests/page-model/menu.js rename to frontend/tests/acceptance/page-model/menu.js diff --git a/frontend/tests/page-model/originals.js b/frontend/tests/acceptance/page-model/originals.js similarity index 100% rename from frontend/tests/page-model/originals.js rename to frontend/tests/acceptance/page-model/originals.js diff --git a/frontend/tests/page-model/page.js b/frontend/tests/acceptance/page-model/page.js similarity index 100% rename from frontend/tests/page-model/page.js rename to frontend/tests/acceptance/page-model/page.js diff --git a/frontend/tests/page-model/photo-edit.js b/frontend/tests/acceptance/page-model/photo-edit.js similarity index 100% rename from frontend/tests/page-model/photo-edit.js rename to frontend/tests/acceptance/page-model/photo-edit.js diff --git a/frontend/tests/page-model/photo.js b/frontend/tests/acceptance/page-model/photo.js similarity index 100% rename from frontend/tests/page-model/photo.js rename to frontend/tests/acceptance/page-model/photo.js diff --git a/frontend/tests/page-model/photoviewer.js b/frontend/tests/acceptance/page-model/photoviewer.js similarity index 100% rename from frontend/tests/page-model/photoviewer.js rename to frontend/tests/acceptance/page-model/photoviewer.js diff --git a/frontend/tests/page-model/settings.js b/frontend/tests/acceptance/page-model/settings.js similarity index 100% rename from frontend/tests/page-model/settings.js rename to frontend/tests/acceptance/page-model/settings.js diff --git a/frontend/tests/page-model/subject.js b/frontend/tests/acceptance/page-model/subject.js similarity index 100% rename from frontend/tests/page-model/subject.js rename to frontend/tests/acceptance/page-model/subject.js diff --git a/frontend/tests/page-model/toolbar.js b/frontend/tests/acceptance/page-model/toolbar.js similarity index 100% rename from frontend/tests/page-model/toolbar.js rename to frontend/tests/acceptance/page-model/toolbar.js diff --git a/frontend/tests/acceptance/photos-upload-delete.js b/frontend/tests/acceptance/photos-upload-delete.js deleted file mode 100644 index 923eb290a..000000000 --- a/frontend/tests/acceptance/photos-upload-delete.js +++ /dev/null @@ -1,282 +0,0 @@ -import { Selector } from "testcafe"; -import testcafeconfig from "./testcafeconfig"; -import fs from "fs"; -import Menu from "../page-model/menu"; -import Toolbar from "../page-model/toolbar"; -import ContextMenu from "../page-model/context-menu"; -import Photo from "../page-model/photo"; -import Page from "../page-model/page"; -import PhotoEdit from "../page-model/photo-edit"; -import Originals from "../page-model/originals"; -import Album from "../page-model/album"; -import Library from "../page-model/library"; - -fixture`Test photos upload and delete`.page`${testcafeconfig.url}`; - -const menu = new Menu(); -const album = new Album(); -const toolbar = new Toolbar(); -const contextmenu = new ContextMenu(); -const photo = new Photo(); -const page = new Page(); -const photoedit = new PhotoEdit(); -const originals = new Originals(); -const library = new Library(); - -test.meta("testID", "photos-upload-delete-001").meta({ type: "smoke" })( - "Upload + Delete jpg/json", - async (t) => { - await menu.openNav(); - const InitialOriginalsCount = await Selector(".nav-originals .nav-count", { timeout: 5000 }) - .innerText; - await t.expect(fs.existsSync("../storage/acceptance/originals/2020/10")).notOk(); - await toolbar.search("digikam"); - const PhotoCount = await photo.getPhotoCount("all"); - - await t.expect(PhotoCount).eql(0); - - await toolbar.triggerToolbarAction("upload"); - await t - .setFilesToUpload(Selector(".input-upload"), [ - "./upload-files/digikam.jpg", - "./upload-files/digikam.json", - ]) - .wait(15000); - const PhotoCountAfterUpload = await photo.getPhotoCount("all"); - - await t.expect(PhotoCountAfterUpload).eql(1); - - const UploadedPhoto = await photo.getNthPhotoUid("all", 0); - await t.navigateTo("/library/files/2020/10"); - const FileCount = await originals.getFileCount(); - - await t.expect(FileCount).eql(2); - - await menu.openNav(); - const OriginalsCountAfterUpload = await Selector(".nav-originals .nav-count", { timeout: 5000 }) - .innerText; - await t.expect(parseInt(InitialOriginalsCount) + 2).eql(parseInt(OriginalsCountAfterUpload)); - - await menu.openPage("browse"); - await toolbar.search("digikam"); - await photo.triggerHoverAction("uid", UploadedPhoto, "select"); - await contextmenu.triggerContextMenuAction("edit", ""); - await t.click(photoedit.filesTab); - - await t - .expect(Selector("div.caption").withText(".json").visible) - .ok() - .expect(Selector("div.caption").withText(".jpg").visible) - .ok(); - - await t.click(photoedit.dialogClose); - - if (t.browser.platform !== "mobile") { - await t.expect(fs.existsSync("../storage/acceptance/originals/2020/10")).ok(); - const originalsLength = fs.readdirSync("../storage/acceptance/originals/2020/10").length; - await t.expect(originalsLength).eql(2); - } - - await contextmenu.triggerContextMenuAction("archive", ""); - await menu.openPage("archive"); - await photo.triggerHoverAction("uid", UploadedPhoto, "select"); - await contextmenu.triggerContextMenuAction("delete", ""); - await menu.openPage("browse"); - await toolbar.search("digikam"); - await photo.checkPhotoVisibility(UploadedPhoto, false); - await t.navigateTo("/library/files/2020/10"); - const FileCountAfterDelete = await originals.getFileCount(); - - await t.expect(FileCountAfterDelete).eql(0); - if (t.browser.platform !== "mobile") { - const originalsLengthAfterDelete = fs.readdirSync( - "../storage/acceptance/originals/2020/10" - ).length; - await t.expect(originalsLengthAfterDelete).eql(0); - } - } -); - -test.meta("testID", "photos-upload-delete-002")("Upload + Delete video", async (t) => { - await t.expect(fs.existsSync("../storage/acceptance/originals/2020/06")).notOk(); - await toolbar.search("korn"); - const PhotoCount = await photo.getPhotoCount("all"); - - await t.expect(PhotoCount).eql(0); - - await toolbar.triggerToolbarAction("upload"); - await t.setFilesToUpload(Selector(".input-upload"), ["./upload-files/korn.mp4"]).wait(15000); - const PhotoCountAfterUpload = await photo.getPhotoCount("all"); - - await t.expect(PhotoCountAfterUpload).eql(1); - - const UploadedPhoto = await photo.getNthPhotoUid("all", 0); - await t.navigateTo("/library/files/2020/06"); - const FileCount = await originals.getFileCount(); - - await t.expect(FileCount).eql(1); - - await menu.openPage("browse"); - await toolbar.search("korn"); - await photo.triggerHoverAction("uid", UploadedPhoto, "select"); - await contextmenu.triggerContextMenuAction("edit", ""); - await t.click(photoedit.filesTab); - - await t - .expect(Selector("div.caption").withText(".mp4").visible) - .ok() - .expect(Selector("div.caption").withText(".jpg").visible) - .ok(); - - await t.click(photoedit.dialogClose); - - if (t.browser.platform !== "mobile") { - await t.expect(fs.existsSync("../storage/acceptance/originals/2020/06")).ok(); - const originalsLength = fs.readdirSync("../storage/acceptance/originals/2020/06").length; - await t.expect(originalsLength).eql(1); - const sidecarLength = fs.readdirSync("../storage/acceptance/originals/2020/06").length; - await t.expect(sidecarLength).eql(1); - } - - await contextmenu.triggerContextMenuAction("archive", ""); - await menu.openPage("archive"); - await photo.triggerHoverAction("uid", UploadedPhoto, "select"); - await contextmenu.triggerContextMenuAction("delete", ""); - await menu.openPage("browse"); - await toolbar.search("korn"); - await photo.checkPhotoVisibility(UploadedPhoto, false); - await t.navigateTo("/library/files/2020/06"); - const FileCountAfterDelete = await originals.getFileCount(); - - await t.expect(FileCountAfterDelete).eql(0); - if (t.browser.platform !== "mobile") { - const originalsLengthAfterDelete = fs.readdirSync( - "../storage/acceptance/originals/2020/06" - ).length; - await t.expect(originalsLengthAfterDelete).eql(0); - const sidecarLengthAfterDelete = fs.readdirSync( - "../storage/acceptance/originals/2020/06" - ).length; - await t.expect(sidecarLengthAfterDelete).eql(0); - } -}); - -test.meta("testID", "photos-upload-delete-003")("Upload to existing Album + Delete", async (t) => { - await menu.openPage("albums"); - await toolbar.search("Christmas"); - const AlbumUid = await album.getNthAlbumUid("all", 0); - await album.openAlbumWithUid(AlbumUid); - const PhotoCount = await photo.getPhotoCount("all"); - await toolbar.triggerToolbarAction("upload"); - await t - .click(Selector(".input-albums")) - .click(page.selectOption.withText("Christmas")) - .setFilesToUpload(Selector(".input-upload"), ["./upload-files/ladybug.jpg"]) - .wait(15000); - const PhotoCountAfterUpload = await photo.getPhotoCount("all"); - - await t.expect(PhotoCountAfterUpload).eql(PhotoCount + 1); - - await menu.openPage("browse"); - await toolbar.search("ladybug"); - const UploadedPhotoUid = await photo.getNthPhotoUid("all", 0); - await photo.triggerHoverAction("uid", UploadedPhotoUid, "select"); - await contextmenu.triggerContextMenuAction("archive", ""); - await menu.openPage("archive"); - await photo.triggerHoverAction("uid", UploadedPhotoUid, "select"); - await contextmenu.triggerContextMenuAction("delete", ""); - await menu.openPage("browse"); - await toolbar.search("ladybug"); - await photo.checkPhotoVisibility(UploadedPhotoUid, false); - await menu.openPage("albums"); - await album.openAlbumWithUid(AlbumUid); - await photo.checkPhotoVisibility(UploadedPhotoUid, false); - const PhotoCountAfterDelete = await photo.getPhotoCount("all"); - - await t.expect(PhotoCountAfterDelete).eql(PhotoCount); -}); - -test.meta("testID", "photos-upload-delete-004")("Upload jpg to new Album + Delete", async (t) => { - await menu.openPage("albums"); - const AlbumCount = await album.getAlbumCount("all"); - await toolbar.triggerToolbarAction("upload"); - await t - .click(Selector(".input-albums")) - .typeText(Selector(".input-albums input"), "NewCreatedAlbum") - .pressKey("enter") - .setFilesToUpload(Selector(".input-upload"), ["./upload-files/digikam.jpg"]) - .wait(15000); - if (t.browser.platform === "mobile") { - await t.eval(() => location.reload()); - } else { - await toolbar.triggerToolbarAction("reload"); - } - const AlbumCountAfterUpload = await album.getAlbumCount("all"); - - await t.expect(AlbumCountAfterUpload).eql(AlbumCount + 1); - - await toolbar.search("NewCreatedAlbum"); - await album.openNthAlbum(0); - const PhotoCount = await photo.getPhotoCount("all"); - - await t.expect(PhotoCount).eql(1); - - await menu.openPage("browse"); - await toolbar.search("digikam"); - const UploadedPhotoUid = await photo.getNthPhotoUid("all", 0); - await photo.triggerHoverAction("uid", UploadedPhotoUid, "select"); - await contextmenu.triggerContextMenuAction("archive", ""); - await menu.openPage("archive"); - await photo.triggerHoverAction("uid", UploadedPhotoUid, "select"); - await contextmenu.triggerContextMenuAction("delete", ""); - await menu.openPage("browse"); - await toolbar.search("digikam"); - await photo.checkPhotoVisibility(UploadedPhotoUid, false); - await menu.openPage("albums"); - await toolbar.search("NewCreatedAlbum"); - await album.openNthAlbum(0); - await photo.checkPhotoVisibility(UploadedPhotoUid, false); - const PhotoCountAfterDelete = await photo.getPhotoCount("all"); - - await t.expect(PhotoCountAfterDelete).eql(0); - - await menu.openPage("albums"); - await toolbar.search("NewCreatedAlbum"); - await album.triggerHoverAction("nth", 0, "select"); - await contextmenu.checkContextMenuCount("1"); - await contextmenu.triggerContextMenuAction("delete", ""); -}); - -test.meta("testID", "photos-upload-delete-005").meta({ type: "smoke" })( - "Try uploading nsfw file", - async (t) => { - await toolbar.triggerToolbarAction("upload"); - await t - .setFilesToUpload(Selector(".input-upload"), ["./upload-files/hentai_2.jpg"]) - .wait(15000); - await menu.openPage("library"); - await t.click(library.logsTab); - - await t.expect(Selector("p").withText("hentai_2.jpg might be offensive").visible).ok(); - } -); - -test.meta("testID", "photos-upload-delete-006").meta({ type: "smoke" })( - "Try uploading txt file", - async (t) => { - await menu.openNav(); - const InitialOriginalsCount = await Selector(".nav-originals .nav-count", { - timeout: 10000, - }).innerText; - await menu.openPage("browse"); - - await toolbar.triggerToolbarAction("upload"); - await t.setFilesToUpload(Selector(".input-upload"), ["./upload-files/foo.txt"]).wait(15000); - await menu.openNav(); - const OriginalsCountAfterUpload = await Selector(".nav-originals .nav-count", { - timeout: 10000, - }).innerText; - - await t.expect(parseInt(InitialOriginalsCount)).eql(parseInt(OriginalsCountAfterUpload)); - } -); diff --git a/frontend/tests/acceptance/photos.js b/frontend/tests/acceptance/photos.js deleted file mode 100644 index 03d97e66a..000000000 --- a/frontend/tests/acceptance/photos.js +++ /dev/null @@ -1,382 +0,0 @@ -import { Selector } from "testcafe"; -import testcafeconfig from "./testcafeconfig"; -import { ClientFunction } from "testcafe"; -import Menu from "../page-model/menu"; -import Toolbar from "../page-model/toolbar"; -import ContextMenu from "../page-model/context-menu"; -import Photo from "../page-model/photo"; -import PhotoViewer from "../page-model/photoviewer"; -import Page from "../page-model/page"; -import PhotoEdit from "../page-model/photo-edit"; - -const scroll = ClientFunction((x, y) => window.scrollTo(x, y)); -const getcurrentPosition = ClientFunction(() => window.pageYOffset); - -fixture`Test photos`.page`${testcafeconfig.url}`; - -const menu = new Menu(); -const toolbar = new Toolbar(); -const contextmenu = new ContextMenu(); -const photo = new Photo(); -const photoviewer = new PhotoViewer(); -const page = new Page(); -const photoedit = new PhotoEdit(); - -test.meta("testID", "photos-001")("Scroll to top", async (t) => { - await toolbar.setFilter("view", "Cards"); - - await t - .expect(Selector("button.is-photo-scroll-top").exists) - .notOk() - .expect(getcurrentPosition()) - .eql(0) - .expect(Selector("div.image.clickable").nth(0).visible) - .ok(); - - await scroll(0, 1400); - await scroll(0, 900); - - await t.click(Selector("button.p-scroll-top")).expect(getcurrentPosition()).eql(0); -}); - -//TODO Covered by admin role test -test.meta("testID", "photos-002")( - "Download single photo/video using clipboard and fullscreen mode", - async (t) => { - const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); - const SecondPhotoUid = await photo.getNthPhotoUid("image", 1); - const FirstVideoUid = await photo.getNthPhotoUid("video", 0); - await photoviewer.openPhotoViewer("uid", SecondPhotoUid); - - await photoviewer.checkPhotoViewerActionAvailability("download", true); - - await photoviewer.triggerPhotoViewerAction("close"); - await photo.triggerHoverAction("uid", FirstPhotoUid, "select"); - await photo.triggerHoverAction("uid", FirstVideoUid, "select"); - await contextmenu.checkContextMenuCount("2"); - - await contextmenu.checkContextMenuActionAvailability("download", true); - } -); - -test.meta("testID", "photos-003").meta({ type: "smoke" })( - "Approve photo using approve and by adding location", - async (t) => { - await menu.openPage("review"); - const FirstPhotoUid = await photo.getNthPhotoUid("all", 0); - const SecondPhotoUid = await photo.getNthPhotoUid("all", 1); - const ThirdPhotoUid = await photo.getNthPhotoUid("all", 2); - await menu.openPage("browse"); - - await photo.checkPhotoVisibility(FirstPhotoUid, false); - await photo.checkPhotoVisibility(SecondPhotoUid, false); - - await menu.openPage("review"); - await photo.triggerHoverAction("uid", FirstPhotoUid, "select"); - await contextmenu.triggerContextMenuAction("edit", ""); - await t.click(photoedit.detailsClose); - if (t.browser.platform === "mobile") { - await t.eval(() => location.reload()); - } else { - await toolbar.triggerToolbarAction("reload"); - } - - await photo.checkPhotoVisibility(FirstPhotoUid, true); - - await contextmenu.triggerContextMenuAction("edit", ""); - await t.click(photoedit.detailsApprove); - if (t.browser.platform === "mobile") { - await t.click(photoedit.detailsApply).click(photoedit.detailsClose); - } else { - await t.click(photoedit.detailsDone); - } - await photo.triggerHoverAction("uid", SecondPhotoUid, "select"); - await contextmenu.triggerContextMenuAction("edit", ""); - await t - .typeText(photoedit.latitude, "9.999", { replace: true }) - .typeText(photoedit.longitude, "9.999", { replace: true }); - if (t.browser.platform === "mobile") { - await t.click(photoedit.detailsApply).click(photoedit.detailsClose); - } else { - await t.click(photoedit.detailsDone); - } - await toolbar.setFilter("view", "Cards"); - const ApproveButtonThirdPhoto = - 'div.is-photo[data-uid="' + ThirdPhotoUid + '"] button.action-approve'; - await t.click(Selector(ApproveButtonThirdPhoto)); - if (t.browser.platform === "mobile") { - await t.eval(() => location.reload()); - } else { - await toolbar.triggerToolbarAction("reload"); - } - - await photo.checkPhotoVisibility(FirstPhotoUid, false); - await photo.checkPhotoVisibility(SecondPhotoUid, false); - await photo.checkPhotoVisibility(ThirdPhotoUid, false); - await menu.openPage("browse"); - await photo.checkPhotoVisibility(FirstPhotoUid, true); - await photo.checkPhotoVisibility(SecondPhotoUid, true); - await photo.checkPhotoVisibility(ThirdPhotoUid, true); - } -); - -test.meta("testID", "photos-004").meta({ type: "smoke" })("Like/dislike photo/video", async (t) => { - const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); - const SecondPhotoUid = await photo.getNthPhotoUid("image", 1); - const FirstVideoUid = await photo.getNthPhotoUid("video", 0); - await menu.openPage("favorites"); - - await photo.checkPhotoVisibility(FirstPhotoUid, false); - await photo.checkPhotoVisibility(SecondPhotoUid, false); - await photo.checkPhotoVisibility(FirstVideoUid, false); - - await menu.openPage("browse"); - await photo.triggerHoverAction("uid", FirstPhotoUid, "favorite"); - await photo.triggerHoverAction("uid", FirstVideoUid, "favorite"); - await photo.triggerHoverAction("uid", SecondPhotoUid, "select"); - await contextmenu.triggerContextMenuAction("edit", ""); - await photoedit.turnSwitchOn("favorite"); - await t.click(photoedit.dialogClose); - await contextmenu.clearSelection(); - - await photo.checkPhotoVisibility(FirstPhotoUid, true); - await photo.checkPhotoVisibility(FirstVideoUid, true); - await photo.checkPhotoVisibility(SecondPhotoUid, true); - - await menu.openPage("favorites"); - - await photo.checkPhotoVisibility(FirstPhotoUid, true); - await photo.checkPhotoVisibility(FirstVideoUid, true); - await photo.checkPhotoVisibility(SecondPhotoUid, true); - - await photo.triggerHoverAction("uid", SecondPhotoUid, "favorite"); - await photo.triggerHoverAction("uid", FirstVideoUid, "select"); - await contextmenu.triggerContextMenuAction("edit", ""); - await photoedit.turnSwitchOff("favorite"); - await t.click(photoedit.dialogClose); - await contextmenu.clearSelection(); - await photoviewer.openPhotoViewer("uid", FirstPhotoUid); - await photoviewer.triggerPhotoViewerAction("like"); - await photoviewer.triggerPhotoViewerAction("close"); - if (t.browser.platform === "mobile") { - await t.eval(() => location.reload()); - } else { - await toolbar.triggerToolbarAction("reload"); - } - - await photo.checkPhotoVisibility(FirstPhotoUid, false); - await photo.checkPhotoVisibility(FirstVideoUid, false); - await photo.checkPhotoVisibility(SecondPhotoUid, false); -}); - -test.meta("testID", "photos-005").meta({ type: "smoke" })("Edit photo/video", async (t) => { - await toolbar.setFilter("view", "Cards"); - const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); - await t.click(page.cardTitle.withAttribute("data-uid", FirstPhotoUid)); - - await t.expect(photoedit.latitude.visible).ok(); - - await t.click(photoedit.dialogNext); - - await t.expect(photoedit.dialogPrevious.getAttribute("disabled")).notEql("disabled"); - - await t.click(photoedit.dialogPrevious).click(photoedit.dialogClose); - await photoviewer.openPhotoViewer("uid", FirstPhotoUid); - await photoviewer.triggerPhotoViewerAction("edit"); - const FirstPhotoTitle = await photoedit.title.value; - const FirstPhotoLocalTime = await photoedit.localTime.value; - const FirstPhotoDay = await photoedit.day.value; - const FirstPhotoMonth = await photoedit.month.value; - const FirstPhotoYear = await photoedit.year.value; - const FirstPhotoTimezone = await photoedit.timezone.value; - const FirstPhotoLatitude = await photoedit.latitude.value; - const FirstPhotoLongitude = await photoedit.longitude.value; - const FirstPhotoAltitude = await photoedit.altitude.value; - const FirstPhotoCountry = await photoedit.country.value; - const FirstPhotoCamera = await photoedit.camera.innerText; - const FirstPhotoIso = await photoedit.iso.value; - const FirstPhotoExposure = await photoedit.exposure.value; - const FirstPhotoLens = await photoedit.lens.innerText; - const FirstPhotoFnumber = await photoedit.fnumber.value; - const FirstPhotoFocalLength = await photoedit.focallength.value; - const FirstPhotoSubject = await photoedit.subject.value; - const FirstPhotoArtist = await photoedit.artist.value; - const FirstPhotoCopyright = await photoedit.copyright.value; - const FirstPhotoLicense = await photoedit.license.value; - const FirstPhotoDescription = await photoedit.description.value; - const FirstPhotoKeywords = await photoedit.keywords.value; - const FirstPhotoNotes = await photoedit.notes.value; - - await t - .typeText(photoedit.title, "Not saved photo title", { replace: true }) - .click(photoedit.detailsClose) - .click(Selector("button.action-date-edit").withAttribute("data-uid", FirstPhotoUid)); - - await t.expect(photoedit.title.value).eql(FirstPhotoTitle); - - await photoedit.editPhoto( - "New Photo Title", - "Europe/Moscow", - "15", - "07", - "2019", - "04:30:30", - "-1", - "41.15333", - "20.168331", - "32", - "1/32", - "29", - "33", - "Super nice edited photo", - "Happy", - "Happy2020", - "Super nice cat license", - "Description of a nice image :)", - ", cat, love", - "Some notes" - ); - if (t.browser.platform === "mobile") { - await t.eval(() => location.reload()); - } else { - await toolbar.triggerToolbarAction("reload"); - } - await toolbar.search("uid:" + FirstPhotoUid); - - await t - .expect(page.cardTitle.withAttribute("data-uid", FirstPhotoUid).innerText) - .eql("New Photo Title"); - - await photo.triggerHoverAction("uid", FirstPhotoUid, "select"); - await contextmenu.triggerContextMenuAction("edit", ""); - - //const expectedValues = [{ FirstPhotoTitle: photoedit.title }, { "bluh bla": photoedit.day }]; - /*const expectedValues = [ - [FirstPhotoTitle, photoedit.title], - ["blah", photoedit.day], - ]; - await photoedit.checkEditFormValuesNewNew(expectedValues);*/ - - await photoedit.checkEditFormValues( - "New Photo Title", - "15", - "07", - "2019", - "04:30:30", - "Europe/Moscow", - "Albania", - "-1", - "", - "", - "", - "32", - "1/32", - "", - "29", - "33", - "Super nice edited photo", - "Happy", - "Happy2020", - "Super nice cat license", - "Description of a nice image :)", - "cat", - "Some notes" - ); - - await photoedit.undoPhotoEdit( - FirstPhotoTitle, - FirstPhotoTimezone, - FirstPhotoDay, - FirstPhotoMonth, - FirstPhotoYear, - FirstPhotoLocalTime, - FirstPhotoAltitude, - FirstPhotoLatitude, - FirstPhotoLongitude, - FirstPhotoCountry, - FirstPhotoIso, - FirstPhotoExposure, - FirstPhotoFnumber, - FirstPhotoFocalLength, - FirstPhotoSubject, - FirstPhotoArtist, - FirstPhotoCopyright, - FirstPhotoLicense, - FirstPhotoDescription, - FirstPhotoKeywords, - FirstPhotoNotes - ); - await contextmenu.checkContextMenuCount("1"); - await contextmenu.clearSelection(); -}); - -test.skip.meta("testID", "photos-006")("Navigate from card view to place", async (t) => { - await toolbar.setFilter("view", "Cards"); - await t.click(page.cardLocation.nth(0)); - - await t - .expect(Selector("#map").exists, { timeout: 15000 }) - .ok() - .expect(Selector("div.p-map-control").visible) - .ok() - .expect(Selector(".input-search input").value) - .notEql(""); -}); - -test.meta("testID", "photos-007")("Mark photos/videos as panorama/scan", async (t) => { - const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); - const FirstVideoUid = await photo.getNthPhotoUid("video", 1); - await menu.openPage("scans"); - - await photo.checkPhotoVisibility(FirstPhotoUid, false); - await photo.checkPhotoVisibility(FirstVideoUid, false); - - await menu.openPage("panoramas"); - - await photo.checkPhotoVisibility(FirstPhotoUid, false); - await photo.checkPhotoVisibility(FirstVideoUid, false); - - await menu.openPage("browse"); - await photo.triggerHoverAction("uid", FirstPhotoUid, "select"); - await photo.triggerHoverAction("uid", FirstVideoUid, "select"); - await contextmenu.triggerContextMenuAction("edit", ""); - await photoedit.turnSwitchOn("scan"); - await photoedit.turnSwitchOn("panorama"); - await t.click(photoedit.dialogNext); - await photoedit.turnSwitchOn("scan"); - await photoedit.turnSwitchOn("panorama"); - await t.click(photoedit.dialogClose); - await contextmenu.clearSelection(); - - await photo.checkPhotoVisibility(FirstPhotoUid, true); - await photo.checkPhotoVisibility(FirstVideoUid, true); - - await menu.openPage("scans"); - - await photo.checkPhotoVisibility(FirstPhotoUid, true); - await photo.checkPhotoVisibility(FirstVideoUid, false); - - await menu.openPage("panoramas"); - - await photo.checkPhotoVisibility(FirstPhotoUid, true); - await photo.checkPhotoVisibility(FirstVideoUid, true); - - await photo.triggerHoverAction("uid", FirstPhotoUid, "select"); - await photo.triggerHoverAction("uid", FirstVideoUid, "select"); - await contextmenu.triggerContextMenuAction("edit", ""); - await photoedit.turnSwitchOff("scan"); - await photoedit.turnSwitchOff("panorama"); - await t.click(photoedit.dialogNext); - await photoedit.turnSwitchOff("scan"); - await photoedit.turnSwitchOff("panorama"); - await t.click(photoedit.dialogClose); - await contextmenu.clearSelection(); - if (t.browser.platform === "mobile") { - await t.eval(() => location.reload()); - } else { - await toolbar.triggerToolbarAction("reload"); - } - - await photo.checkPhotoVisibility(FirstPhotoUid, false); - await photo.checkPhotoVisibility(FirstVideoUid, false); -}); diff --git a/frontend/tests/acceptance/settings/about.js b/frontend/tests/acceptance/settings/about.js deleted file mode 100644 index 1f7be3091..000000000 --- a/frontend/tests/acceptance/settings/about.js +++ /dev/null @@ -1,25 +0,0 @@ -import { Selector } from "testcafe"; -import testcafeconfig from "../testcafeconfig"; -import Menu from "../../page-model/menu"; - -fixture`Test about`.page`${testcafeconfig.url}`; - -const menu = new Menu(); - -test.meta("testID", "about-001")("About page is displayed with all links", async (t) => { - await menu.openPage("about"); - await t - .expect(Selector('a[href="https://photoprism.app/"]').visible) - .ok() - .expect(Selector('a[href="https://photoprism.app/membership"]').visible) - .ok(); -}); - -test.meta("testID", "about-002")("License page is displayed with all links", async (t) => { - await menu.openPage("license"); - await t - .expect(Selector("h3").withText("GNU AFFERO GENERAL PUBLIC LICENSE").visible) - .ok() - .expect(Selector('a[href="https://www.gnu.org/licenses/agpl-3.0.en.html"]').visible) - .ok(); -}); diff --git a/frontend/tests/acceptance/stacks.js b/frontend/tests/acceptance/stacks.js deleted file mode 100644 index cefb289f2..000000000 --- a/frontend/tests/acceptance/stacks.js +++ /dev/null @@ -1,124 +0,0 @@ -import { Selector } from "testcafe"; -import testcafeconfig from "./testcafeconfig"; -import Menu from "../page-model/menu"; -import Toolbar from "../page-model/toolbar"; -import Photo from "../page-model/photo"; -import PhotoViewer from "../page-model/photoviewer"; -import Page from "../page-model/page"; -import PhotoEdit from "../page-model/photo-edit"; -import Library from "../page-model/library"; - -fixture`Test stacks`.page`${testcafeconfig.url}`; - -const menu = new Menu(); -const toolbar = new Toolbar(); -const photo = new Photo(); -const photoviewer = new PhotoViewer(); -const page = new Page(); -const photoedit = new PhotoEdit(); -const library = new Library(); - -test.meta("testID", "stacks-001").meta({ type: "smoke" })( - "View all files of a stack", - async (t) => { - await toolbar.search("ski"); - const SequentialPhotoUid = await photo.getNthPhotoUid("all", 0); - await photo.checkHoverActionAvailability("uid", SequentialPhotoUid, "open", true); - if (t.browser.platform === "desktop") { - console.log(t.browser.platform); - await photo.triggerHoverAction("nth", 0, "open"); - await photoviewer.triggerPhotoViewerAction("next"); - await photoviewer.triggerPhotoViewerAction("previous"); - await photoviewer.triggerPhotoViewerAction("close"); - } - await photo.checkHoverActionAvailability("uid", SequentialPhotoUid, "open", true); - } -); - -test.meta("testID", "stacks-002").meta({ type: "smoke" })("Change primary file", async (t) => { - await toolbar.search("ski"); - const SequentialPhotoUid = await photo.getNthPhotoUid("all", 0); - await toolbar.setFilter("view", "Cards"); - await t - .click(page.cardTitle.withAttribute("data-uid", SequentialPhotoUid)) - .click(photoedit.filesTab); - const FirstFileName = await Selector("div.caption").nth(0).innerText; - - await t.expect(FirstFileName).contains("photos8_1_ski.jpg"); - - await t - .click(photoedit.toggleExpandFile.nth(1)) - .click(photoedit.makeFilePrimary) - .click(photoedit.dialogClose) - .click(page.cardTitle.withAttribute("data-uid", SequentialPhotoUid)); - const FirstFileNameAfterChange = await Selector("div.caption").nth(0).innerText; - - await t - .expect(FirstFileNameAfterChange) - .notContains("photos8_1_ski.jpg") - .expect(FirstFileNameAfterChange) - .contains("photos8_2_ski.jpg"); -}); - -test.meta("testID", "stacks-003").meta({ type: "smoke" })("Ungroup files", async (t) => { - await toolbar.search("group"); - await toolbar.setFilter("view", "Cards"); - const PhotoCount = await photo.getPhotoCount("all"); - const SequentialPhotoUid = await photo.getNthPhotoUid("all", 0); - - await t.expect(PhotoCount).eql(1); - - await menu.openPage("stacks"); - await photo.checkHoverActionAvailability("uid", SequentialPhotoUid, "open", true); - await toolbar.setFilter("view", "Cards"); - await t - .click(page.cardTitle.withAttribute("data-uid", SequentialPhotoUid)) - .click(photoedit.filesTab) - .click(photoedit.toggleExpandFile.nth(0)) - .click(photoedit.toggleExpandFile.nth(1)) - .click(photoedit.unstackFile) - .wait(12000) - .click(photoedit.dialogClose); - await menu.openPage("browse"); - await toolbar.search("group"); - if (t.browser.platform === "mobile") { - await t.eval(() => location.reload()); - } else { - await toolbar.triggerToolbarAction("reload"); - } - const PhotoCountAfterUngroup = await photo.getPhotoCount("all"); - - await t.expect(PhotoCountAfterUngroup).eql(2); - await photo.checkHoverActionAvailability("uid", SequentialPhotoUid, "open", false); -}); - -test.meta("testID", "stacks-004")("Delete non primary file", async (t) => { - await menu.openPage("library"); - await t - .click(library.importTab) - .click(library.openImportFolderSelect, { timeout: 5000 }) - .click(page.selectOption.withText("/pizza")) - .click(library.import) - .wait(10000); - await menu.openPage("browse"); - await toolbar.search("pizza"); - await toolbar.setFilter("view", "Cards"); - const PhotoCount = await photo.getPhotoCount("all"); - const PhotoUid = await photo.getNthPhotoUid("all", 0); - - await t.expect(PhotoCount).eql(1); - - await t.click(page.cardTitle.withAttribute("data-uid", PhotoUid)).click(photoedit.filesTab); - const FileCount = await photoedit.getFileCount(); - - await t.expect(FileCount).eql(2); - - await t - .click(photoedit.toggleExpandFile.nth(1)) - .click(Selector(photoedit.deleteFile)) - .click(Selector(".action-confirm")) - .wait(10000); - const FileCountAfterDeletion = await photoedit.getFileCount(); - - await t.expect(FileCountAfterDeletion).eql(1); -}); diff --git a/frontend/tests/acceptance/states.js b/frontend/tests/acceptance/states.js deleted file mode 100644 index 5f7b42b7f..000000000 --- a/frontend/tests/acceptance/states.js +++ /dev/null @@ -1,147 +0,0 @@ -import { Selector } from "testcafe"; -import testcafeconfig from "./testcafeconfig"; -import Menu from "../page-model/menu"; -import Album from "../page-model/album"; -import Toolbar from "../page-model/toolbar"; -import ContextMenu from "../page-model/context-menu"; -import Photo from "../page-model/photo"; -import Page from "../page-model/page"; -import AlbumDialog from "../page-model/dialog-album"; - -fixture`Test states`.page`${testcafeconfig.url}`; - -const menu = new Menu(); -const album = new Album(); -const toolbar = new Toolbar(); -const contextmenu = new ContextMenu(); -const photo = new Photo(); -const page = new Page(); -const albumdialog = new AlbumDialog(); - -test.meta("testID", "states-001")("Update state details", async (t) => { - await menu.openPage("states"); - await toolbar.search("Canada"); - const AlbumUid = await album.getNthAlbumUid("all", 0); - - await t.expect(page.cardTitle.nth(0).innerText).contains("British Columbia"); - - await t.click(page.cardTitle.nth(0)); - - await t - .expect(albumdialog.title.value) - .eql("British Columbia") - .expect(albumdialog.location.value) - .eql("Canada") - .expect(albumdialog.description.value) - .eql("") - .expect(albumdialog.category.value) - .eql(""); - - await t - .typeText(albumdialog.title, "Wonderland", { replace: true }) - .typeText(albumdialog.location, "Earth", { replace: true }) - .typeText(albumdialog.description, "We love earth") - .typeText(albumdialog.category, "Mountains") - .pressKey("enter") - .click(albumdialog.dialogSave); - - await t - .expect(page.cardTitle.nth(0).innerText) - .contains("Wonderland") - .expect(page.cardDescription.nth(0).innerText) - .contains("We love earth") - .expect(Selector("div.caption").nth(1).innerText) - .contains("Mountains") - .expect(Selector("div.caption").nth(2).innerText) - .contains("Earth"); - - await album.openNthAlbum(0); - - await t.expect(toolbar.toolbarSecondTitle.innerText).contains("Wonderland"); - await t.expect(toolbar.toolbarDescription.innerText).contains("We love earth"); - - await menu.openPage("states"); - if (t.browser.platform === "mobile") { - await toolbar.search("category:Mountains"); - } else { - await toolbar.setFilter("category", "Mountains"); - } - - await t.expect(page.cardTitle.nth(0).innerText).contains("Wonderland"); - - await album.openAlbumWithUid(AlbumUid); - await toolbar.triggerToolbarAction("edit"); - - await t - .expect(albumdialog.description.value) - .eql("We love earth") - .expect(albumdialog.category.value) - .eql("Mountains") - .expect(albumdialog.location.value) - .eql("Earth"); - - await t - .typeText(albumdialog.title, "British Columbia / Canada", { replace: true }) - .click(albumdialog.category) - .pressKey("ctrl+a delete") - .pressKey("enter") - .click(albumdialog.description) - .pressKey("ctrl+a delete") - .pressKey("enter") - .typeText(albumdialog.location, "Canada", { replace: true }) - .click(albumdialog.dialogSave); - await menu.openPage("states"); - await toolbar.search("Canada"); - - await t - .expect(page.cardTitle.nth(0).innerText) - .contains("British Columbia / Canada") - .expect(page.cardDescription.innerText) - .notContains("We love earth") - .expect(Selector("div.caption").nth(0).innerText) - .notContains("Earth"); -}); - -test.meta("testID", "states-002")("Create, Edit, delete sharing link for state", async (t) => { - await page.testCreateEditDeleteSharingLink("states"); -}); - -test.meta("testID", "states-003")("Create/delete album-clone from state", async (t) => { - await menu.openPage("albums"); - const AlbumCount = await album.getAlbumCount("all"); - await menu.openPage("states"); - await toolbar.search("Canada"); - const FirstStateUid = await album.getNthAlbumUid("all", 0); - await album.openAlbumWithUid(FirstStateUid); - const PhotoCountInState = await photo.getPhotoCount("all"); - const FirstPhotoUid = await photo.getNthPhotoUid("image", 0); - const SecondPhotoUid = await photo.getNthPhotoUid("image", 1); - await menu.openPage("states"); - await album.selectAlbumFromUID(FirstStateUid); - await contextmenu.triggerContextMenuAction("clone", "NotYetExistingAlbumForState"); - await menu.openPage("albums"); - const AlbumCountAfterCreation = await album.getAlbumCount("all"); - - await t.expect(AlbumCountAfterCreation).eql(AlbumCount + 1); - - await toolbar.search("NotYetExistingAlbumForState"); - const AlbumUid = await album.getNthAlbumUid("all", 0); - await album.openAlbumWithUid(AlbumUid); - const PhotoCountInAlbum = await photo.getPhotoCount("all"); - - await t.expect(PhotoCountInAlbum).eql(PhotoCountInState); - - await photo.checkPhotoVisibility(FirstPhotoUid, true); - await photo.checkPhotoVisibility(SecondPhotoUid, true); - await menu.openPage("albums"); - await album.selectAlbumFromUID(AlbumUid); - await contextmenu.triggerContextMenuAction("delete", ""); - const AlbumCountAfterDelete = await album.getAlbumCount("all"); - - await t.expect(AlbumCountAfterDelete).eql(AlbumCount); - - await menu.openPage("states"); - await album.openAlbumWithUid(FirstStateUid); - await photo.checkPhotoVisibility(FirstPhotoUid, true); - await photo.checkPhotoVisibility(SecondPhotoUid, true); -});