test: use Vue nodes DOM assertions for stale proxyWidgets test

- Enable Vue nodes and assert via DOM locators instead of LiteGraph internals
- Add data-testid to NodeWidgets container and individual widgets
- Register widget test IDs in centralized TestIds selectors

Amp-Thread-ID: https://ampcode.com/threads/T-019d1436-f636-7178-a78c-a3e8b93047a5
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Alexander Brown
2026-03-21 23:31:56 -07:00
parent 6ac6eeb963
commit 0a3abf5d49
3 changed files with 20 additions and 28 deletions

View File

@@ -57,6 +57,8 @@ export const TestIds = {
colorRed: 'red'
},
widgets: {
container: 'node-widgets',
widget: 'node-widget',
decrement: 'decrement',
increment: 'increment',
domWidgetTextarea: 'dom-widget-textarea',

View File

@@ -2,6 +2,7 @@ import {
comfyPageFixture as test,
comfyExpect as expect
} from '../fixtures/ComfyPage'
import { TestIds } from '../fixtures/selectors'
const WORKFLOW = 'subgraphs/nested-subgraph-stale-proxy-widgets'
@@ -22,42 +23,29 @@ test.describe(
'Nested subgraph stale proxyWidgets',
{ tag: ['@subgraph', '@widget'] },
() => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
})
test('Outer subgraph node has no stale proxyWidgets after nested packing', async ({
comfyPage
}) => {
await comfyPage.workflow.loadWorkflow(WORKFLOW)
await comfyPage.nextFrame()
await comfyPage.vueNodes.waitForNodes()
const result = await comfyPage.page.evaluate(() => {
const graph = window.app!.canvas.graph!
const outerNode = graph.getNodeById('10')
if (
!outerNode ||
typeof outerNode.isSubgraphNode !== 'function' ||
!outerNode.isSubgraphNode()
) {
return { error: 'Node 10 is not a SubgraphNode' }
}
const outerNode = comfyPage.vueNodes.getNodeLocator('10')
await expect(outerNode).toBeVisible()
const proxyWidgets = (outerNode.properties?.proxyWidgets ??
[]) as string[][]
const widgetTypes = (outerNode.widgets ?? []).map(
(w: { type: string }) => w.type
)
const widgets = outerNode.getByTestId(TestIds.widgets.widget)
return { proxyWidgets, widgetTypes }
})
// Only the KSampler seed widget should be present — no stale
// "Disconnected" placeholders from the packed CLIPTextEncode nodes.
await expect(widgets).toHaveCount(1)
await expect(widgets.first()).toBeVisible()
if ('error' in result) {
throw new Error(result.error)
}
// proxyWidgets should only contain ["3","seed"] (KSampler),
// not the stale ["7","text"] or ["6","text"] entries
expect(result.proxyWidgets).toEqual([['3', 'seed']])
// No "button" type widgets (the Disconnected placeholder)
expect(result.widgetTypes).not.toContain('button')
// Verify the seed widget is present via its label
const seedWidget = outerNode.getByLabel('seed', { exact: true })
await expect(seedWidget).toBeVisible()
})
}
)

View File

@@ -4,6 +4,7 @@
</div>
<div
v-else
data-testid="node-widgets"
:class="
cn(
'lg-node-widgets grid grid-cols-[min-content_minmax(80px,min-content)_minmax(125px,1fr)] gap-y-1 pr-3',
@@ -24,6 +25,7 @@
<template v-for="widget in processedWidgets" :key="widget.renderKey">
<div
v-if="!widget.hidden && (!widget.advanced || showAdvanced)"
data-testid="node-widget"
class="lg-node-widget group col-span-full grid grid-cols-subgrid items-stretch"
>
<!-- Widget Input Slot Dot -->