Files
immich-folio/e2e/proofing.spec.ts

96 lines
3.7 KiB
TypeScript
Raw Normal View History

import { test, expect, type Page } from '@playwright/test';
/**
* Client proofing + download e2e.
*
* Two independent capabilities, two albums:
*
* - Proofing (hearts, the selection bar, the send-off modal) is on by default
* for every album, so it is tested against any published album.
* - Downloading (the "Download album" header link and the "Download selected"
* modal action) only exists on an album that opted in with `download: true`
* in gallery.yaml, so those tests run against a separate album and skip
* cleanly when it is not configured.
*
* Override the URLs to match a real deployment:
* E2E_ALBUM_URL an album with photos (proofing tests)
* E2E_DOWNLOAD_ALBUM_URL an album with `download: true`
*/
const ALBUM_URL = process.env.E2E_ALBUM_URL || '/deutschland/kloster-chorin';
const DOWNLOAD_ALBUM_URL = process.env.E2E_DOWNLOAD_ALBUM_URL || ALBUM_URL;
const stickyBar = (page: Page) => page.locator('.proofing-sticky-bar');
const modalCard = (page: Page) => page.locator('.proofing-modal-card');
/** Favourite the first photo and open the send-off modal via the sticky bar. */
async function favouriteAndOpenModal(page: Page) {
const fav = page.locator('.photo-grid__fav-btn').first();
await fav.scrollIntoViewIfNeeded();
await fav.click();
await expect(stickyBar(page)).toBeVisible();
// Second button in the bar is "Share & Export"; the first is the filter.
await stickyBar(page).locator('button').nth(1).click();
await expect(modalCard(page)).toBeVisible();
}
test.describe('Proofing', () => {
test('favouriting a photo surfaces the selection bar', async ({ page }) => {
await page.goto(ALBUM_URL);
const fav = page.locator('.photo-grid__fav-btn').first();
test.skip((await fav.count()) === 0, 'proofing disabled for this album');
await fav.click();
await expect(stickyBar(page)).toBeVisible();
});
test('the send-off modal opens with a selection and clears again', async ({ page }) => {
await page.goto(ALBUM_URL);
const fav = page.locator('.photo-grid__fav-btn').first();
test.skip((await fav.count()) === 0, 'proofing disabled for this album');
await favouriteAndOpenModal(page);
await expect(modalCard(page).locator('h3')).toBeVisible();
// Clear is guarded by a native confirm(); accept it.
page.once('dialog', (dialog) => dialog.accept());
await modalCard(page)
.getByRole('button', { name: /clear selection|auswahl löschen/i })
.click();
await expect(modalCard(page)).toHaveCount(0);
await expect(stickyBar(page)).toHaveCount(0);
});
});
test.describe('Downloads', () => {
test('the header offers a whole-album download', async ({ page }) => {
await page.goto(DOWNLOAD_ALBUM_URL);
const link = page.locator('.album-header__download');
test.skip((await link.count()) === 0, 'album does not opt into downloads');
const [download] = await Promise.all([page.waitForEvent('download'), link.click()]);
expect(download.suggestedFilename()).toMatch(/\.zip$/i);
});
test('the modal downloads just the selected photos', async ({ page }) => {
await page.goto(DOWNLOAD_ALBUM_URL);
const fav = page.locator('.photo-grid__fav-btn').first();
test.skip((await fav.count()) === 0, 'proofing disabled for this album');
await favouriteAndOpenModal(page);
const downloadButton = modalCard(page).getByRole('button', {
name: /download selected|auswahl herunterladen/i,
});
test.skip((await downloadButton.count()) === 0, 'album does not opt into downloads');
const [download] = await Promise.all([page.waitForEvent('download'), downloadButton.click()]);
expect(download.suggestedFilename()).toMatch(/\.zip$/i);
});
});