Files
photoprism/frontend/tests/acceptance/acceptance-public/albums.js
2025-11-28 10:32:00 +01:00

349 lines
14 KiB
JavaScript

import { Selector } from "testcafe";
import testcafeconfig from "../../testcafeconfig.json";
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";
import PhotoEdit from "../page-model/photo-edit";
import Notifies from "../page-model/notifications";
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();
const photoedit = new PhotoEdit();
const notifies = new Notifies();
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 page.clickCardTitleOfUID(FirstPhotoUid);
await t
.click(photoedit.infoTab)
.expect(Selector("td").withText("Albums").visible)
.notOk()
.expect(Selector("td").withText("NotYetExistingAlbum").visible)
.notOk()
.click(photoedit.dialogClose);
await photo.selectPhotoFromUID(SecondPhotoUid);
await photo.selectPhotoFromUID(FirstPhotoUid);
await contextmenu.triggerContextMenuAction("album", "NotYetExistingAlbum");
await page.clickCardTitleOfUID(FirstPhotoUid);
await t
.click(photoedit.infoTab)
.expect(Selector("td").withText("Albums").visible)
.ok()
.expect(Selector("td").withText("NotYetExistingAlbum").visible)
.ok()
.click(photoedit.dialogClose);
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.openAlbumWithUid(AlbumUid);
await toolbar.triggerToolbarAction("delete");
await t.navigateTo("/library/albums");
await notifies.waitForAlbumsToLoad(7000);
const AlbumCountAfterDelete = await album.getAlbumCount("all");
await t.expect(AlbumCountAfterDelete).eql(AlbumCount);
await menu.openPage("browse");
await toolbar.search("photo:true");
await page.clickCardTitleOfUID(FirstPhotoUid);
await t
.click(photoedit.infoTab)
.expect(Selector("td").withText("Albums").visible)
.notOk()
.expect(Selector("td").withText("NotYetExistingAlbum").visible)
.notOk()
.click(photoedit.dialogClose);
});
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");
await t.click(albumdialog.category).click(albumdialog.category).pressKey("ctrl+a delete").click(Selector("form.form-album-edit i.mdi-bookmark"));
await t.expect(albumdialog.category.value).eql("");
await t.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 multiple albums", async (t) => {
// Get initial counts for both Holiday and Christmas albums
await menu.openPage("albums");
await notifies.waitForPhotosToLoad(2000);
await toolbar.search("Holiday");
const HolidayAlbumUid = await album.getNthAlbumUid("all", 0);
await album.openAlbumWithUid(HolidayAlbumUid);
const HolidayPhotoCount = await photo.getPhotoCount("all");
await menu.openPage("albums");
await toolbar.search("Christmas");
const ChristmasAlbumUid = await album.getNthAlbumUid("all", 0);
await album.openAlbumWithUid(ChristmasAlbumUid);
const ChristmasPhotoCount = await photo.getPhotoCount("all");
// Select photos to add to albums
await menu.openPage("browse");
await toolbar.search("photo:true");
const FirstPhotoUid = await photo.getNthPhotoUid("image", 0);
const SecondPhotoUid = await photo.getNthPhotoUid("image", 1);
// Verify photos are not in any albums initially
await page.clickCardTitleOfUID(FirstPhotoUid);
await t
.click(photoedit.infoTab)
.expect(Selector("td").withText("Albums").visible)
.notOk()
.expect(Selector("td").withText("Holiday").visible)
.notOk()
.expect(Selector("td").withText("Christmas").visible)
.notOk()
.click(photoedit.dialogClose);
// Select both photos and add to multiple albums simultaneously
await photo.selectPhotoFromUID(SecondPhotoUid);
await photoviewer.openPhotoViewer("uid", FirstPhotoUid);
await photoviewer.triggerPhotoViewerAction("select-toggle");
await photoviewer.triggerPhotoViewerAction("close-button");
await contextmenu.triggerContextMenuAction("album", ["Holiday", "Christmas", "Food"]);
// Verify photos were added to Holiday album
await menu.openPage("albums");
await album.openAlbumWithUid(HolidayAlbumUid);
const HolidayPhotoCountAfterAdd = await photo.getPhotoCount("all");
await t.expect(HolidayPhotoCountAfterAdd).eql(HolidayPhotoCount + 2);
// Verify photos were added to Christmas album
await menu.openPage("albums");
await album.openAlbumWithUid(ChristmasAlbumUid);
const ChristmasPhotoCountAfterAdd = await photo.getPhotoCount("all");
await t.expect(ChristmasPhotoCountAfterAdd).eql(ChristmasPhotoCount + 2);
// Verify photo info shows all albums
await menu.openPage("browse");
await toolbar.search("photo:true");
await page.clickCardTitleOfUID(FirstPhotoUid);
await t
.click(photoedit.infoTab)
.expect(Selector("td").withText("Albums").visible)
.ok()
.expect(Selector("td").withText("Holiday").visible)
.ok()
.expect(Selector("td").withText("Food").visible)
.ok()
.expect(Selector("td").withText("Christmas").visible)
.ok()
.click(photoedit.dialogClose);
// Remove photos from Holiday album and verify count
await menu.openPage("albums");
await album.openAlbumWithUid(HolidayAlbumUid);
await photo.selectPhotoFromUID(FirstPhotoUid);
await photo.selectPhotoFromUID(SecondPhotoUid);
await contextmenu.triggerContextMenuAction("remove", "");
const HolidayPhotoCountAfterRemove = await photo.getPhotoCount("all");
await t.expect(HolidayPhotoCountAfterRemove).eql(HolidayPhotoCountAfterAdd - 2);
// Verify photos are still in Christmas album
await menu.openPage("albums");
await album.openAlbumWithUid(ChristmasAlbumUid);
const ChristmasPhotoCountAfterHolidayRemove = await photo.getPhotoCount("all");
await t.expect(ChristmasPhotoCountAfterHolidayRemove).eql(ChristmasPhotoCountAfterAdd);
// Verify photo info shows only Christmas album now
await menu.openPage("browse");
await toolbar.search("photo:true");
await page.clickCardTitleOfUID(FirstPhotoUid);
await t
.click(photoedit.infoTab)
.expect(Selector("td").withText("Albums").visible)
.ok()
.expect(Selector("td").withText("Holiday").visible)
.notOk()
.expect(Selector("td").withText("Christmas").visible)
.ok()
.click(photoedit.dialogClose);
// Remove photos from Christmas album to clean up
await menu.openPage("albums");
await album.openAlbumWithUid(ChristmasAlbumUid);
await photo.selectPhotoFromUID(FirstPhotoUid);
await photo.selectPhotoFromUID(SecondPhotoUid);
await contextmenu.triggerContextMenuAction("remove", "");
const ChristmasPhotoCountAfterRemove = await photo.getPhotoCount("all");
await t.expect(ChristmasPhotoCountAfterRemove).eql(ChristmasPhotoCount);
// Delete Food album
await menu.openPage("albums");
await toolbar.search("Food");
const FoodUid = await album.getNthAlbumUid("all", 0);
await album.selectAlbumFromUID(FoodUid);
await contextmenu.triggerContextMenuAction("delete", "");
// Final verification that photos are not in any albums
await menu.openPage("browse");
await toolbar.search("photo:true");
await page.clickCardTitleOfUID(FirstPhotoUid);
await t
.click(photoedit.infoTab)
.expect(Selector("td").withText("Albums").visible)
.notOk()
.expect(Selector("td").withText("Food").visible)
.notOk()
.expect(Selector("td").withText("Holiday").visible)
.notOk()
.expect(Selector("td").withText("Christmas").visible)
.notOk()
.click(photoedit.dialogClose);
});
test.meta("testID", "albums-004-duplicate").meta({ type: "short", mode: "public" })(
"Common: Album duplication when selecting from dropdown then typing same name",
async (t) => {
await menu.openPage("browse");
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"));
await t.click(Selector(".input-albums input"));
const holidayOption = Selector("div").withText("Holiday").parent('div[role="option"]');
if (await holidayOption.visible) {
await t.click(holidayOption);
const afterDropdown = await Selector("span.v-chip").withText("Holiday").count;
await t.expect(afterDropdown).eql(1, "Should have 1 chip after dropdown selection");
await t.click(Selector(".input-albums input"));
await t.typeText(Selector(".input-albums input"), "Holiday", { replace: true }).pressKey("enter");
const afterTyping = await Selector("span.v-chip").withText("Holiday").count;
await t.expect(afterTyping).eql(1, "Should still have only 1 chip after typing duplicate");
}
await t.click(Selector(".action-cancel"));
}
);
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 menu.openPage("browse");
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-albums input"));
await t.expect(page.selectOption.withText("Holiday").visible).ok().expect(page.selectOption.withText("Christmas").visible).ok();
await t.typeText(Selector(".input-albums 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");
});
test.meta("testID", "albums-008").meta({ type: "short", mode: "public" })("Common: Verify album sort options", async (t) => {
await menu.openPage("albums");
await album.checkSortOptions("album");
});
test.meta("testID", "albums-009").meta({ type: "short", mode: "public" })("Common: Set album cover from Albums Page", async (t) => {
await page.testSetAlbumCover("albums");
});