Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b5a03c7eea |
@@ -0,0 +1,13 @@
|
||||
// A job's end toast follows the job, which has no time limit: under load it outlasts the 5 s expect default (#533, as
|
||||
// #520). Do `action`, whose POST to `url` answers with the job it started, then wait for that job's event stream to end.
|
||||
export const APPLY_URL = '/prompt_manager/maintenance/apply';
|
||||
export const RETURN_URL = '/prompt_manager/images/removed/return';
|
||||
|
||||
export async function startAndAwaitJob(page, action, url = APPLY_URL) {
|
||||
const applied = page.waitForResponse(response => response.url().endsWith(url));
|
||||
await action();
|
||||
const { job } = await (await applied).json();
|
||||
const events = await page.request.get(`/prompt_manager/jobs/${job.id}/events`);
|
||||
if (!events.ok()) throw new Error(`Job ${job.id} events answered ${events.status()}`);
|
||||
return job;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { startCoverage, saveCoverage } from '../../tools/vendor/browser-coverage.mjs';
|
||||
import { test, expect } from './fixtures.mjs';
|
||||
import { seedConceptAt, openProduction } from './concept-inventory.mjs';
|
||||
import { startAndAwaitJob } from './job-end.mjs';
|
||||
|
||||
// #480 (D159): Images › Delete…: the review asks every time (nothing preselected), "Remove from the library only"
|
||||
// hides the file and keeps it on disk, "Also move the files to the trash" moves it (the server's fake trash here).
|
||||
@@ -62,7 +63,7 @@ for (const mode of ['library', 'trash']) {
|
||||
const { dialog, primary } = await deleteChecked(page, mode);
|
||||
await expect(dialog.locator('dt', { hasText: 'Media on disk' })).toBeVisible();
|
||||
await expect(primary).toHaveText(mode === 'trash' ? 'Move 1 image to the trash' : 'Remove 1 image from the library');
|
||||
await primary.click();
|
||||
await startAndAwaitJob(page, () => primary.click());
|
||||
await expect(toast(page)).toContainText(mode === 'trash' ? 'Moved 1 image to the trash.' : 'Removed 1 image from the library.');
|
||||
await expect(page.locator(`${CARDS}[data-image-key="${key}"]`)).toHaveCount(0);
|
||||
await expect(page.locator(CARDS)).toHaveCount(before - 1);
|
||||
@@ -81,11 +82,25 @@ test('a finished delete re-reads the sidebar Images count', async ({ page }) =>
|
||||
const before = Number((await badge.textContent()).replace(/,/g, ''));
|
||||
await check(page, 0);
|
||||
const { primary } = await deleteChecked(page, 'library');
|
||||
await primary.click();
|
||||
await startAndAwaitJob(page, () => primary.click());
|
||||
await expect(toast(page)).toContainText('Removed 1 image from the library.');
|
||||
await expect(badge).toHaveText((before - 1).toLocaleString('en-US'));
|
||||
});
|
||||
|
||||
// #533: the toast says "started" for as long as the job's end has not reached the page, then says how it ended.
|
||||
test('a slow job keeps its started toast until the end arrives', async ({ page }) => {
|
||||
await openImages(page);
|
||||
await check(page, 0);
|
||||
let release;
|
||||
const held = new Promise(resolve => { release = resolve; });
|
||||
await page.route('**/prompt_manager/jobs/*/events', async route => { await held; await route.continue(); });
|
||||
const { primary } = await deleteChecked(page, 'library');
|
||||
await primary.click();
|
||||
await expect(toast(page)).toHaveText('Delete images (remove from the library) started.');
|
||||
release();
|
||||
await expect(toast(page)).toContainText('Removed 1 image from the library.');
|
||||
});
|
||||
|
||||
test('Cancel changes nothing', async ({ page }) => {
|
||||
const before = await openImages(page);
|
||||
await check(page, 0);
|
||||
@@ -175,7 +190,7 @@ test('a chosen mode starts exactly one delete, with that mode, however often it
|
||||
const applies = [];
|
||||
page.on('request', request => { if (request.url().includes('/maintenance/apply')) applies.push(request.postDataJSON()); });
|
||||
const { primary } = await deleteChecked(page, 'library');
|
||||
await primary.dblclick();
|
||||
await startAndAwaitJob(page, () => primary.dblclick());
|
||||
await expect(toast(page)).toContainText('Removed 1 image from the library.');
|
||||
await expect(page.locator(CARDS)).toHaveCount(before - 1);
|
||||
expect(applies.length).toBe(1);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { startCoverage, saveCoverage } from '../../tools/vendor/browser-coverage.mjs';
|
||||
import { test, expect } from './fixtures.mjs';
|
||||
import { seedConceptAt, openProduction } from './concept-inventory.mjs';
|
||||
import { RETURN_URL, startAndAwaitJob } from './job-end.mjs';
|
||||
|
||||
// #498 (D162): Images › Show removed images (N) lists the files "Remove from the library only" hid; Return to library
|
||||
// (bar or inspector) clears their marks and scans them again. Nothing is deleted or moved.
|
||||
@@ -46,7 +47,7 @@ async function removeFromLibrary(page, count) {
|
||||
await bar(page).getByRole('button', { name: 'Delete…', exact: true }).click();
|
||||
const dialog = page.getByRole('dialog', { name: /^Delete \d+ images?$/ });
|
||||
await dialog.getByRole('radio', { name: /^Remove from the library only/ }).check();
|
||||
await dialog.locator('.dialog-actions button.danger').click();
|
||||
await startAndAwaitJob(page, () => dialog.locator('.dialog-actions button.danger').click());
|
||||
await expect(toast(page)).toContainText(`Removed ${count} image${count === 1 ? '' : 's'} from the library.`);
|
||||
for (const key of keys) await expect(page.locator(`${CARDS}[data-image-key="${key}"]`)).toHaveCount(0);
|
||||
return keys;
|
||||
@@ -78,7 +79,7 @@ test('Show removed images lists the removed files; Return to library brings them
|
||||
await check(page, 1);
|
||||
const actions = bar(page).locator('button');
|
||||
await expect(actions).toHaveText(['Return to library', 'Clear']);
|
||||
await bar(page).getByRole('button', { name: 'Return to library' }).click();
|
||||
await startAndAwaitJob(page, () => bar(page).getByRole('button', { name: 'Return to library' }).click(), RETURN_URL);
|
||||
await expect(toast(page)).toContainText('Returned 2 images to the library');
|
||||
await expect(toast(page)).toContainText('Tags, categories, collections and favorites do not come back.');
|
||||
// The view emptied: it turns off and Images lists every file again.
|
||||
@@ -98,7 +99,7 @@ test('Return to library from the inspector', async ({ page }) => {
|
||||
await expect(panel.getByRole('button', { name: 'Return to library' })).toBeVisible();
|
||||
await expect(panel.getByRole('button', { name: 'Delete…' })).toHaveCount(0);
|
||||
await expect(panel.locator('button[data-collections]')).toHaveCount(0);
|
||||
await panel.getByRole('button', { name: 'Return to library' }).click();
|
||||
await startAndAwaitJob(page, () => panel.getByRole('button', { name: 'Return to library' }).click(), RETURN_URL);
|
||||
await expect(toast(page)).toContainText('Returned 1 image to the library');
|
||||
await expect(toggle(page)).toHaveCount(0);
|
||||
await expect(page.locator(`${CARDS}[data-image-key="${key}"]`)).toHaveCount(1);
|
||||
@@ -112,7 +113,7 @@ test('the sidebar Images count follows a remove and a return', async ({ page })
|
||||
await expect(imagesBadge(page)).toHaveText((start - 1).toLocaleString('en-US'));
|
||||
await toggle(page).click();
|
||||
await check(page, 0);
|
||||
await bar(page).getByRole('button', { name: 'Return to library' }).click();
|
||||
await startAndAwaitJob(page, () => bar(page).getByRole('button', { name: 'Return to library' }).click(), RETURN_URL);
|
||||
await expect(toast(page)).toContainText('Returned 1 image to the library');
|
||||
await expect(imagesBadge(page)).toHaveText(start.toLocaleString('en-US'));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user