merge: resolve conflict in colors.spec.ts with main

This commit is contained in:
Johnpaul
2026-04-13 22:22:32 +01:00
80 changed files with 1386 additions and 1535 deletions

View File

@@ -414,6 +414,8 @@ export const comfyPageFixture = base.extend<{
const userId = await comfyPage.setupUser(username)
comfyPage.userIds[parallelIndex] = userId
const isVueNodes = testInfo.tags.includes('@vue-nodes')
try {
await comfyPage.setupSettings({
'Comfy.UseNewMenu': 'Top',
@@ -436,7 +438,8 @@ export const comfyPageFixture = base.extend<{
'Comfy.VersionCompatibility.DisableWarnings': true,
// Disable errors tab to prevent missing model detection from
// rendering error indicators on nodes during unrelated tests.
'Comfy.RightSidePanel.ShowErrorsTab': false
'Comfy.RightSidePanel.ShowErrorsTab': false,
...(isVueNodes && { 'Comfy.VueNodes.Enabled': true })
})
} catch (e) {
console.error(e)
@@ -448,6 +451,10 @@ export const comfyPageFixture = base.extend<{
await comfyPage.setup()
if (isVueNodes) {
await comfyPage.vueNodes.waitForNodes()
}
const needsPerf =
testInfo.tags.includes('@perf') || testInfo.tags.includes('@audit')
if (needsPerf) await comfyPage.perf.init()

View File

@@ -8,10 +8,6 @@ import type { WorkspaceStore } from '@e2e/types/globals'
const test = mergeTests(comfyPageFixture, webSocketFixture)
test.describe('Actionbar', { tag: '@ui' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
})
/**
* This test ensures that the autoqueue change mode can only queue one change at a time
*/

View File

@@ -4,10 +4,6 @@ import {
} from '@e2e/fixtures/ComfyPage'
test.describe('Bottom Panel Logs', { tag: '@ui' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
})
test('should open bottom panel via toggle button', async ({ comfyPage }) => {
const { bottomPanel } = comfyPage

View File

@@ -3,10 +3,6 @@ import { expect } from '@playwright/test'
import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage'
test.describe('Bottom Panel Shortcuts', { tag: '@ui' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
})
test('should toggle shortcuts panel visibility', async ({ comfyPage }) => {
const { bottomPanel } = comfyPage

View File

@@ -8,10 +8,9 @@ const NODE_TITLE = 'KSampler'
test.describe(
'Collapsed node link positions',
{ tag: ['@canvas', '@node'] },
{ tag: ['@canvas', '@node', '@vue-nodes'] },
() => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.workflow.loadWorkflow('default')
await comfyPage.vueNodes.waitForNodes()
})

View File

@@ -20,10 +20,6 @@ async function verifyCustomIconSvg(iconElement: Locator) {
}
test.describe('Custom Icons', { tag: '@settings' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
})
test('sidebar tab icons use custom SVGs', async ({ comfyPage }) => {
// Find the icon in the sidebar
const icon = comfyPage.page.locator(

View File

@@ -20,7 +20,6 @@ async function pressKeyAndExpectRequest(
test.describe('Default Keybindings', { tag: '@keyboard' }, () => {
test.describe('Sidebar Toggle Shortcuts', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.canvas.click({ position: { x: 400, y: 400 } })
await comfyPage.nextFrame()
})
@@ -164,8 +163,6 @@ test.describe('Default Keybindings', { tag: '@keyboard' }, () => {
test.describe('Mode and Panel Toggles', () => {
test("'Alt+m' toggles app mode", async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
// Set up linearData so app mode has something to show
await comfyPage.appMode.enterAppModeWithInputs([])
await expect(comfyPage.appMode.linearWidgets).toBeVisible()
@@ -180,7 +177,6 @@ test.describe('Default Keybindings', { tag: '@keyboard' }, () => {
})
test("'Alt+Shift+m' toggles minimap", async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting('Comfy.Minimap.Visible', true)
await comfyPage.settings.setSetting('Comfy.Graph.CanvasMenu', true)
await comfyPage.workflow.loadWorkflow('default')
@@ -196,8 +192,6 @@ test.describe('Default Keybindings', { tag: '@keyboard' }, () => {
})
test("'Ctrl+`' toggles terminal/logs panel", async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await expect(comfyPage.bottomPanel.root).toBeHidden()
await comfyPage.page.keyboard.press('Control+Backquote')

View File

@@ -103,7 +103,6 @@ test.describe('Support', () => {
comfyPage
}) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
// Prevent loading the external page
await comfyPage.page
.context()

View File

@@ -7,7 +7,6 @@ test.describe('Sign In dialog', { tag: '@ui' }, () => {
let dialog: SignInDialog
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
dialog = new SignInDialog(comfyPage.page)
await dialog.open()
})

View File

@@ -9,7 +9,6 @@ import { cleanupFakeModel } from '@e2e/tests/propertiesPanel/ErrorsTabHelper'
test.describe('Error overlay', { tag: '@ui' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting(
'Comfy.RightSidePanel.ShowErrorsTab',
true

View File

@@ -13,10 +13,6 @@ import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage'
type TestSettingId = keyof Settings
test.describe('Topbar commands', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
})
test('Should allow registering topbar commands', async ({ comfyPage }) => {
await comfyPage.page.evaluate(() => {
window.app!.registerExtension({

View File

@@ -5,7 +5,6 @@ import {
test.describe('Focus Mode', { tag: '@ui' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.setup()
})

View File

@@ -4,9 +4,8 @@ import { expect } from '@playwright/test'
import type { ComfyPage } from '@e2e/fixtures/ComfyPage'
import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage'
test.describe('Image Compare', { tag: '@widget' }, () => {
test.describe('Image Compare', { tag: ['@widget', '@vue-nodes'] }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.workflow.loadWorkflow('widgets/image_compare_widget')
await comfyPage.vueNodes.waitForNodes()
})

View File

@@ -895,7 +895,6 @@ test.describe('Load workflow', { tag: '@screenshot' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
workflowA = generateUniqueFilename()
await comfyPage.menu.topbar.saveWorkflow(workflowA)
workflowB = generateUniqueFilename()
@@ -970,7 +969,6 @@ test.describe('Load workflow', { tag: '@screenshot' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
workflowA = generateUniqueFilename()
await comfyPage.menu.topbar.saveWorkflow(workflowA)
workflowB = generateUniqueFilename()
@@ -1060,13 +1058,10 @@ test.describe('Load workflow', { tag: '@screenshot' }, () => {
})
test.describe('Load duplicate workflow', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
})
test('A workflow can be loaded multiple times in a row', async ({
comfyPage
}) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.workflow.loadWorkflow('nodes/single_ksampler')
await comfyPage.menu.workflowsTab.open()
await comfyPage.command.executeCommand('Comfy.NewBlankWorkflow')

View File

@@ -7,7 +7,6 @@ import {
test.describe('Job History Actions', { tag: '@ui' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.setup()
// Expand the queue overlay so the JobHistoryActionsMenu is visible

View File

@@ -5,7 +5,6 @@ import {
test.describe('Linear Mode', { tag: '@ui' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.setup()
})

View File

@@ -3,11 +3,7 @@ import { expect } from '@playwright/test'
import type { ComfyPage } from '@e2e/fixtures/ComfyPage'
import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage'
test.describe('Mask Editor', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
})
test.describe('Mask Editor', { tag: '@vue-nodes' }, () => {
async function loadImageOnNode(comfyPage: ComfyPage) {
await comfyPage.workflow.loadWorkflow('widgets/load_image_widget')
await comfyPage.vueNodes.waitForNodes()

View File

@@ -3,10 +3,6 @@ import { expect } from '@playwright/test'
import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage'
test.describe('Menu', { tag: '@ui' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
})
test('Can register sidebar tab', async ({ comfyPage }) => {
const initialChildrenCount = await comfyPage.menu.buttons.count()

View File

@@ -35,7 +35,6 @@ async function clickMinimapAt(
test.describe('Minimap', { tag: '@canvas' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting('Comfy.Minimap.Visible', true)
await comfyPage.settings.setSetting('Comfy.Graph.CanvasMenu', true)
await comfyPage.workflow.loadWorkflow('default')

View File

@@ -88,7 +88,6 @@ async function setLocaleAndWaitForWorkflowReload(
test.describe('Node Help', { tag: ['@slow', '@ui'] }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.setup()
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting('Comfy.NodeLibrary.NewDesign', false)
})

View File

@@ -5,8 +5,6 @@ import {
test.describe('Node Library Essentials Tab', { tag: '@ui' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
// Enable the essentials feature flag via the reactive serverFeatureFlags ref.
// In production, this flag comes via WebSocket or remoteConfig (cloud only).
// The localhost test server has neither, so we set it directly.

View File

@@ -43,7 +43,6 @@ function imageOutput(...filenames: string[]) {
test.describe('Output History', { tag: '@ui' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.appMode.enterAppModeWithInputs([[KSAMPLER_NODE, 'seed']])
await expect(comfyPage.appMode.linearWidgets).toBeVisible()
await comfyPage.nextFrame()

View File

@@ -9,10 +9,9 @@ import {
triggerSerialization
} from '@e2e/helpers/painter'
test.describe('Painter', { tag: '@widget' }, () => {
test.describe('Painter', { tag: ['@widget', '@vue-nodes'] }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.page.evaluate(() => window.app?.graph?.clear())
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.workflow.loadWorkflow('widgets/painter_widget')
await comfyPage.vueNodes.waitForNodes()
})

View File

@@ -2,53 +2,53 @@ import { expect } from '@playwright/test'
import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage'
test.describe('Paste Image context menu option', { tag: ['@node'] }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
})
test.describe(
'Paste Image context menu option',
{ tag: ['@node', '@vue-nodes'] },
() => {
test('shows Paste Image in LoadImage node context menu', async ({
comfyPage
}) => {
await comfyPage.workflow.loadWorkflow('widgets/load_image_widget')
test('shows Paste Image in LoadImage node context menu', async ({
comfyPage
}) => {
await comfyPage.workflow.loadWorkflow('widgets/load_image_widget')
const loadImageNode = (
await comfyPage.nodeOps.getNodeRefsByType('LoadImage')
)[0]
const loadImageNode = (
await comfyPage.nodeOps.getNodeRefsByType('LoadImage')
)[0]
const nodeEl = comfyPage.page.locator(
`[data-node-id="${loadImageNode.id}"]`
)
await nodeEl.click({ button: 'right' })
const menu = comfyPage.page.locator('.p-contextmenu')
await menu.waitFor({ state: 'visible' })
const menuLabels = await menu
.locator('[role="menuitem"] span.flex-1')
.allInnerTexts()
const nodeEl = comfyPage.page.locator(
`[data-node-id="${loadImageNode.id}"]`
)
await nodeEl.click({ button: 'right' })
const menu = comfyPage.page.locator('.p-contextmenu')
await menu.waitFor({ state: 'visible' })
const menuLabels = await menu
.locator('[role="menuitem"] span.flex-1')
.allInnerTexts()
expect(menuLabels).toContain('Paste Image')
})
expect(menuLabels).toContain('Paste Image')
})
test('does not show Paste Image on output-only image nodes', async ({
comfyPage
}) => {
await comfyPage.workflow.loadWorkflow('nodes/single_save_image_node')
test('does not show Paste Image on output-only image nodes', async ({
comfyPage
}) => {
await comfyPage.workflow.loadWorkflow('nodes/single_save_image_node')
const saveImageNode = (
await comfyPage.nodeOps.getNodeRefsByType('SaveImage')
)[0]
const saveImageNode = (
await comfyPage.nodeOps.getNodeRefsByType('SaveImage')
)[0]
const nodeEl = comfyPage.page.locator(
`[data-node-id="${saveImageNode.id}"]`
)
await nodeEl.click({ button: 'right' })
const menu = comfyPage.page.locator('.p-contextmenu')
await menu.waitFor({ state: 'visible' })
const menuLabels = await menu
.locator('[role="menuitem"] span.flex-1')
.allInnerTexts()
const nodeEl = comfyPage.page.locator(
`[data-node-id="${saveImageNode.id}"]`
)
await nodeEl.click({ button: 'right' })
const menu = comfyPage.page.locator('.p-contextmenu')
await menu.waitFor({ state: 'visible' })
const menuLabels = await menu
.locator('[role="menuitem"] span.flex-1')
.allInnerTexts()
expect(menuLabels).not.toContain('Paste Image')
expect(menuLabels).not.toContain('Open Image')
})
})
expect(menuLabels).not.toContain('Paste Image')
expect(menuLabels).not.toContain('Open Image')
})
}
)

View File

@@ -6,7 +6,6 @@ import { PropertiesPanelHelper } from '@e2e/tests/propertiesPanel/PropertiesPane
test.describe('Errors tab - common', { tag: '@ui' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting(
'Comfy.RightSidePanel.ShowErrorsTab',
true

View File

@@ -7,7 +7,6 @@ import { TestIds } from '@e2e/fixtures/selectors'
test.describe('Errors tab - Execution errors', { tag: '@ui' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting(
'Comfy.RightSidePanel.ShowErrorsTab',
true

View File

@@ -38,7 +38,6 @@ function getDropzone(comfyPage: ComfyPage) {
test.describe('Errors tab - Missing media', { tag: '@ui' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting(
'Comfy.RightSidePanel.ShowErrorsTab',
true

View File

@@ -13,7 +13,6 @@ import {
test.describe('Errors tab - Missing models', { tag: '@ui' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting(
'Comfy.RightSidePanel.ShowErrorsTab',
true

View File

@@ -6,7 +6,6 @@ import { loadWorkflowAndOpenErrorsTab } from '@e2e/tests/propertiesPanel/ErrorsT
test.describe('Errors tab - Missing nodes', { tag: '@ui' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting(
'Comfy.RightSidePanel.ShowErrorsTab',
true

View File

@@ -3,13 +3,11 @@ import { expect } from '@playwright/test'
import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage'
import { PropertiesPanelHelper } from '@e2e/tests/propertiesPanel/PropertiesPanelHelper'
test.describe('Properties panel - Node settings', () => {
test.describe('Properties panel - Node settings', { tag: '@vue-nodes' }, () => {
let panel: PropertiesPanelHelper
test.beforeEach(async ({ comfyPage }) => {
panel = new PropertiesPanelHelper(comfyPage.page)
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.vueNodes.waitForNodes()
await comfyPage.actionbar.propertiesButton.click()
await comfyPage.nodeOps.selectNodes(['KSampler'])
await panel.switchToTab('Settings')

View File

@@ -19,10 +19,6 @@ function createMockRelease(overrides?: Partial<ReleaseNote>): ReleaseNote {
}
test.describe('Release Notifications', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
})
test('should show help center with release information', async ({
comfyPage
}) => {

View File

@@ -47,7 +47,6 @@ test.describe('Remote COMBO Widget', { tag: '@widget' }, () => {
}
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting('Comfy.NodeLibrary.NewDesign', false)
await comfyPage.settings.setSetting(
'Comfy.NodeSearchBoxImpl',
@@ -57,7 +56,6 @@ test.describe('Remote COMBO Widget', { tag: '@widget' }, () => {
test.describe('Loading options', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.page.route(
'**/api/models/checkpoints**',
async (route, request) => {

View File

@@ -3,10 +3,8 @@ import { expect } from '@playwright/test'
import type { ComfyPage } from '@e2e/fixtures/ComfyPage'
import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage'
test.describe('MediaLightbox', { tag: ['@slow'] }, () => {
test.describe('MediaLightbox', { tag: ['@slow', '@vue-nodes'] }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.setup()
})

View File

@@ -5,10 +5,6 @@ import {
import { TestIds } from '@e2e/fixtures/selectors'
test.describe('Right Side Panel Tabs', { tag: '@ui' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
})
test('Properties panel opens with workflow overview', async ({
comfyPage
}) => {

View File

@@ -4,13 +4,8 @@ import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage'
test.describe(
'Save Image and WEBM preview',
{ tag: ['@screenshot', '@widget'] },
{ tag: ['@screenshot', '@widget', '@vue-nodes'] },
() => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.vueNodes.waitForNodes()
})
test('Can preview both SaveImage and SaveWEBM outputs', async ({
comfyPage
}) => {

View File

@@ -3,10 +3,8 @@ import {
comfyPageFixture as test
} from '@e2e/fixtures/ComfyPage'
test.describe('@canvas Selection Rectangle', () => {
test.describe('@canvas Selection Rectangle', { tag: '@vue-nodes' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.setup()
await comfyPage.vueNodes.waitForNodes()
})

View File

@@ -28,10 +28,6 @@ async function selectNodeWithPan(comfyPage: ComfyPage, nodeRef: NodeReference) {
await nodeRef.click('title')
}
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
})
test.describe('Selection Toolbox - Button Actions', { tag: '@ui' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.Canvas.SelectionToolbox', true)

View File

@@ -43,7 +43,6 @@ async function renameInlineFolder(comfyPage: ComfyPage, newName: string) {
test.describe('Node library sidebar', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting('Comfy.NodeLibrary.NewDesign', false)
await comfyPage.settings.setSetting(bookmarksSettingId, [])
await comfyPage.settings.setSetting(bookmarksCustomizationSettingId, {})

View File

@@ -4,7 +4,6 @@ import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage'
test.describe('Node library sidebar V2', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting('Comfy.NodeLibrary.NewDesign', true)
const tab = comfyPage.menu.nodeLibraryTabV2

View File

@@ -5,7 +5,6 @@ import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage'
test.describe('Sidebar splitter width independence', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting('Comfy.Sidebar.UnifiedWidth', true)
await comfyPage.settings.setSetting('Comfy.NodeLibrary.NewDesign', false)
})

View File

@@ -6,7 +6,6 @@ import { openErrorsTab } from '@e2e/tests/propertiesPanel/ErrorsTabHelper'
test.describe('Workflows sidebar', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting(
'Comfy.Workflow.WorkflowTabsPosition',
'Sidebar'

View File

@@ -11,14 +11,8 @@ async function openVueNodeContextMenu(comfyPage: ComfyPage, nodeTitle: string) {
test.describe(
'Subgraph Duplicate Independent Values',
{ tag: ['@slow', '@subgraph'] },
{ tag: ['@slow', '@subgraph', '@vue-nodes'] },
() => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.vueNodes.waitForNodes()
})
test('Duplicated subgraphs maintain independent widget values', async ({
comfyPage
}) => {

View File

@@ -8,10 +8,6 @@ const domPreviewSelector = '.image-preview'
test.describe('Subgraph Lifecycle', { tag: ['@subgraph'] }, () => {
test.describe('Cleanup Behavior After Promoted Source Removal', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
})
test('Deleting the promoted source removes the exterior DOM widget', async ({
comfyPage
}) => {

View File

@@ -33,10 +33,6 @@ function hasVisibleNodeInViewport() {
test.describe('Subgraph Navigation', { tag: ['@slow', '@subgraph'] }, () => {
test.describe('Subgraph Navigation and UI', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
})
test('Breadcrumb updates when subgraph node title is changed', async ({
comfyPage
}) => {
@@ -108,10 +104,6 @@ test.describe('Subgraph Navigation', { tag: ['@slow', '@subgraph'] }, () => {
})
test.describe('Navigation Hotkeys', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
})
test('Navigation hotkey can be customized', async ({ comfyPage }) => {
await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph')
await comfyPage.nextFrame()

View File

@@ -478,7 +478,6 @@ test.describe(
comfyPage
}) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.workflow.loadWorkflow(
'subgraphs/subgraph-nested-promotion'
)
@@ -523,7 +522,6 @@ test.describe(
comfyPage
}) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.workflow.loadWorkflow(
'subgraphs/subgraph-with-promoted-text-widget'
)

View File

@@ -116,7 +116,6 @@ test.describe('Subgraph Promotion DOM', { tag: ['@subgraph'] }, () => {
comfyPage
}) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.workflow.loadWorkflow(
'subgraphs/subgraph-with-promoted-text-widget'
)

View File

@@ -42,7 +42,6 @@ async function searchAndExpectResult(
test.describe('Subgraph Search Aliases', { tag: ['@subgraph'] }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting(
'Comfy.NodeSearchBoxImpl',
'v1 (legacy)'

View File

@@ -4,12 +4,11 @@ import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage'
test.describe(
'Zero UUID workflow: subgraph undo rendering',
{ tag: ['@workflow', '@subgraph'] },
{ tag: ['@workflow', '@subgraph', '@vue-nodes'] },
() => {
test.beforeEach(async ({ comfyPage }) => {
test.setTimeout(30000) // Extend timeout as we need to reload the page an additional time
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.page.reload() // Reload page as we need to enter in Vue mode
await comfyPage.page.reload() // Reload page to ensure Vue mode is active
await comfyPage.page.waitForFunction(() => !!window.app?.graph)
})

View File

@@ -46,10 +46,6 @@ test.describe(
'Subgraph promoted widget panel',
{ tag: ['@node', '@widget'] },
() => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
})
test.describe('SubgraphEditor (Settings panel)', () => {
test('linked promoted widgets have hide toggle disabled', async ({
comfyPage

View File

@@ -16,10 +16,6 @@ async function checkTemplateFileExists(
}
test.describe('Templates', { tag: ['@slow', '@workflow'] }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
})
test('should have a JSON workflow file for each template', async ({
comfyPage
}) => {

View File

@@ -5,7 +5,6 @@ import {
test.describe('Toast Notifications', { tag: '@ui' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.setup()
})

View File

@@ -4,7 +4,6 @@ import { comfyPageFixture as test } from '@e2e/fixtures/ComfyPage'
test.describe('Workflow tabs', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting(
'Comfy.Workflow.WorkflowTabsPosition',
'Topbar'

View File

@@ -37,7 +37,6 @@ test.describe('Version Mismatch Warnings', { tag: '@slow' }, () => {
}
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting(
'Comfy.VersionCompatibility.DisableWarnings',
false

View File

@@ -112,11 +112,9 @@ async function getNodeGroupCenteringErrors(
})
}
test.describe('Vue Node Groups', { tag: '@screenshot' }, () => {
test.describe('Vue Node Groups', { tag: ['@screenshot', '@vue-nodes'] }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.settings.setSetting('Comfy.Minimap.ShowGroups', true)
await comfyPage.vueNodes.waitForNodes()
})
test('should allow creating groups with hotkey', async ({ comfyPage }) => {

View File

@@ -3,12 +3,7 @@ import {
comfyPageFixture as test
} from '@e2e/fixtures/ComfyPage'
test.describe('Vue Nodes Canvas Pan', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.vueNodes.waitForNodes()
})
test.describe('Vue Nodes Canvas Pan', { tag: '@vue-nodes' }, () => {
test(
'@mobile Can pan with touch',
{ tag: '@screenshot' },

View File

@@ -3,9 +3,8 @@ import {
comfyPageFixture as test
} from '@e2e/fixtures/ComfyPage'
test.describe('Vue Nodes Zoom', () => {
test.describe('Vue Nodes Zoom', { tag: '@vue-nodes' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.settings.setSetting('LiteGraph.Canvas.MinFontSizeForLOD', 8)
await comfyPage.vueNodes.waitForNodes()
})

View File

@@ -5,146 +5,151 @@ import {
import type { ComfyPage } from '@e2e/fixtures/ComfyPage'
import { fitToViewInstant } from '@e2e/helpers/fitToView'
test.describe('Vue Node Bring to Front', { tag: '@screenshot' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled')
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.workflow.loadWorkflow('vueNodes/simple-triple')
await comfyPage.vueNodes.waitForNodes()
await fitToViewInstant(comfyPage)
})
test.describe(
'Vue Node Bring to Front',
{ tag: ['@screenshot', '@vue-nodes'] },
() => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled')
await comfyPage.workflow.loadWorkflow('vueNodes/simple-triple')
await comfyPage.vueNodes.waitForNodes()
await fitToViewInstant(comfyPage)
})
/**
* Helper to get the z-index of a node by its title
*/
async function getNodeZIndex(
comfyPage: ComfyPage,
title: string
): Promise<number> {
const node = comfyPage.vueNodes.getNodeByTitle(title)
const style = await node.getAttribute('style')
const match = style?.match(/z-index:\s*(\d+)/)
return match ? parseInt(match[1], 10) : Number.NaN
/**
* Helper to get the z-index of a node by its title
*/
async function getNodeZIndex(
comfyPage: ComfyPage,
title: string
): Promise<number> {
const node = comfyPage.vueNodes.getNodeByTitle(title)
const style = await node.getAttribute('style')
const match = style?.match(/z-index:\s*(\d+)/)
return match ? parseInt(match[1], 10) : Number.NaN
}
/**
* Helper to get the bounding box center of a node
*/
async function getNodeCenter(
comfyPage: ComfyPage,
title: string
): Promise<{ x: number; y: number }> {
const node = comfyPage.vueNodes.getNodeByTitle(title)
const box = await node.boundingBox()
if (!box) throw new Error(`Node "${title}" not found`)
return { x: box.x + box.width / 2, y: box.y + box.height / 2 }
}
test('should bring overlapped node to front when clicking on it', async ({
comfyPage
}) => {
// Get initial positions
const clipCenter = await getNodeCenter(comfyPage, 'CLIP Text Encode')
const ksamplerHeader = await comfyPage.page
.getByText('KSampler')
.boundingBox()
if (!ksamplerHeader) throw new Error('KSampler header not found')
// Drag KSampler on top of CLIP Text Encode
await comfyPage.canvasOps.dragAndDrop(
{ x: ksamplerHeader.x + 50, y: ksamplerHeader.y + 10 },
clipCenter
)
await comfyPage.nextFrame()
// Screenshot showing KSampler on top of CLIP
await expect(comfyPage.canvas).toHaveScreenshot(
'bring-to-front-overlapped-before.png'
)
// KSampler should be on top (higher z-index) after being dragged
await expect
.poll(async () => {
const ksamplerZ = await getNodeZIndex(comfyPage, 'KSampler')
const clipZ = await getNodeZIndex(comfyPage, 'CLIP Text Encode')
return ksamplerZ - clipZ
})
.toBeGreaterThan(0)
// Click on CLIP Text Encode (underneath) - need to click on a visible part
// Since KSampler is on top, we click on the edge of CLIP that should still be visible
const clipNode = comfyPage.vueNodes.getNodeByTitle('CLIP Text Encode')
const clipBox = await clipNode.boundingBox()
if (!clipBox) throw new Error('CLIP node not found')
// Click on a visible edge of CLIP
await comfyPage.page.mouse.click(clipBox.x + 30, clipBox.y + 10)
await comfyPage.nextFrame()
// CLIP should now be on top - compare post-action z-indices
await expect
.poll(async () => {
const clipZ = await getNodeZIndex(comfyPage, 'CLIP Text Encode')
const ksamplerZ = await getNodeZIndex(comfyPage, 'KSampler')
return clipZ - ksamplerZ
})
.toBeGreaterThan(0)
// Screenshot showing CLIP now on top
await expect(comfyPage.canvas).toHaveScreenshot(
'bring-to-front-overlapped-after.png'
)
})
test('should bring overlapped node to front when clicking on its widget', async ({
comfyPage
}) => {
// Get CLIP Text Encode position (it has a text widget)
const clipCenter = await getNodeCenter(comfyPage, 'CLIP Text Encode')
// Get VAE Decode position and drag it on top of CLIP
const vaeHeader = await comfyPage.page
.getByText('VAE Decode')
.boundingBox()
if (!vaeHeader) throw new Error('VAE Decode header not found')
await comfyPage.canvasOps.dragAndDrop(
{ x: vaeHeader.x + 50, y: vaeHeader.y + 10 },
{ x: clipCenter.x - 50, y: clipCenter.y }
)
await comfyPage.nextFrame()
// VAE should be on top after drag
await expect
.poll(async () => {
const vaeZ = await getNodeZIndex(comfyPage, 'VAE Decode')
const clipZ = await getNodeZIndex(comfyPage, 'CLIP Text Encode')
return vaeZ - clipZ
})
.toBeGreaterThan(0)
// Screenshot showing VAE on top
await expect(comfyPage.canvas).toHaveScreenshot(
'bring-to-front-widget-overlapped-before.png'
)
// Click on the text widget of CLIP Text Encode
const clipNode = comfyPage.vueNodes.getNodeByTitle('CLIP Text Encode')
const clipBox = await clipNode.boundingBox()
if (!clipBox) throw new Error('CLIP node not found')
await comfyPage.page.mouse.click(clipBox.x + 170, clipBox.y + 80)
await comfyPage.nextFrame()
// CLIP should now be on top - compare post-action z-indices
await expect
.poll(async () => {
const clipZ = await getNodeZIndex(comfyPage, 'CLIP Text Encode')
const vaeZ = await getNodeZIndex(comfyPage, 'VAE Decode')
return clipZ - vaeZ
})
.toBeGreaterThan(0)
// Screenshot showing CLIP now on top after widget click
await expect(comfyPage.canvas).toHaveScreenshot(
'bring-to-front-widget-overlapped-after.png'
)
})
}
/**
* Helper to get the bounding box center of a node
*/
async function getNodeCenter(
comfyPage: ComfyPage,
title: string
): Promise<{ x: number; y: number }> {
const node = comfyPage.vueNodes.getNodeByTitle(title)
const box = await node.boundingBox()
if (!box) throw new Error(`Node "${title}" not found`)
return { x: box.x + box.width / 2, y: box.y + box.height / 2 }
}
test('should bring overlapped node to front when clicking on it', async ({
comfyPage
}) => {
// Get initial positions
const clipCenter = await getNodeCenter(comfyPage, 'CLIP Text Encode')
const ksamplerHeader = await comfyPage.page
.getByText('KSampler')
.boundingBox()
if (!ksamplerHeader) throw new Error('KSampler header not found')
// Drag KSampler on top of CLIP Text Encode
await comfyPage.canvasOps.dragAndDrop(
{ x: ksamplerHeader.x + 50, y: ksamplerHeader.y + 10 },
clipCenter
)
await comfyPage.nextFrame()
// Screenshot showing KSampler on top of CLIP
await expect(comfyPage.canvas).toHaveScreenshot(
'bring-to-front-overlapped-before.png'
)
// KSampler should be on top (higher z-index) after being dragged
await expect
.poll(async () => {
const ksamplerZ = await getNodeZIndex(comfyPage, 'KSampler')
const clipZ = await getNodeZIndex(comfyPage, 'CLIP Text Encode')
return ksamplerZ - clipZ
})
.toBeGreaterThan(0)
// Click on CLIP Text Encode (underneath) - need to click on a visible part
// Since KSampler is on top, we click on the edge of CLIP that should still be visible
const clipNode = comfyPage.vueNodes.getNodeByTitle('CLIP Text Encode')
const clipBox = await clipNode.boundingBox()
if (!clipBox) throw new Error('CLIP node not found')
// Click on a visible edge of CLIP
await comfyPage.page.mouse.click(clipBox.x + 30, clipBox.y + 10)
await comfyPage.nextFrame()
// CLIP should now be on top - compare post-action z-indices
await expect
.poll(async () => {
const clipZ = await getNodeZIndex(comfyPage, 'CLIP Text Encode')
const ksamplerZ = await getNodeZIndex(comfyPage, 'KSampler')
return clipZ - ksamplerZ
})
.toBeGreaterThan(0)
// Screenshot showing CLIP now on top
await expect(comfyPage.canvas).toHaveScreenshot(
'bring-to-front-overlapped-after.png'
)
})
test('should bring overlapped node to front when clicking on its widget', async ({
comfyPage
}) => {
// Get CLIP Text Encode position (it has a text widget)
const clipCenter = await getNodeCenter(comfyPage, 'CLIP Text Encode')
// Get VAE Decode position and drag it on top of CLIP
const vaeHeader = await comfyPage.page.getByText('VAE Decode').boundingBox()
if (!vaeHeader) throw new Error('VAE Decode header not found')
await comfyPage.canvasOps.dragAndDrop(
{ x: vaeHeader.x + 50, y: vaeHeader.y + 10 },
{ x: clipCenter.x - 50, y: clipCenter.y }
)
await comfyPage.nextFrame()
// VAE should be on top after drag
await expect
.poll(async () => {
const vaeZ = await getNodeZIndex(comfyPage, 'VAE Decode')
const clipZ = await getNodeZIndex(comfyPage, 'CLIP Text Encode')
return vaeZ - clipZ
})
.toBeGreaterThan(0)
// Screenshot showing VAE on top
await expect(comfyPage.canvas).toHaveScreenshot(
'bring-to-front-widget-overlapped-before.png'
)
// Click on the text widget of CLIP Text Encode
const clipNode = comfyPage.vueNodes.getNodeByTitle('CLIP Text Encode')
const clipBox = await clipNode.boundingBox()
if (!clipBox) throw new Error('CLIP node not found')
await comfyPage.page.mouse.click(clipBox.x + 170, clipBox.y + 80)
await comfyPage.nextFrame()
// CLIP should now be on top - compare post-action z-indices
await expect
.poll(async () => {
const clipZ = await getNodeZIndex(comfyPage, 'CLIP Text Encode')
const vaeZ = await getNodeZIndex(comfyPage, 'VAE Decode')
return clipZ - vaeZ
})
.toBeGreaterThan(0)
// Screenshot showing CLIP now on top after widget click
await expect(comfyPage.canvas).toHaveScreenshot(
'bring-to-front-widget-overlapped-after.png'
)
})
})
)

View File

@@ -60,13 +60,7 @@ async function getNodeRef(comfyPage: ComfyPage, nodeTitle: string) {
return refs[0]
}
test.describe('Vue Node Context Menu', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.vueNodes.waitForNodes()
})
test.describe('Vue Node Context Menu', { tag: '@vue-nodes' }, () => {
test.describe('Single Node Actions', () => {
test('should rename node via context menu', async ({ comfyPage }) => {
await openContextMenu(comfyPage, 'KSampler')

View File

@@ -7,11 +7,7 @@ import {
getPromotedWidgetCountByName
} from '@e2e/helpers/promotedWidgets'
test.describe('Vue Nodes Image Preview', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
})
test.describe('Vue Nodes Image Preview', { tag: '@vue-nodes' }, () => {
async function loadImageOnNode(comfyPage: ComfyPage) {
await comfyPage.workflow.loadWorkflow('widgets/load_image_widget')
await comfyPage.vueNodes.waitForNodes()

View File

@@ -5,12 +5,7 @@ import {
import type { ComfyPage } from '@e2e/fixtures/ComfyPage'
import type { Position } from '@e2e/fixtures/types'
test.describe('Vue Node Moving', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.vueNodes.waitForNodes()
})
test.describe('Vue Node Moving', { tag: '@vue-nodes' }, () => {
const getHeaderPos = async (
comfyPage: ComfyPage,
title: string

View File

@@ -6,146 +6,152 @@ test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled')
})
test.describe('Vue Nodes - Delete Key Interaction', () => {
test.beforeEach(async ({ comfyPage }) => {
// Enable Vue nodes rendering
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.settings.setSetting('Comfy.Graph.CanvasMenu', false)
await comfyPage.setup()
})
test.describe(
'Vue Nodes - Delete Key Interaction',
{ tag: '@vue-nodes' },
() => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.Graph.CanvasMenu', false)
await comfyPage.setup()
})
test('Can select all and delete Vue nodes with Delete key', async ({
comfyPage
}) => {
await comfyPage.vueNodes.waitForNodes()
test('Can select all and delete Vue nodes with Delete key', async ({
comfyPage
}) => {
await comfyPage.vueNodes.waitForNodes()
// Get initial Vue node count
await expect
.poll(() => comfyPage.vueNodes.getNodeCount())
.toBeGreaterThan(0)
const initialNodeCount = await comfyPage.vueNodes.getNodeCount()
// Get initial Vue node count
await expect
.poll(() => comfyPage.vueNodes.getNodeCount())
.toBeGreaterThan(0)
const initialNodeCount = await comfyPage.vueNodes.getNodeCount()
// Select all Vue nodes
await comfyPage.keyboard.selectAll()
// Select all Vue nodes
await comfyPage.keyboard.selectAll()
// Verify all Vue nodes are selected
await expect(comfyPage.vueNodes.selectedNodes).toHaveCount(initialNodeCount)
// Verify all Vue nodes are selected
await expect(comfyPage.vueNodes.selectedNodes).toHaveCount(
initialNodeCount
)
// Delete with Delete key
await comfyPage.vueNodes.deleteSelected()
// Delete with Delete key
await comfyPage.vueNodes.deleteSelected()
// Verify all Vue nodes were deleted
await expect.poll(() => comfyPage.vueNodes.getNodeCount()).toBe(0)
})
// Verify all Vue nodes were deleted
await expect.poll(() => comfyPage.vueNodes.getNodeCount()).toBe(0)
})
test('Can select specific Vue node and delete it', async ({ comfyPage }) => {
await comfyPage.vueNodes.waitForNodes()
test('Can select specific Vue node and delete it', async ({
comfyPage
}) => {
await comfyPage.vueNodes.waitForNodes()
// Get initial Vue node count
await expect
.poll(() => comfyPage.vueNodes.getNodeCount())
.toBeGreaterThan(0)
const initialNodeCount = await comfyPage.vueNodes.getNodeCount()
// Get initial Vue node count
await expect
.poll(() => comfyPage.vueNodes.getNodeCount())
.toBeGreaterThan(0)
const initialNodeCount = await comfyPage.vueNodes.getNodeCount()
// Get first Vue node ID and select it
const nodeIds = await comfyPage.vueNodes.getNodeIds()
await comfyPage.vueNodes.selectNode(nodeIds[0])
// Get first Vue node ID and select it
const nodeIds = await comfyPage.vueNodes.getNodeIds()
await comfyPage.vueNodes.selectNode(nodeIds[0])
// Verify selection
await expect(comfyPage.vueNodes.selectedNodes).toHaveCount(1)
// Verify selection
await expect(comfyPage.vueNodes.selectedNodes).toHaveCount(1)
// Delete with Delete key
await comfyPage.vueNodes.deleteSelected()
// Delete with Delete key
await comfyPage.vueNodes.deleteSelected()
// Verify one Vue node was deleted
await expect
.poll(() => comfyPage.vueNodes.getNodeCount())
.toBe(initialNodeCount - 1)
})
// Verify one Vue node was deleted
await expect
.poll(() => comfyPage.vueNodes.getNodeCount())
.toBe(initialNodeCount - 1)
})
test('Can select and delete Vue node with Backspace key', async ({
comfyPage
}) => {
await comfyPage.vueNodes.waitForNodes()
test('Can select and delete Vue node with Backspace key', async ({
comfyPage
}) => {
await comfyPage.vueNodes.waitForNodes()
const initialNodeCount = await comfyPage.vueNodes.getNodeCount()
const initialNodeCount = await comfyPage.vueNodes.getNodeCount()
// Select first Vue node
const nodeIds = await comfyPage.vueNodes.getNodeIds()
await comfyPage.vueNodes.selectNode(nodeIds[0])
// Select first Vue node
const nodeIds = await comfyPage.vueNodes.getNodeIds()
await comfyPage.vueNodes.selectNode(nodeIds[0])
// Delete with Backspace key instead of Delete
await comfyPage.vueNodes.deleteSelectedWithBackspace()
// Delete with Backspace key instead of Delete
await comfyPage.vueNodes.deleteSelectedWithBackspace()
// Verify Vue node was deleted
await expect
.poll(() => comfyPage.vueNodes.getNodeCount())
.toBe(initialNodeCount - 1)
})
// Verify Vue node was deleted
await expect
.poll(() => comfyPage.vueNodes.getNodeCount())
.toBe(initialNodeCount - 1)
})
test('Delete key does not delete node when typing in Vue node widgets', async ({
comfyPage
}) => {
const initialNodeCount = await comfyPage.nodeOps.getGraphNodesCount()
test('Delete key does not delete node when typing in Vue node widgets', async ({
comfyPage
}) => {
const initialNodeCount = await comfyPage.nodeOps.getGraphNodesCount()
// Find a text input widget in a Vue node
const textWidget = comfyPage.page
.locator('input[type="text"], textarea')
.first()
// Find a text input widget in a Vue node
const textWidget = comfyPage.page
.locator('input[type="text"], textarea')
.first()
// Click on text widget to focus it
await textWidget.click()
await textWidget.fill('test text')
// Click on text widget to focus it
await textWidget.click()
await textWidget.fill('test text')
// Press Delete while focused on widget - should delete text, not node
await textWidget.press('Delete')
// Press Delete while focused on widget - should delete text, not node
await textWidget.press('Delete')
// Node count should remain the same
await expect
.poll(() => comfyPage.nodeOps.getGraphNodesCount())
.toBe(initialNodeCount)
})
// Node count should remain the same
await expect
.poll(() => comfyPage.nodeOps.getGraphNodesCount())
.toBe(initialNodeCount)
})
test('Delete key does not delete node when nothing is selected', async ({
comfyPage
}) => {
await comfyPage.vueNodes.waitForNodes()
test('Delete key does not delete node when nothing is selected', async ({
comfyPage
}) => {
await comfyPage.vueNodes.waitForNodes()
// Ensure no Vue nodes are selected
await comfyPage.vueNodes.clearSelection()
await expect(comfyPage.vueNodes.selectedNodes).toHaveCount(0)
// Ensure no Vue nodes are selected
await comfyPage.vueNodes.clearSelection()
await expect(comfyPage.vueNodes.selectedNodes).toHaveCount(0)
// Press Delete key - should not crash and should handle gracefully
await comfyPage.page.keyboard.press('Delete')
// Press Delete key - should not crash and should handle gracefully
await comfyPage.page.keyboard.press('Delete')
// Vue node count should remain the same
await expect
.poll(() => comfyPage.vueNodes.getNodeCount())
.toBeGreaterThan(0)
})
// Vue node count should remain the same
await expect
.poll(() => comfyPage.vueNodes.getNodeCount())
.toBeGreaterThan(0)
})
test('Can multi-select with Ctrl+click and delete multiple Vue nodes', async ({
comfyPage
}) => {
await comfyPage.vueNodes.waitForNodes()
const initialNodeCount = await comfyPage.vueNodes.getNodeCount()
test('Can multi-select with Ctrl+click and delete multiple Vue nodes', async ({
comfyPage
}) => {
await comfyPage.vueNodes.waitForNodes()
const initialNodeCount = await comfyPage.vueNodes.getNodeCount()
// Multi-select first two Vue nodes using Ctrl+click
const nodeIds = await comfyPage.vueNodes.getNodeIds()
const nodesToSelect = nodeIds.slice(0, 2)
await comfyPage.vueNodes.selectNodes(nodesToSelect)
// Multi-select first two Vue nodes using Ctrl+click
const nodeIds = await comfyPage.vueNodes.getNodeIds()
const nodesToSelect = nodeIds.slice(0, 2)
await comfyPage.vueNodes.selectNodes(nodesToSelect)
// Verify expected nodes are selected
await expect(comfyPage.vueNodes.selectedNodes).toHaveCount(
nodesToSelect.length
)
// Verify expected nodes are selected
await expect(comfyPage.vueNodes.selectedNodes).toHaveCount(
nodesToSelect.length
)
// Delete selected Vue nodes
await comfyPage.vueNodes.deleteSelected()
// Delete selected Vue nodes
await comfyPage.vueNodes.deleteSelected()
// Verify expected nodes were deleted
await expect
.poll(() => comfyPage.vueNodes.getNodeCount())
.toBe(initialNodeCount - nodesToSelect.length)
})
})
// Verify expected nodes were deleted
await expect
.poll(() => comfyPage.vueNodes.getNodeCount())
.toBe(initialNodeCount - nodesToSelect.length)
})
}
)

View File

@@ -4,10 +4,9 @@ import {
} from '@e2e/fixtures/ComfyPage'
import { TestIds } from '@e2e/fixtures/selectors'
test.describe('Vue Nodes Renaming', () => {
test.describe('Vue Nodes Renaming', { tag: '@vue-nodes' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.Graph.CanvasMenu', false)
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.setup()
await comfyPage.vueNodes.waitForNodes()
})

View File

@@ -3,12 +3,7 @@ import {
comfyPageFixture as test
} from '@e2e/fixtures/ComfyPage'
test.describe('Vue Node Resizing', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.vueNodes.waitForNodes()
})
test.describe('Vue Node Resizing', { tag: '@vue-nodes' }, () => {
test('should resize node without position drift after selecting', async ({
comfyPage
}) => {

View File

@@ -7,12 +7,7 @@ test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled')
})
test.describe('Vue Node Selection', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.vueNodes.waitForNodes()
})
test.describe('Vue Node Selection', { tag: '@vue-nodes' }, () => {
const modifiers = [
{ key: 'Control', name: 'ctrl' },
{ key: 'Shift', name: 'shift' },

View File

@@ -6,13 +6,10 @@ import {
const BYPASS_HOTKEY = 'Control+b'
const BYPASS_CLASS = /before:bg-bypass\/60/
test.describe('Vue Node Bypass', () => {
test.describe('Vue Node Bypass', { tag: '@vue-nodes' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting('Comfy.Minimap.Visible', false)
await comfyPage.settings.setSetting('Comfy.Graph.CanvasMenu', true)
await comfyPage.vueNodes.waitForNodes()
})
test(

View File

@@ -3,11 +3,10 @@ import {
comfyPageFixture as test
} from '@e2e/fixtures/ComfyPage'
test.describe('Vue Node Collapse', () => {
test.describe('Vue Node Collapse', { tag: '@vue-nodes' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.Graph.CanvasMenu', false)
await comfyPage.settings.setSetting('Comfy.EnableTooltips', true)
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.setup()
await comfyPage.vueNodes.waitForNodes()
})

View File

@@ -4,55 +4,58 @@ import {
} from '@e2e/fixtures/ComfyPage'
import { TestIds } from '@e2e/fixtures/selectors'
test.describe('Vue Node Custom Colors', { tag: '@screenshot' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting('Comfy.Canvas.SelectionToolbox', true)
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.vueNodes.waitForNodes()
})
test('displays color picker button and allows color selection', async ({
comfyPage
}) => {
const loadCheckpointNode = comfyPage.page.locator('[data-node-id]').filter({
hasText: 'Load Checkpoint'
test.describe(
'Vue Node Custom Colors',
{ tag: ['@screenshot', '@vue-nodes'] },
() => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.Canvas.SelectionToolbox', true)
})
await loadCheckpointNode.getByText('Load Checkpoint').click()
const colorPickerButton = comfyPage.page.getByTestId(
TestIds.selectionToolbox.colorPickerButton
)
await colorPickerButton.click()
test('displays color picker button and allows color selection', async ({
comfyPage
}) => {
const loadCheckpointNode = comfyPage.page
.locator('[data-node-id]')
.filter({
hasText: 'Load Checkpoint'
})
await loadCheckpointNode.getByText('Load Checkpoint').click()
const colorPickerGroup = comfyPage.page.getByRole('group').filter({
has: comfyPage.page.getByTestId(TestIds.selectionToolbox.colorBlue)
const colorPickerButton = comfyPage.page.getByTestId(
TestIds.selectionToolbox.colorPickerButton
)
await colorPickerButton.click()
const colorPickerGroup = comfyPage.page.getByRole('group').filter({
has: comfyPage.page.getByTestId(TestIds.selectionToolbox.colorBlue)
})
await colorPickerGroup
.getByTestId(TestIds.selectionToolbox.colorBlue)
.click()
await expect(loadCheckpointNode).toHaveScreenshot(
'vue-node-custom-color-blue.png'
)
})
await colorPickerGroup
.getByTestId(TestIds.selectionToolbox.colorBlue)
.click()
await expect(loadCheckpointNode).toHaveScreenshot(
'vue-node-custom-color-blue.png'
)
})
test('should load node colors from workflow', async ({ comfyPage }) => {
await comfyPage.workflow.loadWorkflow('nodes/every_node_color')
await comfyPage.vueNodes.waitForNodes()
await expect(comfyPage.canvas).toHaveScreenshot(
'vue-node-custom-colors-dark-all-colors.png'
)
})
test('should load node colors from workflow', async ({ comfyPage }) => {
await comfyPage.workflow.loadWorkflow('nodes/every_node_color')
await comfyPage.vueNodes.waitForNodes()
await expect(comfyPage.canvas).toHaveScreenshot(
'vue-node-custom-colors-dark-all-colors.png'
)
})
test('should show brightened node colors on light theme', async ({
comfyPage
}) => {
await comfyPage.settings.setSetting('Comfy.ColorPalette', 'light')
await comfyPage.workflow.loadWorkflow('nodes/every_node_color')
await comfyPage.vueNodes.waitForNodes()
await expect(comfyPage.canvas).toHaveScreenshot(
'vue-node-custom-colors-light-all-colors.png'
)
})
})
test('should show brightened node colors on light theme', async ({
comfyPage
}) => {
await comfyPage.settings.setSetting('Comfy.ColorPalette', 'light')
await comfyPage.workflow.loadWorkflow('nodes/every_node_color')
await comfyPage.vueNodes.waitForNodes()
await expect(comfyPage.canvas).toHaveScreenshot(
'vue-node-custom-colors-light-all-colors.png'
)
})
}
)

View File

@@ -5,12 +5,7 @@ import {
const ERROR_CLASS = /ring-destructive-background/
test.describe('Vue Node Error', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.vueNodes.waitForNodes()
})
test.describe('Vue Node Error', { tag: '@vue-nodes' }, () => {
test('should display error state when node is missing (node from workflow is not installed)', async ({
comfyPage
}) => {

View File

@@ -6,12 +6,7 @@ import {
const MUTE_HOTKEY = 'Control+m'
const MUTE_OPACITY = '0.5'
test.describe('Vue Node Mute', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.vueNodes.waitForNodes()
})
test.describe('Vue Node Mute', { tag: '@vue-nodes' }, () => {
test(
'should allow toggling mute on a selected node with hotkey',
{ tag: '@screenshot' },

View File

@@ -6,12 +6,7 @@ import {
const PIN_HOTKEY = 'p'
const PIN_INDICATOR = '[data-testid="node-pin-indicator"]'
test.describe('Vue Node Pin', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.vueNodes.waitForNodes()
})
test.describe('Vue Node Pin', { tag: '@vue-nodes' }, () => {
test('should allow toggling pin on a selected node with hotkey', async ({
comfyPage
}) => {

View File

@@ -3,9 +3,8 @@ import {
comfyPageFixture as test
} from '@e2e/fixtures/ComfyPage'
test.describe('Vue Reroute Node Size', () => {
test.describe('Vue Reroute Node Size', { tag: '@vue-nodes' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.settings.setSetting('Comfy.Minimap.Visible', false)
await comfyPage.workflow.loadWorkflow('links/single_connected_reroute_node')
await comfyPage.vueNodes.waitForNodes()

View File

@@ -3,9 +3,8 @@ import {
comfyPageFixture as test
} from '@e2e/fixtures/ComfyPage'
test.describe('Advanced Widget Visibility', () => {
test.describe('Advanced Widget Visibility', { tag: '@vue-nodes' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.settings.setSetting(
'Comfy.Node.AlwaysShowAdvancedWidgets',
false

View File

@@ -6,11 +6,7 @@ import type { ComfyPage } from '@e2e/fixtures/ComfyPage'
type CropValue = { x: number; y: number; width: number; height: number } | null
test.describe('Image Crop', { tag: '@widget' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
})
test.describe('Image Crop', { tag: ['@widget', '@vue-nodes'] }, () => {
test.describe('without source image', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.workflow.loadWorkflow('widgets/image_crop_widget')

View File

@@ -3,9 +3,8 @@ import {
comfyPageFixture as test
} from '@e2e/fixtures/ComfyPage'
test.describe('Vue Integer Widget', () => {
test.describe('Vue Integer Widget', { tag: '@vue-nodes' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.setup()
})

View File

@@ -4,12 +4,7 @@ import {
} from '@e2e/fixtures/ComfyPage'
import { TestIds } from '@e2e/fixtures/selectors'
test.describe('Vue Upload Widgets', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.vueNodes.waitForNodes()
})
test.describe('Vue Upload Widgets', { tag: '@vue-nodes' }, () => {
test('should hide canvas-only upload buttons', async ({ comfyPage }) => {
await comfyPage.setup()
await comfyPage.workflow.loadWorkflow('widgets/all_load_widgets')

View File

@@ -4,12 +4,7 @@ import {
} from '@e2e/fixtures/ComfyPage'
import type { ComfyPage } from '@e2e/fixtures/ComfyPage'
test.describe('Vue Multiline String Widget', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.vueNodes.waitForNodes()
})
test.describe('Vue Multiline String Widget', { tag: '@vue-nodes' }, () => {
const getFirstClipNode = (comfyPage: ComfyPage) =>
comfyPage.vueNodes.getNodeByTitle('CLIP Text Encode (Prompt)').first()

View File

@@ -4,12 +4,7 @@ import {
} from '@e2e/fixtures/ComfyPage'
import type { TestGraphAccess } from '@e2e/types/globals'
test.describe('Vue Widget Reactivity', () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.vueNodes.waitForNodes()
})
test.describe('Vue Widget Reactivity', { tag: '@vue-nodes' }, () => {
test('Should display added widgets', async ({ comfyPage }) => {
const loadCheckpointNode = comfyPage.page.locator(
'css=[data-testid="node-body-4"] > .lg-node-widgets > div'

View File

@@ -3,10 +3,8 @@ import {
comfyPageFixture as test
} from '@e2e/fixtures/ComfyPage'
test.describe('Widget copy button', { tag: '@ui' }, () => {
test.describe('Widget copy button', { tag: ['@ui', '@vue-nodes'] }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
await comfyPage.setup()
// Add a PreviewAny node which has a read-only textarea with a copy button

View File

@@ -5,7 +5,6 @@ import type { ComfyPage } from '@e2e/fixtures/ComfyPage'
test.describe('Workflow Tab Thumbnails', { tag: '@workflow' }, () => {
test.beforeEach(async ({ comfyPage }) => {
await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top')
await comfyPage.settings.setSetting(
'Comfy.Workflow.WorkflowTabsPosition',
'Topbar'