* feat(cutover): every entry point opens the workspace; legacy pages stay reachable The top-bar PM button, the nodes' Web UI buttons and /prompt_manager/web now open the workspace Library. Overview's cards open their native pages. The legacy pages stay at their URLs, with no route changed. Classic Web UI no longer navigates the canvas away when a popup is blocked; it shows a notification, as the focused node does. Closes #525 * feat(cutover): link the legacy pages from System and when the workspace fails to load System's Overview section ends with one small Legacy pages line (D165). If a workspace module fails to load or throws while starting, the page shows a static message with the same links instead of an empty shell. Part of #525 * test(cutover): prove the Pair node's Web UI on the real host Part of #525 * test(cutover): count the new real-host cases in the stock matrix pin The PM button test and three renderer-and-reload tests, in 2 projects, take the stock matrix from 110 to 118. Part of #525
81 lines
5.6 KiB
JavaScript
81 lines
5.6 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { execFileSync } from 'node:child_process';
|
|
import { fileURLToPath } from 'node:url';
|
|
import { readFileSync } from 'node:fs';
|
|
|
|
const root = fileURLToPath(new URL('../../', import.meta.url));
|
|
test('real-ComfyUI suite registers Classic and Nodes 2.0 startup projects', () => {
|
|
const output = execFileSync(process.execPath, ['tools/vendor/node_modules/@playwright/test/cli.js',
|
|
'test', '--config', 'tools/vendor/comfyui.config.mjs', '--list'], {
|
|
cwd: root, encoding: 'utf8', env: { ...process.env,
|
|
PM_COMFY_ROOT: '/unused-pinned-checkout', PM_COMFY_URL: 'http://127.0.0.1:8199/' },
|
|
});
|
|
assert.match(output, /\[classic-start\]/);
|
|
assert.match(output, /\[nodes2-start\]/);
|
|
});
|
|
|
|
test('execution script discovers only the new matrix and preserves all 78 original stock cases plus the native editor and renderer host cases', () => {
|
|
const manifest = JSON.parse(readFileSync(new URL('../../tools/vendor/package.json', import.meta.url), 'utf8'));
|
|
assert.equal(manifest.scripts['test:executions'], 'playwright test --config playwright.execution.config.mjs');
|
|
const list = config => execFileSync(process.execPath, ['tools/vendor/node_modules/@playwright/test/cli.js',
|
|
'test', '--config', config, '--list'], { cwd: root, encoding: 'utf8',
|
|
env: { ...process.env, PM_COMFY_ROOT: '/unused-pinned-checkout' } });
|
|
const stock = list('tools/vendor/comfyui.config.mjs');
|
|
// + local Inspect host case (inspect-sender.spec.mjs, 2 projects), + the S10 renderer case (prompt-bridge.spec.mjs, 2 projects)
|
|
// + #343 linked text: five node types, PromptSearchList, the pre-#343 workflows, legacy Primitive, moved link,
|
|
// paste/clone/undo, wildcard Primitive, subgraph Primitive (text-link.spec.mjs, 2 projects)
|
|
// + #525 the PM button and three nodes' Web UI after renderer switches and reload (prompt-manager.spec.mjs, 2 projects)
|
|
assert.match(stock, /Total: 118 tests in 9 files/);
|
|
assert.doesNotMatch(stock, /execution-history/);
|
|
assert.doesNotMatch(stock, /execution-outputs/);
|
|
assert.doesNotMatch(stock, /library-location/); // it starts its own fresh host (#249 S6b)
|
|
assert.doesNotMatch(stock, /image-attribution/); // needs the owned fixture pack (#342)
|
|
const executions = list('tools/vendor/playwright.execution.config.mjs');
|
|
assert.match(executions, /\[classic-start\]/);
|
|
assert.match(executions, /\[nodes2-start\]/);
|
|
// + the fresh-host library location case, + #342 image attribution, + #343 linked text,
|
|
// + #332 image category routes on a generated output (image-attribution.spec.mjs, 2 projects),
|
|
// + #347 cached runtime-linked runs: five node kinds and eight one-renderer cases (execution-text-link.spec.mjs, 2 projects),
|
|
// + #90 Save to library off (five node types), + #247 foreign workflows (image-attribution.spec.mjs, 2 tests x 2 projects)
|
|
assert.match(executions, /Total: 132 tests in 5 files/);
|
|
for (const project of ['classic-start', 'nodes2-start']) {
|
|
const cases = executions.split('\n').filter(line => line.includes(`[${project}]`));
|
|
assert.equal(cases.filter(line => line.includes('execution-history.spec.mjs')).length, 15);
|
|
assert.equal(cases.filter(line => line.includes('execution-outputs.spec.mjs')).length, 8);
|
|
assert.equal(cases.filter(line => line.includes('library-location.spec.mjs')).length, 1);
|
|
assert.equal(cases.filter(line => line.includes('image-attribution.spec.mjs')).length, 5);
|
|
assert.equal(cases.filter(line => line.includes('execution-text-link.spec.mjs')).length, 37);
|
|
}
|
|
assert.doesNotMatch(executions, /prompt-manager.spec/);
|
|
});
|
|
|
|
test('execution config refuses live-host URLs and binds a managed loopback port', () => {
|
|
for (const url of ['http://127.0.0.1:8188/', 'https://127.0.0.1:8196/', 'http://localhost:8196/', 'http://example.com:8196/']) {
|
|
assert.throws(() => execFileSync(process.execPath, ['--input-type=module', '-e',
|
|
"await import('./tools/vendor/playwright.execution.config.mjs')"], { cwd: root, stdio: 'pipe',
|
|
env: { ...process.env, PM_COMFY_ROOT: '/unused', PM_EXECUTION_URL: url } }), /loopback|8196/);
|
|
}
|
|
});
|
|
|
|
test('CI retains stock, execution and pack suites in order with uploaded execution reports', () => {
|
|
const workflow = readFileSync(new URL('../../.github/workflows/test.yml', import.meta.url), 'utf8');
|
|
const commands = [...workflow.matchAll(/^ run: npm run --prefix tools\/vendor (test:[a-z]+)$/gm)].map(match => match[1]);
|
|
assert.deepEqual(commands, ['test:comfyui', 'test:executions', 'test:compat']);
|
|
assert.match(workflow, /path: tools\/vendor\/test-results\//);
|
|
});
|
|
|
|
test('real-host config waits for its own launcher, never for whichever server holds the port', async t => {
|
|
const previous = process.env.PM_COMFY_ROOT;
|
|
process.env.PM_COMFY_ROOT = '/unused-pinned-checkout';
|
|
t.after(() => { if (previous === undefined) delete process.env.PM_COMFY_ROOT; else process.env.PM_COMFY_ROOT = previous; });
|
|
const { default: config } = await import('../../tools/vendor/comfyui.config.mjs');
|
|
const [server] = config.webServer;
|
|
assert.equal(server.url, undefined);
|
|
assert.equal(server.port, undefined);
|
|
assert.equal(server.reuseExistingServer, false);
|
|
const ready = server.wait.stdout.exec('Starting server\nPM_COMFY_HOST_READY base-directory=/tmp/comfyassets-host-a b\r\nlater');
|
|
assert.equal(ready.groups.pm_comfy_host_base, '/tmp/comfyassets-host-a b');
|
|
assert.equal(server.wait.stdout.exec('To see the GUI go to: http://127.0.0.1:8189'), null);
|
|
});
|