mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 06:20:11 +00:00
## Summary Extract repeated patterns from 12 subgraph Playwright spec files into shared test utilities, reducing duplication by ~142 lines. ## Changes - **What**: New shared helpers for common subgraph test operations: - `SubgraphHelper`: `getSlotCount()`, `getSlotLabel()`, `removeSlot()`, `findSubgraphNodeId()` - `NodeReference`: `delete()` - `subgraphTestUtils`: `serializeAndReload()`, `convertDefaultKSamplerToSubgraph()`, `expectWidgetBelowHeader()`, `collectConsoleWarnings()`, `packAllInteriorNodes()` - Replaced ~72 inline `page.evaluate` blocks and multi-line sequences with single helper calls across 12 spec files ## Review Focus - Behavioral equivalence: every replacement is a mechanical extraction with no test logic changes - API surface of new helpers: naming, parameter types, placement in existing utility classes - Whether any remaining inline patterns in the spec files would benefit from further extraction ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-10629-test-extract-shared-subgraph-E2E-test-utilities-3306d73d365081b0b6b5db52ed0a4552) by [Unito](https://www.unito.io) --------- Co-authored-by: Amp <amp@ampcode.com>
105 lines
3.3 KiB
TypeScript
105 lines
3.3 KiB
TypeScript
import { expect } from '@playwright/test'
|
|
|
|
import { comfyPageFixture as test } from '../fixtures/ComfyPage'
|
|
import { SubgraphHelper } from '../fixtures/helpers/SubgraphHelper'
|
|
|
|
test.describe('Nested subgraph configure order', { tag: ['@subgraph'] }, () => {
|
|
const WORKFLOW = 'subgraphs/subgraph-nested-duplicate-ids'
|
|
|
|
test('Loads without "No link found" or "Failed to resolve legacy -1" console warnings', async ({
|
|
comfyPage
|
|
}) => {
|
|
const { warnings } = SubgraphHelper.collectConsoleWarnings(comfyPage.page, [
|
|
'No link found',
|
|
'Failed to resolve legacy -1'
|
|
])
|
|
|
|
await comfyPage.workflow.loadWorkflow(WORKFLOW)
|
|
|
|
expect(warnings).toEqual([])
|
|
})
|
|
|
|
test('All three subgraph levels resolve promoted widgets', async ({
|
|
comfyPage
|
|
}) => {
|
|
await comfyPage.workflow.loadWorkflow(WORKFLOW)
|
|
await comfyPage.nextFrame()
|
|
|
|
const results = await comfyPage.page.evaluate(() => {
|
|
const graph = window.app!.canvas.graph!
|
|
const allGraphs = [graph, ...graph.subgraphs.values()]
|
|
|
|
return allGraphs.flatMap((g) =>
|
|
g._nodes
|
|
.filter(
|
|
(n) => typeof n.isSubgraphNode === 'function' && n.isSubgraphNode()
|
|
)
|
|
.map((hostNode) => {
|
|
const proxyWidgets = Array.isArray(
|
|
hostNode.properties?.proxyWidgets
|
|
)
|
|
? hostNode.properties.proxyWidgets
|
|
: []
|
|
|
|
const widgetEntries = proxyWidgets
|
|
.filter(
|
|
(e: unknown): e is [string, string] =>
|
|
Array.isArray(e) &&
|
|
e.length >= 2 &&
|
|
typeof e[0] === 'string' &&
|
|
typeof e[1] === 'string'
|
|
)
|
|
.map(([interiorNodeId, widgetName]: [string, string]) => {
|
|
const sg = hostNode.isSubgraphNode() ? hostNode.subgraph : null
|
|
const interiorNode = sg?.getNodeById(Number(interiorNodeId))
|
|
return {
|
|
interiorNodeId,
|
|
widgetName,
|
|
resolved: interiorNode !== null && interiorNode !== undefined
|
|
}
|
|
})
|
|
|
|
return {
|
|
hostNodeId: String(hostNode.id),
|
|
widgetEntries
|
|
}
|
|
})
|
|
)
|
|
})
|
|
|
|
expect(
|
|
results.length,
|
|
'Should have subgraph host nodes at multiple nesting levels'
|
|
).toBeGreaterThanOrEqual(2)
|
|
|
|
for (const { hostNodeId, widgetEntries } of results) {
|
|
expect(
|
|
widgetEntries.length,
|
|
`Host node ${hostNodeId} should have promoted widgets`
|
|
).toBeGreaterThan(0)
|
|
|
|
for (const { interiorNodeId, widgetName, resolved } of widgetEntries) {
|
|
expect(interiorNodeId).not.toBe('-1')
|
|
expect(Number(interiorNodeId)).toBeGreaterThan(0)
|
|
expect(widgetName).toBeTruthy()
|
|
expect(
|
|
resolved,
|
|
`Widget "${widgetName}" (interior node ${interiorNodeId}) on host ${hostNodeId} should resolve`
|
|
).toBe(true)
|
|
}
|
|
}
|
|
})
|
|
|
|
test('Prompt execution succeeds without 400 error', async ({ comfyPage }) => {
|
|
await comfyPage.workflow.loadWorkflow(WORKFLOW)
|
|
await comfyPage.nextFrame()
|
|
|
|
const responsePromise = comfyPage.page.waitForResponse('**/api/prompt')
|
|
|
|
await comfyPage.command.executeCommand('Comfy.QueuePrompt')
|
|
|
|
const response = await responsePromise
|
|
expect(response.status()).not.toBe(400)
|
|
})
|
|
})
|