* feat(ui): add Focused Prompt Manager node (#186) * feat(ui): autocomplete saved Focused metadata with shared controls (#186) * feat(ui): autocomplete Focused library filters (#186)
124 lines
6.5 KiB
JavaScript
124 lines
6.5 KiB
JavaScript
import { test, expect } from '../../tools/vendor/node_modules/@playwright/test/index.mjs';
|
|
import { installHostHooks } from './host-fixture.mjs';
|
|
|
|
installHostHooks(test);
|
|
|
|
for (const type of ['PromptManager', 'PromptManagerText']) {
|
|
test(`${type} selects real database prompts and preserves text across renderers and reload`, async ({ page, request }, testInfo) => {
|
|
const text = `Host test ${type} ${testInfo.project.name}`;
|
|
const saved = await request.post('/prompt_manager/save', { data: { text, category: 'Host tests', tags: ['host-test'] } });
|
|
expect(saved.ok()).toBe(true);
|
|
expect((await saved.json()).success).toBe(true);
|
|
const id = await page.evaluate(async type => {
|
|
const { app } = await import('/scripts/app.js');
|
|
const node = LiteGraph.createNode(type);
|
|
app.graph.add(node);
|
|
node.setSize([650, 800]);
|
|
app.canvas.centerOnNode(node);
|
|
return node.id;
|
|
}, type);
|
|
const recent = page.getByRole('button', { name: '📋 Recent', exact: true });
|
|
await expect(recent).toBeVisible();
|
|
if (type === 'PromptManager') {
|
|
await expect(page.locator('.pm-classic')).toBeVisible();
|
|
await expect(page.getByRole('button', { name: '🔍 Search', exact: true })).toHaveCSS('background-color', 'rgb(8, 119, 187)');
|
|
}
|
|
await recent.click();
|
|
await page.getByText(text, { exact: true }).click();
|
|
const state = () => page.evaluate(async id => {
|
|
const { app } = await import('/scripts/app.js');
|
|
const node = app.graph.getNodeById(id);
|
|
return Object.fromEntries(node.widgets.filter(widget => ['text', 'category', 'tags'].includes(widget.name)).map(widget => [widget.name, widget.value]));
|
|
}, id);
|
|
await expect.poll(state).toMatchObject({ text, category: 'Host tests', tags: 'host-test' });
|
|
for (const renderer of [!testInfo.project.metadata.initialRenderer, testInfo.project.metadata.initialRenderer]) {
|
|
await page.evaluate(async renderer => {
|
|
const { app } = await import('/scripts/app.js');
|
|
await app.ui.settings.setSettingValue('Comfy.VueNodes.Enabled', renderer);
|
|
app.canvas.ds.scale = .8;
|
|
app.canvas.centerOnNode(app.graph._nodes[0]);
|
|
}, renderer);
|
|
await expect.poll(() => page.evaluate(() => LiteGraph.vueNodesMode)).toBe(renderer);
|
|
await expect(recent).toHaveCount(1);
|
|
await expect(recent).toBeVisible();
|
|
expect(await state()).toMatchObject({ text });
|
|
}
|
|
const output = await page.evaluate(async id => {
|
|
const { app } = await import('/scripts/app.js');
|
|
const prompt = await app.graphToPrompt();
|
|
const workflow = app.graph.serialize();
|
|
await app.loadGraphData(workflow);
|
|
return prompt.output[String(id)].inputs;
|
|
}, id);
|
|
expect(output.text).toBe(text);
|
|
await expect.poll(state).toMatchObject({ text, category: 'Host tests', tags: 'host-test' });
|
|
await expect(recent).toHaveCount(1);
|
|
await page.screenshot({ path: testInfo.outputPath(`${type}-reloaded.png`) });
|
|
const removedStyle = await page.evaluate(async id => {
|
|
const { app } = await import('/scripts/app.js');
|
|
const node = app.graph.getNodeById(id);
|
|
const style = node._styleSheet;
|
|
app.graph.remove(node);
|
|
return !style.isConnected;
|
|
}, id);
|
|
expect(removedStyle).toBe(true);
|
|
await expect(recent).toHaveCount(0);
|
|
});
|
|
}
|
|
|
|
test('all node schemas and extension entrypoints load from the real host', async ({ page, request }) => {
|
|
const definitions = await (await request.get('/object_info')).json();
|
|
expect(definitions.PromptManager.display_name).toBe('Prompt Manager (Classic)');
|
|
for (const name of ['PromptManager', 'PromptManagerText', 'PromptSearchList']) expect(definitions[name]?.name).toBe(name);
|
|
const extensions = await (await request.get('/extensions')).json();
|
|
expect(extensions.filter(path => path.startsWith('/extensions/promptmanager/'))).toEqual(['/extensions/promptmanager/prompt_manager.js']);
|
|
const result = await page.evaluate(async () => {
|
|
const { app } = await import('/scripts/app.js');
|
|
const node = LiteGraph.createNode('PromptSearchList');
|
|
app.graph.add(node);
|
|
const workflow = app.graph.serialize();
|
|
await app.loadGraphData(workflow);
|
|
return { type: app.graph._nodes[0].type, extension: app.extensions.some(item => item.name === 'PromptManager.UI') };
|
|
});
|
|
expect(result).toEqual({ type: 'PromptSearchList', extension: true });
|
|
});
|
|
|
|
for (const type of ['PromptManager', 'PromptManagerText']) {
|
|
test(`${type} Web UI button opens actual standalone pages`, async ({ page }) => {
|
|
await page.evaluate(async type => {
|
|
const { app } = await import('/scripts/app.js');
|
|
const node = LiteGraph.createNode(type);
|
|
app.graph.add(node);
|
|
app.canvas.centerOnNode(node);
|
|
}, type);
|
|
const popupPromise = page.waitForEvent('popup');
|
|
await page.getByRole('button', { name: '🌐 Web UI', exact: true }).click();
|
|
const popup = await popupPromise;
|
|
await popup.waitForLoadState('domcontentloaded');
|
|
await expect(popup).toHaveURL(/\/prompt_manager\/(web|admin)/);
|
|
await expect(popup.locator('body')).toContainText('Prompt');
|
|
await popup.goto(new URL('/prompt_manager/gallery', page.url()).href);
|
|
await expect(popup.locator('#addPromptBtn')).toBeVisible();
|
|
await popup.close();
|
|
});
|
|
}
|
|
|
|
test('Classic controls follow actual ComfyUI light and dark palettes', async ({ page }, testInfo) => {
|
|
await page.evaluate(async () => {
|
|
const { app } = await import('/scripts/app.js');
|
|
const node = LiteGraph.createNode('PromptManager');
|
|
app.graph.add(node);
|
|
node.setSize([650, 800]);
|
|
app.canvas.centerOnNode(node);
|
|
});
|
|
for (const palette of ['light', 'dark']) {
|
|
await page.evaluate(async palette => {
|
|
const { app } = await import('/scripts/app.js');
|
|
await app.ui.settings.setSettingValue('Comfy.ColorPalette', palette);
|
|
}, palette);
|
|
await expect(page.locator('.pm-classic')).toHaveAttribute('data-ca-theme', palette);
|
|
await expect(page.getByRole('button', { name: '🔍 Search', exact: true })).toHaveCSS('background-color', 'rgb(8, 119, 187)');
|
|
await page.screenshot({ path: testInfo.outputPath(`classic-${palette}.png`) });
|
|
}
|
|
});
|