Files
ComfyAssets-ComfyUI_PromptM…/tests/comfyui/workspace.spec.mjs
T
Vito Sansevero 831368a600 feat(images): concept image cards; image opens the viewer
Cards are the concept media card: .media-art > button.image-open with the
image or video, and .media-info with the D10 title (linked title only when
the link is confirmed, else the filename; title attribute = path), the D11
subtitle "W x H · EXT · Seed N" (seed shown as the listing's string) and an
Inspect info button. The byte size and the Preview button are gone.

Activating the image (click, Enter, Space) opens the viewer and focus
returns to it on Escape; Info selects the image into the panel (D19).
Arrow, Home and End navigation, bounded rendering and scroll restoration
are kept.

Columns and gap now come from the concept grid's computed style
(gridMetrics) instead of a production breakpoint table, so the concept
breakpoints apply; a 120px minimum card bounds extreme zoom (D3, D31).
images.css card rules are retired into marked overlay rules. The scope
chip reads "All output folders" when no folder is chosen (D14).
2026-10-20 03:54:30 -07:00

57 lines
3.5 KiB
JavaScript

import { test, expect } from '../../tools/vendor/node_modules/@playwright/test/index.mjs';
import { installHostHooks } from './host-fixture.mjs';
installHostHooks(test);
test('workspace serves real library data beside either ComfyUI renderer', async ({ page, context, request }, testInfo) => {
const saved = await request.post('/prompt_manager/save', { data: {
text: `Workspace host smoke ${testInfo.project.name}`, tags: ['workspace-host'],
} });
expect(saved.ok()).toBe(true);
const stats = (await (await request.get('/prompt_manager/stats')).json()).stats;
const workspace = await context.newPage();
const errors = [];
workspace.on('pageerror', error => errors.push(error.message));
try {
await workspace.goto('/prompt_manager/workspace#/overview');
await expect(workspace.locator('#workspace-main h1')).toHaveText('Overview');
await expect(workspace.locator('dt').filter({ hasText: /^Prompts$/ }).locator('+ dd'))
.toHaveText(stats.total_prompts.toLocaleString());
await workspace.getByRole('combobox', { name: 'Theme' }).selectOption('light');
await expect(workspace.locator('body')).toHaveAttribute('data-ca-theme', 'light');
const imageResponse = workspace.waitForResponse(response => {
const url = new URL(response.url());
return url.pathname === '/prompt_manager/images/output' && url.searchParams.get('mode') === 'workspace';
});
await workspace.getByRole('navigation', { name: 'Workspace', exact: true })
.getByRole('link', { name: /^Images(?:\s*[\d,]+)?$/ }).click();
await expect(workspace.locator('#workspace-main h1')).toHaveText('Images');
const images = await imageResponse;
expect(images.ok()).toBe(true);
const collection = await images.json();
expect(collection.success).toBe(true);
await expect(workspace.getByRole('list', { name: 'Image collection', exact: true })).toBeAttached();
if (collection.images.length) {
await expect(workspace.locator('article[data-image-key]').first()).toBeVisible();
} else {
await expect(workspace.getByText('No matching images · 0 images', { exact: true })).toBeVisible();
await expect(workspace.locator('.gallery-body > .empty')).toHaveText('No matching images. Try another search or category.');
}
// D29: Images no longer links the legacy gallery; Overview's "Open existing image gallery" card does.
await expect(workspace.locator('#workspace-main a[href="/prompt_manager/gallery"]')).toHaveCount(0);
await workspace.evaluate(() => { location.hash = '/overview'; });
const gallery = workspace.locator('#workspace-main').getByRole('link', { name: 'Open existing image gallery', exact: true });
await expect(gallery).toHaveAttribute('href', '/prompt_manager/gallery');
expect((await workspace.request.get('/prompt_manager/gallery')).ok()).toBe(true);
await workspace.evaluate(() => { location.hash = '/images'; });
await workspace.reload();
await expect(workspace.locator('#workspace-main h1')).toHaveText('Images');
await expect(workspace.locator('body')).toHaveAttribute('data-ca-theme', 'light');
await workspace.screenshot({ path: testInfo.outputPath('workspace-host.png') });
expect(errors).toEqual([]);
expect(await page.evaluate(() => LiteGraph.vueNodesMode)).toBe(testInfo.project.metadata.initialRenderer);
} finally {
await workspace.close();
}
});