Files
ComfyUI_frontend/browser_tests/tests/graphCanvasMenu.spec.ts
snomiao a6f3709d4a fix: Stabilize flaky link visibility toggle test
The test was flaky because it wasn't properly waiting for the canvas
to update after changing the link render mode setting. The setting
change triggers a canvas redraw via setDirty(), but the actual redraw
happens asynchronously.

Changes:
- Add explicit wait for canvas.links_render_mode to update
- Capture initial link render mode to properly verify state changes
- Add double frame wait plus 100ms delay to ensure canvas redraw completes
- Improve wait condition for visible links to handle undefined initial state
- Add timeout protection to prevent test hanging

This ensures the test reliably waits for both the setting change
and the visual update before taking screenshots, eliminating the
race condition that was causing intermittent failures.
2025-09-09 15:20:17 +09:00

126 lines
4.0 KiB
TypeScript

import { expect } from '@playwright/test'
import { comfyPageFixture as test } from '../fixtures/ComfyPage'
test.describe('Graph Canvas Menu', () => {
test.beforeEach(async ({ comfyPage }) => {
// Set link render mode to spline to make sure it's not affected by other tests'
// side effects.
await comfyPage.setSetting('Comfy.LinkRenderMode', 2)
// Enable canvas menu for all tests
await comfyPage.setSetting('Comfy.Graph.CanvasMenu', true)
})
test('Can toggle link visibility', async ({ comfyPage }) => {
const button = comfyPage.page.getByTestId('toggle-link-visibility-button')
// Get the initial link render mode and HIDDEN_LINK constant
const { initialMode, hiddenLinkMode } = await comfyPage.page.evaluate(
() => {
return {
initialMode: window['app']?.canvas?.links_render_mode,
hiddenLinkMode: window['LiteGraph'].HIDDEN_LINK
}
}
)
// First click - hide links
await button.click()
// Wait for the setting to actually change to hidden
await comfyPage.page.waitForFunction(
(expectedMode) => {
const canvas = window['app']?.canvas
return canvas && canvas.links_render_mode === expectedMode
},
hiddenLinkMode,
{ timeout: 5000 }
)
// Wait for canvas to complete rendering with hidden links
// Use multiple frames and a small delay to ensure canvas is fully updated
await comfyPage.nextFrame()
await comfyPage.nextFrame()
await comfyPage.page.waitForTimeout(100) // Small delay for canvas rendering
await expect(comfyPage.canvas).toHaveScreenshot(
'canvas-with-hidden-links.png'
)
expect(await comfyPage.getSetting('Comfy.LinkRenderMode')).toBe(
hiddenLinkMode
)
// Second click - show links again
await button.click()
// Wait for the setting to change back to the initial mode
await comfyPage.page.waitForFunction(
({ hiddenMode, initial }) => {
const canvas = window['app']?.canvas
// Check that it's not hidden and matches the expected visible mode
return (
canvas &&
canvas.links_render_mode !== hiddenMode &&
(initial === undefined || canvas.links_render_mode === initial)
)
},
{ hiddenMode: hiddenLinkMode, initial: initialMode },
{ timeout: 5000 }
)
// Wait for canvas to complete rendering with visible links
// Use multiple frames and a small delay to ensure canvas is fully updated
await comfyPage.nextFrame()
await comfyPage.nextFrame()
await comfyPage.page.waitForTimeout(100) // Small delay for canvas rendering
await expect(comfyPage.canvas).toHaveScreenshot(
'canvas-with-visible-links.png'
)
expect(await comfyPage.getSetting('Comfy.LinkRenderMode')).not.toBe(
hiddenLinkMode
)
})
test('Focus mode button is clickable and has correct test id', async ({
comfyPage
}) => {
const focusButton = comfyPage.page.getByTestId('focus-mode-button')
await expect(focusButton).toBeVisible()
await expect(focusButton).toBeEnabled()
// Test that the button can be clicked without error
await focusButton.click()
await comfyPage.nextFrame()
})
test('Zoom controls popup opens and closes', async ({ comfyPage }) => {
// Find the zoom button by its percentage text content
const zoomButton = comfyPage.page.locator('button').filter({
hasText: '%'
})
await expect(zoomButton).toBeVisible()
// Click to open zoom controls
await zoomButton.click()
await comfyPage.nextFrame()
// Zoom controls modal should be visible
const zoomModal = comfyPage.page
.locator('div')
.filter({
hasText: 'Zoom To Fit'
})
.first()
await expect(zoomModal).toBeVisible()
// Click backdrop to close
const backdrop = comfyPage.page.locator('.fixed.inset-0').first()
await backdrop.click()
await comfyPage.nextFrame()
// Modal should be hidden
await expect(zoomModal).not.toBeVisible()
})
})