Compare commits

...

9 Commits

Author SHA1 Message Date
github-actions
6f309e08c2 [automated] Update test expectations 2026-03-20 18:38:03 +00:00
Alexander Brown
d9790ec730 Merge branch 'main' into drjkl/noodles-going-crazy-or-away 2026-03-20 11:32:09 -07:00
Alexander Brown
dcbf422d5e Merge branch 'main' into drjkl/noodles-going-crazy-or-away 2026-03-19 19:40:38 -07:00
Alexander Brown
6a95c00468 Merge branch 'main' into drjkl/noodles-going-crazy-or-away 2026-03-19 00:47:09 -07:00
github-actions
1d291b13d2 [automated] Update test expectations 2026-03-19 06:31:24 +00:00
Alexander Brown
de831619f6 Merge branch 'main' into drjkl/noodles-going-crazy-or-away 2026-03-18 23:25:33 -07:00
Alexander Brown
d4bcf96900 test: add mode switch links E2E spec
Amp-Thread-ID: https://ampcode.com/threads/T-019d0327-9c42-7359-bd74-d086101824a4
Co-authored-by: Amp <amp@ampcode.com>
2026-03-18 23:23:24 -07:00
Alexander Brown
1f7658af8a fix: avoid double getBoundingClientRect in slot element tracking
Amp-Thread-ID: https://ampcode.com/threads/T-019d0327-9c42-7359-bd74-d086101824a4
Co-authored-by: Amp <amp@ampcode.com>
2026-03-18 16:07:36 -07:00
Alexander Brown
0ac1ab2773 fix: resync slot layouts when switching between app mode and graph mode
Slot elements lose their DOM measurements when the graph canvas is hidden
via display:none in app mode. On switching back, links rendered with stale
coordinates or disappeared entirely.

- Add isSlotElementMeasurable guard to skip hidden/disconnected elements
- Delete stale slot layouts for unmeasurable elements so links don't render
  at wrong positions
- Watch linearMode to clear/resync slot layouts on mode transitions
- Keep pendingSlotSync active until at least one measurable layout exists
- Expose requestSlotLayoutSyncForAllNodes for explicit full resync
- Add getNodeIds to nodeSlotRegistryStore for iteration

Amp-Thread-ID: https://ampcode.com/threads/T-019d02f7-4b78-71f9-9db4-f79c911e8b31
Co-authored-by: Amp <amp@ampcode.com>
2026-03-18 15:27:14 -07:00
4 changed files with 92 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
import type { Page } from '@playwright/test'
import {
comfyExpect as expect,
comfyPageFixture as test
} from '../../../fixtures/ComfyPage'
import type { ComfyPage } from '../../../fixtures/ComfyPage'
import { fitToViewInstant } from '../../../helpers/fitToView'
/**
* Inject linearData into the current graph so that the app mode toggle
* recognises output nodes and shows the linear UI.
*/
async function injectLinearData(page: Page) {
await page.evaluate(async () => {
const graph = window.app!.graph
if (!graph) return
const outputNodeIds = graph.nodes
.filter(
(n: { type?: string }) =>
n.type === 'SaveImage' || n.type === 'PreviewImage'
)
.map((n: { id: number | string }) => String(n.id))
const workflow = graph.serialize() as unknown as Record<string, unknown>
const extra = (workflow.extra ?? {}) as Record<string, unknown>
extra.linearData = { inputs: [], outputs: outputNodeIds }
workflow.extra = extra
await window.app!.loadGraphData(
workflow as unknown as Parameters<
NonNullable<typeof window.app>['loadGraphData']
>[0]
)
})
}
async function enterAppMode(comfyPage: ComfyPage) {
await injectLinearData(comfyPage.page)
await comfyPage.nextFrame()
await comfyPage.page.evaluate(() => {
window.app!.extensionManager.command.execute('Comfy.ToggleLinear')
})
await comfyPage.nextFrame()
}
async function enterGraphMode(comfyPage: ComfyPage) {
await comfyPage.page.evaluate(() => {
window.app!.extensionManager.command.execute('Comfy.ToggleLinear')
})
await comfyPage.nextFrame()
}
test.describe(
'Vue Node links after mode switch',
{ tag: ['@screenshot', '@canvas'] },
() => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.workflow.loadWorkflow('default')
await comfyPage.vueNodes.waitForNodes()
await fitToViewInstant(comfyPage)
})
test('links render correctly after switching to app mode and back', async ({
comfyPage
}) => {
// Capture baseline screenshot with links visible in graph mode
await expect(comfyPage.canvas).toHaveScreenshot(
'mode-switch-links-before.png'
)
// Switch to app mode — graph canvas hidden via display:none
await enterAppMode(comfyPage)
await expect(
comfyPage.page.locator('[data-testid="linear-widgets"]')
).toBeVisible({ timeout: 5000 })
// Switch back to graph mode
await enterGraphMode(comfyPage)
await comfyPage.vueNodes.waitForNodes()
await fitToViewInstant(comfyPage)
// Links must render at the same positions as before the mode switch
await expect(comfyPage.canvas).toHaveScreenshot(
'mode-switch-links-after.png'
)
})
}
)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

After

Width:  |  Height:  |  Size: 98 KiB