diff --git a/browser_tests/fixtures/ComfyPage.ts b/browser_tests/fixtures/ComfyPage.ts index 06d37d22b4..0d83d20f2f 100644 --- a/browser_tests/fixtures/ComfyPage.ts +++ b/browser_tests/fixtures/ComfyPage.ts @@ -28,7 +28,6 @@ import { NodeOperationsHelper } from './helpers/NodeOperationsHelper' import { SettingsHelper } from './helpers/SettingsHelper' import { SubgraphHelper } from './helpers/SubgraphHelper' import { WorkflowHelper } from './helpers/WorkflowHelper' -import type { FolderStructure } from './helpers/WorkflowHelper' import type { Position } from './types' import type { NodeReference } from './utils/litegraphUtils' @@ -228,14 +227,6 @@ export class ComfyPage { this.contextMenu = new ContextMenu(page) } - convertLeafToContent(structure: FolderStructure): FolderStructure { - return this.workflow.convertLeafToContent(structure) - } - - async setupWorkflowsDirectory(structure: FolderStructure) { - return this.workflow.setupWorkflowsDirectory(structure) - } - async setupUser(username: string) { const res = await this.request.get(`${this.url}/api/users`) if (res.status() !== 200) @@ -384,14 +375,6 @@ export class ComfyPage { ) } - async setSetting(settingId: string, settingValue: unknown): Promise { - return this.settings.setSetting(settingId, settingValue) - } - - async getSetting(settingId: string): Promise { - return this.settings.getSetting(settingId) - } - async goto() { await this.page.goto(this.url) } @@ -406,17 +389,6 @@ export class ComfyPage { return new Promise((resolve) => setTimeout(resolve, ms)) } - async loadWorkflow(workflowName: string) { - return this.workflow.loadWorkflow(workflowName) - } - - async deleteWorkflow( - workflowName: string, - whenMissing: 'ignoreMissing' | 'throwIfMissing' = 'ignoreMissing' - ) { - return this.workflow.deleteWorkflow(workflowName, whenMissing) - } - /** * Attach a screenshot to the test report. * By default, screenshots are only taken in non-CI environments. @@ -475,52 +447,6 @@ export class ComfyPage { .catch(() => {}) } - /** - * @deprecated Use NodeReference pattern instead: - * ``` - * const node = await comfyPage.nodeOps.getNodeRefByTitle('CLIP Text Encode (Prompt)'); - * await node.click(); - * ``` - */ - async clickTextEncodeNode1() { - await this.canvas.click({ - position: DefaultGraphPositions.textEncodeNode1 - }) - await this.nextFrame() - } - - /** - * @deprecated Use NodeReference pattern instead: - * ``` - * const node = await comfyPage.nodeOps.getNodeRefByTitle('CLIP Text Encode (Prompt)'); - * await node.clickToggler(); - * ``` - */ - async clickTextEncodeNodeToggler() { - await this.canvas.click({ - position: DefaultGraphPositions.textEncodeNodeToggler - }) - await this.nextFrame() - } - - /** - * @deprecated Use NodeReference pattern instead: - * ``` - * const node = await comfyPage.nodeOps.getNodeRefByTitle('CLIP Text Encode (Prompt)'); - * await node.click(); - * ``` - */ - async clickTextEncodeNode2() { - await this.canvas.click({ - position: DefaultGraphPositions.textEncodeNode2 - }) - await this.nextFrame() - } - - async clickEmptySpace() { - return this.canvasOps.clickEmptySpace(DefaultGraphPositions.emptySpaceClick) - } - async dragAndDropExternalResource( options: { fileName?: string @@ -669,28 +595,6 @@ export class ComfyPage { await this.nextFrame() } - // Default graph positions - get clipTextEncodeNode1InputSlot(): Position { - return DefaultGraphPositions.clipTextEncodeNode1InputSlot - } - - get clipTextEncodeNode2InputSlot(): Position { - return DefaultGraphPositions.clipTextEncodeNode2InputSlot - } - - // A point on input edge. - get clipTextEncodeNode2InputLinkPath(): Position { - return DefaultGraphPositions.clipTextEncodeNode2InputLinkPath - } - - get loadCheckpointNodeClipOutputSlot(): Position { - return DefaultGraphPositions.loadCheckpointNodeClipOutputSlot - } - - get emptySpace(): Position { - return DefaultGraphPositions.emptySpace - } - get promptDialogInput() { return this.page.locator('.p-dialog-content input[type="text"]') } @@ -704,8 +608,8 @@ export class ComfyPage { async disconnectEdge() { await this.canvasOps.dragAndDrop( - this.clipTextEncodeNode1InputSlot, - this.emptySpace + DefaultGraphPositions.clipTextEncodeNode1InputSlot, + DefaultGraphPositions.emptySpace ) } @@ -716,11 +620,11 @@ export class ComfyPage { ) { const { reverse = false } = options const start = reverse - ? this.clipTextEncodeNode1InputSlot - : this.loadCheckpointNodeClipOutputSlot + ? DefaultGraphPositions.clipTextEncodeNode1InputSlot + : DefaultGraphPositions.loadCheckpointNodeClipOutputSlot const end = reverse - ? this.loadCheckpointNodeClipOutputSlot - : this.clipTextEncodeNode1InputSlot + ? DefaultGraphPositions.loadCheckpointNodeClipOutputSlot + : DefaultGraphPositions.clipTextEncodeNode1InputSlot await this.canvasOps.dragAndDrop(start, end) } @@ -738,155 +642,11 @@ export class ComfyPage { await this.nextFrame() } - /** - * @deprecated Use `comfyPage.contextMenu.clickMenuItem(name)` instead. - */ - async clickContextMenuItem(name: string): Promise { - await this.contextMenu.clickMenuItem(name) - await this.nextFrame() - } - - /** - * @deprecated Use `comfyPage.contextMenu.clickLitegraphMenuItem(name)` instead. - * Clicks on a litegraph context menu item (uses .litemenu-entry selector). - * Use this for canvas/node context menus, not PrimeVue menus. - */ - async clickLitegraphContextMenuItem(name: string): Promise { - await this.contextMenu.clickLitegraphMenuItem(name) - await this.nextFrame() - } - - /** - * @deprecated Use NodeReference pattern instead: - * ``` - * const node = await comfyPage.nodeOps.getNodeRefByTitle('Empty Latent Image'); - * await node.click(); - * ``` - */ - async clickEmptyLatentNode() { - await this.canvas.click({ - position: { - x: 724, - y: 625 - } - }) - await this.page.mouse.move(10, 10) - await this.nextFrame() - } - - /** - * @deprecated Use NodeReference pattern instead: - * ``` - * const node = await comfyPage.nodeOps.getNodeRefByTitle('Empty Latent Image'); - * await node.rightClick(); - * ``` - */ - async rightClickEmptyLatentNode() { - await this.canvas.click({ - position: { - x: 724, - y: 645 - }, - button: 'right' - }) - await this.page.mouse.move(10, 10) - await this.nextFrame() - } - - async ctrlSend(keyToPress: string, locator: Locator | null = this.canvas) { - await this.keyboard.ctrlSend(keyToPress, locator) - } - - async ctrlA(locator?: Locator | null) { - await this.keyboard.selectAll(locator) - } - - async ctrlB(locator?: Locator | null) { - await this.keyboard.bypass(locator) - } - - async ctrlC(locator?: Locator | null) { - await this.clipboard.copy(locator) - } - - async ctrlV(locator?: Locator | null) { - await this.clipboard.paste(locator) - } - - async ctrlZ(locator?: Locator | null) { - await this.keyboard.undo(locator) - } - - async ctrlY(locator?: Locator | null) { - await this.keyboard.redo(locator) - } - - async ctrlArrowUp(locator?: Locator | null) { - await this.keyboard.moveUp(locator) - } - - async ctrlArrowDown(locator?: Locator | null) { - await this.keyboard.moveDown(locator) - } - async closeMenu() { await this.page.click('button.comfy-close-menu-btn') await this.nextFrame() } - /** - * @deprecated Use dialog-specific close methods instead (e.g., settingDialog.close()) - */ - async closeDialog() { - await this.page - .locator('.p-dialog') - .getByRole('button', { name: 'Close' }) - .click({ force: true }) - await this.page.locator('.p-dialog').waitFor({ state: 'hidden' }) - } - - async resizeKsamplerNode( - percentX: number, - percentY: number, - revertAfter: boolean = false - ) { - return this.nodeOps.resizeNode( - DefaultGraphPositions.ksampler.pos, - DefaultGraphPositions.ksampler.size, - percentX, - percentY, - revertAfter - ) - } - - async resizeLoadCheckpointNode( - percentX: number, - percentY: number, - revertAfter: boolean = false - ) { - return this.nodeOps.resizeNode( - DefaultGraphPositions.loadCheckpoint.pos, - DefaultGraphPositions.loadCheckpoint.size, - percentX, - percentY, - revertAfter - ) - } - - async resizeEmptyLatentNode( - percentX: number, - percentY: number, - revertAfter: boolean = false - ) { - return this.nodeOps.resizeNode( - DefaultGraphPositions.emptyLatent.pos, - DefaultGraphPositions.emptyLatent.size, - percentX, - percentY, - revertAfter - ) - } - async clickDialogButton(prompt: string, buttonText: string = 'Yes') { const modal = this.page.locator( `.comfy-modal-content:has-text("${prompt}")` diff --git a/browser_tests/fixtures/helpers/WorkflowHelper.ts b/browser_tests/fixtures/helpers/WorkflowHelper.ts index 440ed1c97d..82f8ec15e8 100644 --- a/browser_tests/fixtures/helpers/WorkflowHelper.ts +++ b/browser_tests/fixtures/helpers/WorkflowHelper.ts @@ -72,7 +72,8 @@ export class WorkflowHelper { // Delete workflow await workflowsTab.getPersistedItem(workflowName).click({ button: 'right' }) - await this.comfyPage.clickContextMenuItem('Delete') + await this.comfyPage.contextMenu.clickMenuItem('Delete') + await this.comfyPage.nextFrame() await this.comfyPage.confirmDialog.delete.click() // Clear toast & close tab diff --git a/browser_tests/fixtures/utils/litegraphUtils.ts b/browser_tests/fixtures/utils/litegraphUtils.ts index 8106fb5101..42c547629e 100644 --- a/browser_tests/fixtures/utils/litegraphUtils.ts +++ b/browser_tests/fixtures/utils/litegraphUtils.ts @@ -380,7 +380,7 @@ export class NodeReference { } async copy() { await this.click('title') - await this.comfyPage.ctrlC() + await this.comfyPage.clipboard.copy() await this.comfyPage.nextFrame() } async connectWidget( diff --git a/browser_tests/tests/actionbar.spec.ts b/browser_tests/tests/actionbar.spec.ts index 1a18577d72..80bc351763 100644 --- a/browser_tests/tests/actionbar.spec.ts +++ b/browser_tests/tests/actionbar.spec.ts @@ -9,7 +9,7 @@ const test = mergeTests(comfyPageFixture, webSocketFixture) test.describe('Actionbar', { tag: '@ui' }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') }) /** diff --git a/browser_tests/tests/backgroundImageUpload.spec.ts b/browser_tests/tests/backgroundImageUpload.spec.ts index da93b01fe2..0f49787b21 100644 --- a/browser_tests/tests/backgroundImageUpload.spec.ts +++ b/browser_tests/tests/backgroundImageUpload.spec.ts @@ -3,18 +3,18 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Background Image Upload', () => { test.beforeEach(async ({ comfyPage }) => { // Reset the background image setting before each test - await comfyPage.setSetting('Comfy.Canvas.BackgroundImage', '') + await comfyPage.settings.setSetting('Comfy.Canvas.BackgroundImage', '') }) test.afterEach(async ({ comfyPage }) => { // Clean up background image setting after each test - await comfyPage.setSetting('Comfy.Canvas.BackgroundImage', '') + await comfyPage.settings.setSetting('Comfy.Canvas.BackgroundImage', '') }) test('should show background image upload component in settings', async ({ @@ -88,7 +88,7 @@ test.describe('Background Image Upload', () => { await expect(clearButton).toBeEnabled() // Verify the setting value was actually set - const settingValue = await comfyPage.getSetting( + const settingValue = await comfyPage.settings.getSetting( 'Comfy.Canvas.BackgroundImage' ) expect(settingValue).toMatch(/^\/api\/view\?.*subfolder=backgrounds/) @@ -124,7 +124,7 @@ test.describe('Background Image Upload', () => { await expect(clearButton).toBeEnabled() // Verify the setting value was updated - const settingValue = await comfyPage.getSetting( + const settingValue = await comfyPage.settings.getSetting( 'Comfy.Canvas.BackgroundImage' ) expect(settingValue).toBe(testImageUrl) @@ -136,7 +136,10 @@ test.describe('Background Image Upload', () => { const testImageUrl = 'https://example.com/test-image.png' // First set a background image - await comfyPage.setSetting('Comfy.Canvas.BackgroundImage', testImageUrl) + await comfyPage.settings.setSetting( + 'Comfy.Canvas.BackgroundImage', + testImageUrl + ) // Open settings dialog await comfyPage.page.keyboard.press('Control+,') @@ -169,7 +172,7 @@ test.describe('Background Image Upload', () => { await expect(clearButton).toBeDisabled() // Verify the setting value was cleared - const settingValue = await comfyPage.getSetting( + const settingValue = await comfyPage.settings.getSetting( 'Comfy.Canvas.BackgroundImage' ) expect(settingValue).toBe('') diff --git a/browser_tests/tests/bottomPanelShortcuts.spec.ts b/browser_tests/tests/bottomPanelShortcuts.spec.ts index 516c53b7b5..d89de7c613 100644 --- a/browser_tests/tests/bottomPanelShortcuts.spec.ts +++ b/browser_tests/tests/bottomPanelShortcuts.spec.ts @@ -4,7 +4,7 @@ import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.describe('Bottom Panel Shortcuts', { tag: '@ui' }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') }) test('should toggle shortcuts panel visibility', async ({ comfyPage }) => { diff --git a/browser_tests/tests/browserTabTitle.spec.ts b/browser_tests/tests/browserTabTitle.spec.ts index f3ad9515e0..7df98e9113 100644 --- a/browser_tests/tests/browserTabTitle.spec.ts +++ b/browser_tests/tests/browserTabTitle.spec.ts @@ -1,11 +1,12 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' +import { DefaultGraphPositions } from '../fixtures/constants/defaultGraphPositions' test.describe('Browser tab title', { tag: '@smoke' }, () => { test.describe('Beta Menu', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') }) test('Can display workflow name', async ({ comfyPage }) => { @@ -30,7 +31,9 @@ test.describe('Browser tab title', { tag: '@smoke' }, () => { const textBox = comfyPage.widgetTextBox await textBox.fill('Hello World') - await comfyPage.clickEmptySpace() + await comfyPage.canvasOps.clickEmptySpace( + DefaultGraphPositions.emptySpaceClick + ) expect(await comfyPage.page.title()).toBe(`*test - ComfyUI`) // Delete the saved workflow for cleanup. @@ -42,7 +45,7 @@ test.describe('Browser tab title', { tag: '@smoke' }, () => { test.describe('Legacy Menu', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test('Can display default title', async ({ comfyPage }) => { diff --git a/browser_tests/tests/changeTracker.spec.ts b/browser_tests/tests/changeTracker.spec.ts index bd5b898a5e..40cedc5582 100644 --- a/browser_tests/tests/changeTracker.spec.ts +++ b/browser_tests/tests/changeTracker.spec.ts @@ -3,6 +3,7 @@ import { comfyExpect as expect, comfyPageFixture as test } from '../fixtures/ComfyPage' +import { DefaultGraphPositions } from '../fixtures/constants/defaultGraphPositions' async function beforeChange(comfyPage: ComfyPage) { await comfyPage.page.evaluate(() => { @@ -16,14 +17,14 @@ async function afterChange(comfyPage: ComfyPage) { } test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Change Tracker', { tag: '@workflow' }, () => { test.describe('Undo/Redo', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') - await comfyPage.setupWorkflowsDirectory({}) + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.workflow.setupWorkflowsDirectory({}) }) test('Can undo multiple operations', async ({ comfyPage }) => { @@ -45,19 +46,19 @@ test.describe('Change Tracker', { tag: '@workflow' }, () => { expect(await comfyPage.getUndoQueueSize()).toBe(1) expect(await comfyPage.getRedoQueueSize()).toBe(0) - await comfyPage.ctrlB() + await comfyPage.keyboard.bypass() await expect(node).toBeBypassed() expect(await comfyPage.isCurrentWorkflowModified()).toBe(true) expect(await comfyPage.getUndoQueueSize()).toBe(2) expect(await comfyPage.getRedoQueueSize()).toBe(0) - await comfyPage.ctrlZ() + await comfyPage.keyboard.undo() await expect(node).not.toBeBypassed() expect(await comfyPage.isCurrentWorkflowModified()).toBe(true) expect(await comfyPage.getUndoQueueSize()).toBe(1) expect(await comfyPage.getRedoQueueSize()).toBe(1) - await comfyPage.ctrlZ() + await comfyPage.keyboard.undo() await expect(node).not.toBeCollapsed() expect(await comfyPage.isCurrentWorkflowModified()).toBe(false) expect(await comfyPage.getUndoQueueSize()).toBe(0) @@ -77,27 +78,29 @@ test.describe('Change Tracker', { tag: '@workflow' }, () => { // Bypass + collapse node await node.click('title') await node.click('collapse') - await comfyPage.ctrlB() + await comfyPage.keyboard.bypass() await expect(node).toBeCollapsed() await expect(node).toBeBypassed() // Undo, undo, ensure both changes undone - await comfyPage.ctrlZ() + await comfyPage.keyboard.undo() await expect(node).not.toBeBypassed() await expect(node).toBeCollapsed() - await comfyPage.ctrlZ() + await comfyPage.keyboard.undo() await expect(node).not.toBeBypassed() await expect(node).not.toBeCollapsed() // Prevent clicks registering a double-click - await comfyPage.clickEmptySpace() + await comfyPage.canvasOps.clickEmptySpace( + DefaultGraphPositions.emptySpaceClick + ) await node.click('title') // Run again, but within a change transaction await beforeChange(comfyPage) await node.click('collapse') - await comfyPage.ctrlB() + await comfyPage.keyboard.bypass() await expect(node).toBeCollapsed() await expect(node).toBeBypassed() @@ -105,7 +108,7 @@ test.describe('Change Tracker', { tag: '@workflow' }, () => { await afterChange(comfyPage) // Ensure undo reverts both changes - await comfyPage.ctrlZ() + await comfyPage.keyboard.undo() await expect(node).not.toBeBypassed() await expect(node).not.toBeCollapsed() }) @@ -116,7 +119,7 @@ test.describe('Change Tracker', { tag: '@workflow' }, () => { const node = (await comfyPage.nodeOps.getFirstNodeRef())! const bypassAndPin = async () => { await beforeChange(comfyPage) - await comfyPage.ctrlB() + await comfyPage.keyboard.bypass() await expect(node).toBeBypassed() await comfyPage.page.keyboard.press('KeyP') await comfyPage.nextFrame() @@ -142,12 +145,12 @@ test.describe('Change Tracker', { tag: '@workflow' }, () => { await multipleChanges() - await comfyPage.ctrlZ() + await comfyPage.keyboard.undo() await expect(node).not.toBeBypassed() await expect(node).not.toBePinned() await expect(node).not.toBeCollapsed() - await comfyPage.ctrlY() + await comfyPage.keyboard.redo() await expect(node).toBeBypassed() await expect(node).toBePinned() await expect(node).toBeCollapsed() @@ -159,7 +162,9 @@ test.describe('Change Tracker', { tag: '@workflow' }, () => { window['app'].graph.extra.foo = 'bar' }) // Click empty space to trigger a change detection. - await comfyPage.clickEmptySpace() + await comfyPage.canvasOps.clickEmptySpace( + DefaultGraphPositions.emptySpaceClick + ) expect(await comfyPage.getUndoQueueSize()).toBe(1) }) diff --git a/browser_tests/tests/colorPalette.spec.ts b/browser_tests/tests/colorPalette.spec.ts index 4a6d691971..66dcf981e6 100644 --- a/browser_tests/tests/colorPalette.spec.ts +++ b/browser_tests/tests/colorPalette.spec.ts @@ -4,7 +4,7 @@ import type { Palette } from '../../src/schemas/colorPaletteSchema' import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) const customColorPalettes: Record = { @@ -153,23 +153,26 @@ const customColorPalettes: Record = { test.describe('Color Palette', { tag: ['@screenshot', '@settings'] }, () => { test('Can show custom color palette', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.CustomColorPalettes', customColorPalettes) + await comfyPage.settings.setSetting( + 'Comfy.CustomColorPalettes', + customColorPalettes + ) // Reload to apply the new setting. Setting Comfy.CustomColorPalettes directly // doesn't update the store immediately. await comfyPage.setup() - await comfyPage.loadWorkflow('nodes/every_node_color') - await comfyPage.setSetting('Comfy.ColorPalette', 'obsidian_dark') + await comfyPage.workflow.loadWorkflow('nodes/every_node_color') + await comfyPage.settings.setSetting('Comfy.ColorPalette', 'obsidian_dark') await expect(comfyPage.canvas).toHaveScreenshot( 'custom-color-palette-obsidian-dark-all-colors.png' ) - await comfyPage.setSetting('Comfy.ColorPalette', 'light_red') + await comfyPage.settings.setSetting('Comfy.ColorPalette', 'light_red') await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot( 'custom-color-palette-light-red.png' ) - await comfyPage.setSetting('Comfy.ColorPalette', 'dark') + await comfyPage.settings.setSetting('Comfy.ColorPalette', 'dark') await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot('default-color-palette.png') }) @@ -180,13 +183,16 @@ test.describe('Color Palette', { tag: ['@screenshot', '@settings'] }, () => { }, customColorPalettes.obsidian_dark) expect(await comfyPage.getToastErrorCount()).toBe(0) - await comfyPage.setSetting('Comfy.ColorPalette', 'obsidian_dark') + await comfyPage.settings.setSetting('Comfy.ColorPalette', 'obsidian_dark') await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot( 'custom-color-palette-obsidian-dark.png' ) // Legacy `custom_` prefix is still supported - await comfyPage.setSetting('Comfy.ColorPalette', 'custom_obsidian_dark') + await comfyPage.settings.setSetting( + 'Comfy.ColorPalette', + 'custom_obsidian_dark' + ) await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot( 'custom-color-palette-obsidian-dark.png' @@ -199,20 +205,20 @@ test.describe( { tag: ['@screenshot', '@settings'] }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.loadWorkflow('nodes/every_node_color') + await comfyPage.workflow.loadWorkflow('nodes/every_node_color') }) test('should adjust opacity via node opacity setting', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Node.Opacity', 0.5) + await comfyPage.settings.setSetting('Comfy.Node.Opacity', 0.5) // Drag mouse to force canvas to redraw await comfyPage.page.mouse.move(0, 0) await expect(comfyPage.canvas).toHaveScreenshot('node-opacity-0.5.png') - await comfyPage.setSetting('Comfy.Node.Opacity', 1.0) + await comfyPage.settings.setSetting('Comfy.Node.Opacity', 1.0) await comfyPage.page.mouse.move(8, 8) await expect(comfyPage.canvas).toHaveScreenshot('node-opacity-1.png') @@ -221,8 +227,8 @@ test.describe( test('should persist color adjustments when changing themes', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Node.Opacity', 0.2) - await comfyPage.setSetting('Comfy.ColorPalette', 'arc') + await comfyPage.settings.setSetting('Comfy.Node.Opacity', 0.2) + await comfyPage.settings.setSetting('Comfy.ColorPalette', 'arc') await comfyPage.nextFrame() await comfyPage.page.mouse.move(0, 0) await expect(comfyPage.canvas).toHaveScreenshot( @@ -233,8 +239,8 @@ test.describe( test('should not serialize color adjustments in workflow', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Node.Opacity', 0.5) - await comfyPage.setSetting('Comfy.ColorPalette', 'light') + await comfyPage.settings.setSetting('Comfy.Node.Opacity', 0.5) + await comfyPage.settings.setSetting('Comfy.ColorPalette', 'light') await comfyPage.nextFrame() const parsed = await ( await comfyPage.page.waitForFunction( @@ -262,7 +268,7 @@ test.describe( test('should lighten node colors when switching to light theme', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.ColorPalette', 'light') + await comfyPage.settings.setSetting('Comfy.ColorPalette', 'light') await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot( 'node-lightened-colors.png' @@ -271,8 +277,8 @@ test.describe( test.describe('Context menu color adjustments', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.ColorPalette', 'light') - await comfyPage.setSetting('Comfy.Node.Opacity', 0.3) + await comfyPage.settings.setSetting('Comfy.ColorPalette', 'light') + await comfyPage.settings.setSetting('Comfy.Node.Opacity', 0.3) const node = await comfyPage.nodeOps.getFirstNodeRef() await node?.clickContextMenuOption('Colors') }) diff --git a/browser_tests/tests/commands.spec.ts b/browser_tests/tests/commands.spec.ts index acf99d1772..66776387a8 100644 --- a/browser_tests/tests/commands.spec.ts +++ b/browser_tests/tests/commands.spec.ts @@ -3,7 +3,7 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Keybindings', { tag: '@keyboard' }, () => { diff --git a/browser_tests/tests/copyPaste.spec.ts b/browser_tests/tests/copyPaste.spec.ts index aaa9a6f72e..89c494b276 100644 --- a/browser_tests/tests/copyPaste.spec.ts +++ b/browser_tests/tests/copyPaste.spec.ts @@ -1,24 +1,29 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' +import { DefaultGraphPositions } from '../fixtures/constants/defaultGraphPositions' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Copy Paste', { tag: ['@screenshot', '@workflow'] }, () => { test('Can copy and paste node', async ({ comfyPage }) => { - await comfyPage.clickEmptyLatentNode() + await comfyPage.canvas.click({ position: { x: 724, y: 625 } }) await comfyPage.page.mouse.move(10, 10) - await comfyPage.ctrlC() - await comfyPage.ctrlV() + await comfyPage.nextFrame() + await comfyPage.clipboard.copy() + await comfyPage.clipboard.paste() await expect(comfyPage.canvas).toHaveScreenshot('copied-node.png') }) test('Can copy and paste node with link', async ({ comfyPage }) => { - await comfyPage.clickTextEncodeNode1() + await comfyPage.canvas.click({ + position: DefaultGraphPositions.textEncodeNode1 + }) + await comfyPage.nextFrame() await comfyPage.page.mouse.move(10, 10) - await comfyPage.ctrlC() + await comfyPage.clipboard.copy() await comfyPage.page.keyboard.press('Control+Shift+V') await expect(comfyPage.canvas).toHaveScreenshot('copied-node-with-link.png') }) @@ -28,9 +33,9 @@ test.describe('Copy Paste', { tag: ['@screenshot', '@workflow'] }, () => { await textBox.click() const originalString = await textBox.inputValue() await textBox.selectText() - await comfyPage.ctrlC(null) - await comfyPage.ctrlV(null) - await comfyPage.ctrlV(null) + await comfyPage.clipboard.copy(null) + await comfyPage.clipboard.paste(null) + await comfyPage.clipboard.paste(null) const resultString = await textBox.inputValue() expect(resultString).toBe(originalString + originalString) }) @@ -44,7 +49,7 @@ test.describe('Copy Paste', { tag: ['@screenshot', '@workflow'] }, () => { y: 281 } }) - await comfyPage.ctrlC(null) + await comfyPage.clipboard.copy(null) // Empty latent node's width await comfyPage.canvas.click({ position: { @@ -52,7 +57,7 @@ test.describe('Copy Paste', { tag: ['@screenshot', '@workflow'] }, () => { y: 643 } }) - await comfyPage.ctrlV(null) + await comfyPage.clipboard.paste(null) await comfyPage.page.keyboard.press('Enter') await expect(comfyPage.canvas).toHaveScreenshot('copied-widget-value.png') }) @@ -63,15 +68,17 @@ test.describe('Copy Paste', { tag: ['@screenshot', '@workflow'] }, () => { test('Paste in text area with node previously copied', async ({ comfyPage }) => { - await comfyPage.clickEmptyLatentNode() - await comfyPage.ctrlC(null) + await comfyPage.canvas.click({ position: { x: 724, y: 625 } }) + await comfyPage.page.mouse.move(10, 10) + await comfyPage.nextFrame() + await comfyPage.clipboard.copy(null) const textBox = comfyPage.widgetTextBox await textBox.click() await textBox.inputValue() await textBox.selectText() - await comfyPage.ctrlC(null) - await comfyPage.ctrlV(null) - await comfyPage.ctrlV(null) + await comfyPage.clipboard.copy(null) + await comfyPage.clipboard.paste(null) + await comfyPage.clipboard.paste(null) await expect(comfyPage.canvas).toHaveScreenshot( 'paste-in-text-area-with-node-previously-copied.png' ) @@ -82,10 +89,10 @@ test.describe('Copy Paste', { tag: ['@screenshot', '@workflow'] }, () => { await textBox.click() await textBox.inputValue() await textBox.selectText() - await comfyPage.ctrlC(null) + await comfyPage.clipboard.copy(null) // Unfocus textbox. await comfyPage.page.mouse.click(10, 10) - await comfyPage.ctrlV(null) + await comfyPage.clipboard.paste(null) await expect(comfyPage.canvas).toHaveScreenshot('no-node-copied.png') }) @@ -106,15 +113,15 @@ test.describe('Copy Paste', { tag: ['@screenshot', '@workflow'] }, () => { const initialCount = await comfyPage.nodeOps.getGraphNodesCount() expect(initialCount).toBeGreaterThan(1) await comfyPage.canvas.click() - await comfyPage.ctrlA() + await comfyPage.keyboard.selectAll() await comfyPage.page.mouse.move(10, 10) - await comfyPage.ctrlC() - await comfyPage.ctrlV() + await comfyPage.clipboard.copy() + await comfyPage.clipboard.paste() const pasteCount = await comfyPage.nodeOps.getGraphNodesCount() expect(pasteCount).toBe(initialCount * 2) - await comfyPage.ctrlZ() + await comfyPage.keyboard.undo() const undoCount = await comfyPage.nodeOps.getGraphNodesCount() expect(undoCount).toBe(initialCount) }) diff --git a/browser_tests/tests/customIcons.spec.ts b/browser_tests/tests/customIcons.spec.ts index eb4eccfd54..ed9680406e 100644 --- a/browser_tests/tests/customIcons.spec.ts +++ b/browser_tests/tests/customIcons.spec.ts @@ -24,7 +24,7 @@ async function verifyCustomIconSvg(iconElement: Locator) { test.describe('Custom Icons', { tag: '@settings' }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') }) test('sidebar tab icons use custom SVGs', async ({ comfyPage }) => { diff --git a/browser_tests/tests/dialog.spec.ts b/browser_tests/tests/dialog.spec.ts index e102f27fc8..a14e1bcee9 100644 --- a/browser_tests/tests/dialog.spec.ts +++ b/browser_tests/tests/dialog.spec.ts @@ -5,14 +5,14 @@ import type { Keybinding } from '../../src/platform/keybindings' import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Load workflow warning', { tag: '@ui' }, () => { test('Should display a warning when loading a workflow with missing nodes', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('missing/missing_nodes') + await comfyPage.workflow.loadWorkflow('missing/missing_nodes') // Wait for the element with the .comfy-missing-nodes selector to be visible const missingNodesWarning = comfyPage.page.locator('.comfy-missing-nodes') @@ -22,7 +22,7 @@ test.describe('Load workflow warning', { tag: '@ui' }, () => { test('Should display a warning when loading a workflow with missing nodes in subgraphs', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('missing/missing_nodes_in_subgraph') + await comfyPage.workflow.loadWorkflow('missing/missing_nodes_in_subgraph') // Wait for the element with the .comfy-missing-nodes selector to be visible const missingNodesWarning = comfyPage.page.locator('.comfy-missing-nodes') @@ -36,10 +36,14 @@ test.describe('Load workflow warning', { tag: '@ui' }, () => { }) test('Does not report warning on undo/redo', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.NodeSearchBoxImpl', 'default') + await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'default') - await comfyPage.loadWorkflow('missing/missing_nodes') - await comfyPage.closeDialog() + await comfyPage.workflow.loadWorkflow('missing/missing_nodes') + await comfyPage.page + .locator('.p-dialog') + .getByRole('button', { name: 'Close' }) + .click({ force: true }) + await comfyPage.page.locator('.p-dialog').waitFor({ state: 'hidden' }) // Wait for any async operations to complete after dialog closes await comfyPage.nextFrame() @@ -49,9 +53,9 @@ test('Does not report warning on undo/redo', async ({ comfyPage }) => { await comfyPage.searchBox.fillAndSelectFirstNode('KSampler') // Undo and redo the change - await comfyPage.ctrlZ() + await comfyPage.keyboard.undo() await expect(comfyPage.page.locator('.comfy-missing-nodes')).not.toBeVisible() - await comfyPage.ctrlY() + await comfyPage.keyboard.redo() await expect(comfyPage.page.locator('.comfy-missing-nodes')).not.toBeVisible() }) @@ -59,7 +63,7 @@ test.describe('Execution error', () => { test('Should display an error message when an execution error occurs', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('nodes/execution_error') + await comfyPage.workflow.loadWorkflow('nodes/execution_error') await comfyPage.queueButton.click() await comfyPage.nextFrame() @@ -71,7 +75,10 @@ test.describe('Execution error', () => { test.describe('Missing models warning', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Workflow.ShowMissingModelsWarning', true) + await comfyPage.settings.setSetting( + 'Comfy.Workflow.ShowMissingModelsWarning', + true + ) await comfyPage.page.evaluate((url: string) => { return fetch(`${url}/api/devtools/cleanup_fake_model`) }, comfyPage.url) @@ -80,7 +87,7 @@ test.describe('Missing models warning', () => { test('Should display a warning when missing models are found', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('missing/missing_models') + await comfyPage.workflow.loadWorkflow('missing/missing_models') const missingModelsWarning = comfyPage.page.locator('.comfy-missing-models') await expect(missingModelsWarning).toBeVisible() @@ -97,7 +104,9 @@ test.describe('Missing models warning', () => { comfyPage }) => { // Load workflow that has a node with models metadata at the node level - await comfyPage.loadWorkflow('missing/missing_models_from_node_properties') + await comfyPage.workflow.loadWorkflow( + 'missing/missing_models_from_node_properties' + ) const missingModelsWarning = comfyPage.page.locator('.comfy-missing-models') await expect(missingModelsWarning).toBeVisible() @@ -146,7 +155,7 @@ test.describe('Missing models warning', () => { { times: 1 } ) - await comfyPage.loadWorkflow('missing/missing_models') + await comfyPage.workflow.loadWorkflow('missing/missing_models') const missingModelsWarning = comfyPage.page.locator('.comfy-missing-models') await expect(missingModelsWarning).not.toBeVisible() @@ -157,7 +166,9 @@ test.describe('Missing models warning', () => { }) => { // This tests the scenario where outdated model metadata exists in the workflow // but the actual selected models (widget values) have changed - await comfyPage.loadWorkflow('missing/model_metadata_widget_mismatch') + await comfyPage.workflow.loadWorkflow( + 'missing/model_metadata_widget_mismatch' + ) // The missing models warning should NOT appear const missingModelsWarning = comfyPage.page.locator('.comfy-missing-models') @@ -171,7 +182,7 @@ test.describe('Missing models warning', () => { }) => { // The fake_model.safetensors is served by // https://github.com/Comfy-Org/ComfyUI_devtools/blob/main/__init__.py - await comfyPage.loadWorkflow('missing/missing_models') + await comfyPage.workflow.loadWorkflow('missing/missing_models') const missingModelsWarning = comfyPage.page.locator('.comfy-missing-models') await expect(missingModelsWarning).toBeVisible() @@ -190,11 +201,11 @@ test.describe('Missing models warning', () => { let closeButton: Locator test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting( + await comfyPage.settings.setSetting( 'Comfy.Workflow.ShowMissingModelsWarning', true ) - await comfyPage.loadWorkflow('missing/missing_models') + await comfyPage.workflow.loadWorkflow('missing/missing_models') checkbox = comfyPage.page.getByLabel("Don't show this again") closeButton = comfyPage.page.getByLabel('Close') @@ -210,7 +221,7 @@ test.describe('Missing models warning', () => { await closeButton.click() await changeSettingPromise - const settingValue = await comfyPage.getSetting( + const settingValue = await comfyPage.settings.getSetting( 'Comfy.Workflow.ShowMissingModelsWarning' ) expect(settingValue).toBe(false) @@ -221,7 +232,7 @@ test.describe('Missing models warning', () => { }) => { await closeButton.click() - const settingValue = await comfyPage.getSetting( + const settingValue = await comfyPage.settings.getSetting( 'Comfy.Workflow.ShowMissingModelsWarning' ) expect(settingValue).toBe(true) @@ -252,9 +263,11 @@ test.describe('Settings', () => { test('Can change canvas zoom speed setting', async ({ comfyPage }) => { const maxSpeed = 2.5 - await comfyPage.setSetting('Comfy.Graph.ZoomSpeed', maxSpeed) + await comfyPage.settings.setSetting('Comfy.Graph.ZoomSpeed', maxSpeed) await test.step('Setting should persist', async () => { - expect(await comfyPage.getSetting('Comfy.Graph.ZoomSpeed')).toBe(maxSpeed) + expect(await comfyPage.settings.getSetting('Comfy.Graph.ZoomSpeed')).toBe( + maxSpeed + ) }) }) @@ -311,7 +324,7 @@ test.describe('Support', () => { test('Should open external zendesk link with OSS tag', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') const pagePromise = comfyPage.page.context().waitForEvent('page') await comfyPage.menu.topbar.triggerTopbarCommand(['Help', 'Support']) const newPage = await pagePromise @@ -337,7 +350,7 @@ test.describe('Error dialog', () => { } }) - await comfyPage.loadWorkflow('default') + await comfyPage.workflow.loadWorkflow('default') const errorDialog = comfyPage.page.locator('.comfy-error-report') await expect(errorDialog).toBeVisible() @@ -363,8 +376,10 @@ test.describe('Signin dialog', () => { comfyPage }) => { const nodeNum = (await comfyPage.nodeOps.getNodes()).length - await comfyPage.clickEmptyLatentNode() - await comfyPage.ctrlC() + await comfyPage.canvas.click({ position: { x: 724, y: 625 } }) + await comfyPage.page.mouse.move(10, 10) + await comfyPage.nextFrame() + await comfyPage.clipboard.copy() const textBox = comfyPage.widgetTextBox await textBox.click() diff --git a/browser_tests/tests/domWidget.spec.ts b/browser_tests/tests/domWidget.spec.ts index c1fa881219..c47823fa06 100644 --- a/browser_tests/tests/domWidget.spec.ts +++ b/browser_tests/tests/domWidget.spec.ts @@ -3,12 +3,12 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('DOM Widget', { tag: '@widget' }, () => { test('Collapsed multiline textarea is not visible', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('widgets/collapsed_multiline') + await comfyPage.workflow.loadWorkflow('widgets/collapsed_multiline') const textareaWidget = comfyPage.page.locator('.comfy-multiline-input') await expect(textareaWidget).not.toBeVisible() }) @@ -33,7 +33,7 @@ test.describe('DOM Widget', { tag: '@widget' }, () => { 'Position update when entering focus mode', { tag: '@screenshot' }, async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') await comfyPage.executeCommand('Workspace.ToggleFocusMode') await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot('focus-mode-on.png') @@ -68,9 +68,9 @@ test.describe('DOM Widget', { tag: '@widget' }, () => { .first() await expect(textareaWidget).toBeVisible() - await comfyPage.setSetting('Comfy.Sidebar.Size', 'small') - await comfyPage.setSetting('Comfy.Sidebar.Location', 'left') - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.Sidebar.Size', 'small') + await comfyPage.settings.setSetting('Comfy.Sidebar.Location', 'left') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') await comfyPage.nextFrame() let oldPos: [number, number] @@ -85,15 +85,15 @@ test.describe('DOM Widget', { tag: '@widget' }, () => { // --- test --- - await comfyPage.setSetting('Comfy.Sidebar.Size', 'normal') + await comfyPage.settings.setSetting('Comfy.Sidebar.Size', 'normal') await comfyPage.nextFrame() await checkBboxChange() - await comfyPage.setSetting('Comfy.Sidebar.Location', 'right') + await comfyPage.settings.setSetting('Comfy.Sidebar.Location', 'right') await comfyPage.nextFrame() await checkBboxChange() - await comfyPage.setSetting('Comfy.UseNewMenu', 'Bottom') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Bottom') await comfyPage.nextFrame() await checkBboxChange() }) diff --git a/browser_tests/tests/execution.spec.ts b/browser_tests/tests/execution.spec.ts index 49667f076c..b5c8ee07fe 100644 --- a/browser_tests/tests/execution.spec.ts +++ b/browser_tests/tests/execution.spec.ts @@ -1,9 +1,10 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' +import { DefaultGraphPositions } from '../fixtures/constants/defaultGraphPositions' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Execution', { tag: ['@smoke', '@workflow'] }, () => { @@ -12,7 +13,9 @@ test.describe('Execution', { tag: ['@smoke', '@workflow'] }, () => { { tag: '@screenshot' }, async ({ comfyPage }) => { await comfyPage.disconnectEdge() - await comfyPage.clickEmptySpace() + await comfyPage.canvasOps.clickEmptySpace( + DefaultGraphPositions.emptySpaceClick + ) await comfyPage.executeCommand('Comfy.QueuePrompt') await expect(comfyPage.page.locator('.comfy-error-report')).toBeVisible() @@ -35,7 +38,7 @@ test.describe( { tag: ['@smoke', '@workflow'] }, () => { test('Execute to selected output nodes', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('execution/partial_execution') + await comfyPage.workflow.loadWorkflow('execution/partial_execution') const input = await comfyPage.nodeOps.getNodeRefById(3) const output1 = await comfyPage.nodeOps.getNodeRefById(1) const output2 = await comfyPage.nodeOps.getNodeRefById(4) diff --git a/browser_tests/tests/extensionAPI.spec.ts b/browser_tests/tests/extensionAPI.spec.ts index fd312cca70..932fb0ef3a 100644 --- a/browser_tests/tests/extensionAPI.spec.ts +++ b/browser_tests/tests/extensionAPI.spec.ts @@ -5,7 +5,7 @@ import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.describe('Topbar commands', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') }) test('Should allow registering topbar commands', async ({ comfyPage }) => { @@ -102,10 +102,14 @@ test.describe('Topbar commands', () => { }) // onChange is called when the setting is first added expect(await comfyPage.page.evaluate(() => window['changeCount'])).toBe(1) - expect(await comfyPage.getSetting('TestSetting')).toBe('Hello, world!') + expect(await comfyPage.settings.getSetting('TestSetting')).toBe( + 'Hello, world!' + ) - await comfyPage.setSetting('TestSetting', 'Hello, universe!') - expect(await comfyPage.getSetting('TestSetting')).toBe('Hello, universe!') + await comfyPage.settings.setSetting('TestSetting', 'Hello, universe!') + expect(await comfyPage.settings.getSetting('TestSetting')).toBe( + 'Hello, universe!' + ) expect(await comfyPage.page.evaluate(() => window['changeCount'])).toBe(2) }) @@ -127,12 +131,16 @@ test.describe('Topbar commands', () => { }) }) - expect(await comfyPage.getSetting('Comfy.TestSetting')).toBe(false) + expect(await comfyPage.settings.getSetting('Comfy.TestSetting')).toBe( + false + ) expect(await comfyPage.page.evaluate(() => window['changeCount'])).toBe(1) await comfyPage.settingDialog.open() await comfyPage.settingDialog.toggleBooleanSetting('Comfy.TestSetting') - expect(await comfyPage.getSetting('Comfy.TestSetting')).toBe(true) + expect(await comfyPage.settings.getSetting('Comfy.TestSetting')).toBe( + true + ) expect(await comfyPage.page.evaluate(() => window['changeCount'])).toBe(2) }) @@ -301,7 +309,7 @@ test.describe('Topbar commands', () => { test.describe('Selection Toolbox', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Canvas.SelectionToolbox', true) + await comfyPage.settings.setSetting('Comfy.Canvas.SelectionToolbox', true) }) test('Should allow adding commands to selection toolbox', async ({ diff --git a/browser_tests/tests/featureFlags.spec.ts b/browser_tests/tests/featureFlags.spec.ts index 73f1cd2f57..cf453297d9 100644 --- a/browser_tests/tests/featureFlags.spec.ts +++ b/browser_tests/tests/featureFlags.spec.ts @@ -3,7 +3,7 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Feature Flags', { tag: ['@slow', '@settings'] }, () => { diff --git a/browser_tests/tests/graph.spec.ts b/browser_tests/tests/graph.spec.ts index 340b5b6977..949e216d59 100644 --- a/browser_tests/tests/graph.spec.ts +++ b/browser_tests/tests/graph.spec.ts @@ -3,14 +3,14 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Graph', { tag: ['@smoke', '@canvas'] }, () => { // Should be able to fix link input slot index after swap the input order // Ref: https://github.com/Comfy-Org/ComfyUI_frontend/issues/3348 test('Fix link input slots', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('inputs/input_order_swap') + await comfyPage.workflow.loadWorkflow('inputs/input_order_swap') expect( await comfyPage.page.evaluate(() => { return window['app'].graph.links.get(1)?.target_slot @@ -19,8 +19,8 @@ test.describe('Graph', { tag: ['@smoke', '@canvas'] }, () => { }) test('Validate workflow links', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Validation.Workflows', true) - await comfyPage.loadWorkflow('links/bad_link') + await comfyPage.settings.setSetting('Comfy.Validation.Workflows', true) + await comfyPage.workflow.loadWorkflow('links/bad_link') await expect(comfyPage.getVisibleToastCount()).resolves.toBe(2) }) }) diff --git a/browser_tests/tests/graphCanvasMenu.spec.ts b/browser_tests/tests/graphCanvasMenu.spec.ts index 4e6d1b2fb3..80904e8dce 100644 --- a/browser_tests/tests/graphCanvasMenu.spec.ts +++ b/browser_tests/tests/graphCanvasMenu.spec.ts @@ -3,16 +3,16 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Graph Canvas Menu', { tag: ['@screenshot', '@canvas'] }, () => { 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) + await comfyPage.settings.setSetting('Comfy.LinkRenderMode', 2) // Enable canvas menu for all tests - await comfyPage.setSetting('Comfy.Graph.CanvasMenu', true) + await comfyPage.settings.setSetting('Comfy.Graph.CanvasMenu', true) }) test( @@ -28,7 +28,7 @@ test.describe('Graph Canvas Menu', { tag: ['@screenshot', '@canvas'] }, () => { const hiddenLinkRenderMode = await comfyPage.page.evaluate(() => { return window['LiteGraph'].HIDDEN_LINK }) - expect(await comfyPage.getSetting('Comfy.LinkRenderMode')).toBe( + expect(await comfyPage.settings.getSetting('Comfy.LinkRenderMode')).toBe( hiddenLinkRenderMode ) @@ -37,9 +37,9 @@ test.describe('Graph Canvas Menu', { tag: ['@screenshot', '@canvas'] }, () => { await expect(comfyPage.canvas).toHaveScreenshot( 'canvas-with-visible-links.png' ) - expect(await comfyPage.getSetting('Comfy.LinkRenderMode')).not.toBe( - hiddenLinkRenderMode - ) + expect( + await comfyPage.settings.getSetting('Comfy.LinkRenderMode') + ).not.toBe(hiddenLinkRenderMode) } ) diff --git a/browser_tests/tests/groupNode.spec.ts b/browser_tests/tests/groupNode.spec.ts index 94cb5a0b87..96248ec144 100644 --- a/browser_tests/tests/groupNode.spec.ts +++ b/browser_tests/tests/groupNode.spec.ts @@ -2,10 +2,11 @@ import { expect } from '@playwright/test' import type { ComfyPage } from '../fixtures/ComfyPage' import { comfyPageFixture as test } from '../fixtures/ComfyPage' +import { DefaultGraphPositions } from '../fixtures/constants/defaultGraphPositions' import type { NodeReference } from '../fixtures/utils/litegraphUtils' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Group Node', { tag: '@node' }, () => { @@ -16,7 +17,7 @@ test.describe('Group Node', { tag: '@node' }, () => { let libraryTab test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') libraryTab = comfyPage.menu.nodeLibraryTab await comfyPage.nodeOps.convertAllNodesToGroupNode(groupNodeName) await libraryTab.open() @@ -50,7 +51,7 @@ test.describe('Group Node', { tag: '@node' }, () => { // Verify the node is added to the bookmarks tab expect( - await comfyPage.getSetting('Comfy.NodeLibrary.Bookmarks.V2') + await comfyPage.settings.getSetting('Comfy.NodeLibrary.Bookmarks.V2') ).toEqual([groupNodeBookmarkName]) // Verify the bookmark node with the same name is added to the tree expect(await libraryTab.getNode(groupNodeName).count()).not.toBe(0) @@ -64,7 +65,7 @@ test.describe('Group Node', { tag: '@node' }, () => { // Verify the node is removed from the bookmarks tab expect( - await comfyPage.getSetting('Comfy.NodeLibrary.Bookmarks.V2') + await comfyPage.settings.getSetting('Comfy.NodeLibrary.Bookmarks.V2') ).toHaveLength(0) }) @@ -107,7 +108,7 @@ test.describe('Group Node', { tag: '@node' }, () => { ) test('Displays tooltip on title hover', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.EnableTooltips', true) + await comfyPage.settings.setSetting('Comfy.EnableTooltips', true) await comfyPage.nodeOps.convertAllNodesToGroupNode('Group Node') await comfyPage.page.mouse.move(47, 173) await expect(comfyPage.page.locator('.node-tooltip')).toBeVisible() @@ -146,7 +147,7 @@ test.describe('Group Node', { tag: '@node' }, () => { test('Preserves hidden input configuration when containing duplicate node types', async ({ comfyPage }) => { - await comfyPage.loadWorkflow( + await comfyPage.workflow.loadWorkflow( 'groupnodes/group_node_identical_nodes_hidden_inputs' ) await comfyPage.nextFrame() @@ -215,7 +216,7 @@ test.describe('Group Node', { tag: '@node' }, () => { test('Loads from a workflow using the legacy path separator ("/")', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('groupnodes/legacy_group_node') + await comfyPage.workflow.loadWorkflow('groupnodes/legacy_group_node') expect(await comfyPage.nodeOps.getGraphNodesCount()).toBe(1) await expect( comfyPage.page.locator('.comfy-missing-nodes') @@ -256,8 +257,8 @@ test.describe('Group Node', { tag: '@node' }, () => { } test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') - await comfyPage.loadWorkflow(WORKFLOW_NAME) + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.workflow.loadWorkflow(WORKFLOW_NAME) groupNode = await comfyPage.nodeOps.getFirstNodeRef() if (!groupNode) throw new Error(`Group node not found in workflow ${WORKFLOW_NAME}`) @@ -267,7 +268,7 @@ test.describe('Group Node', { tag: '@node' }, () => { test('Copies and pastes group node within the same workflow', async ({ comfyPage }) => { - await comfyPage.ctrlV() + await comfyPage.clipboard.paste() await verifyNodeLoaded(comfyPage, 2) }) @@ -275,12 +276,12 @@ test.describe('Group Node', { tag: '@node' }, () => { comfyPage }) => { // Set setting - await comfyPage.setSetting('Comfy.ConfirmClear', false) + await comfyPage.settings.setSetting('Comfy.ConfirmClear', false) // Clear workflow await comfyPage.executeCommand('Comfy.ClearWorkflow') - await comfyPage.ctrlV() + await comfyPage.clipboard.paste() await verifyNodeLoaded(comfyPage, 1) }) @@ -288,15 +289,15 @@ test.describe('Group Node', { tag: '@node' }, () => { comfyPage }) => { await comfyPage.menu.topbar.triggerTopbarCommand(['New']) - await comfyPage.ctrlV() + await comfyPage.clipboard.paste() await verifyNodeLoaded(comfyPage, 1) }) test('Copies and pastes group node across different workflows', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('default') - await comfyPage.ctrlV() + await comfyPage.workflow.loadWorkflow('default') + await comfyPage.clipboard.paste() await verifyNodeLoaded(comfyPage, 1) }) @@ -304,7 +305,7 @@ test.describe('Group Node', { tag: '@node' }, () => { comfyPage }) => { await comfyPage.menu.topbar.triggerTopbarCommand(['New']) - await comfyPage.ctrlV() + await comfyPage.clipboard.paste() const currentGraphState = await comfyPage.page.evaluate(() => window['app'].graph.serialize() ) @@ -328,7 +329,10 @@ test.describe('Group Node', { tag: '@node' }, () => { }) test('Convert to group node, selected 1 node', async ({ comfyPage }) => { expect(await comfyPage.getVisibleToastCount()).toBe(0) - await comfyPage.clickTextEncodeNode1() + await comfyPage.canvas.click({ + position: DefaultGraphPositions.textEncodeNode1 + }) + await comfyPage.nextFrame() await comfyPage.page.keyboard.press('Alt+g') expect(await comfyPage.getVisibleToastCount()).toBe(1) }) diff --git a/browser_tests/tests/interaction.spec.ts b/browser_tests/tests/interaction.spec.ts index 6f10d68718..ea3662a1d3 100644 --- a/browser_tests/tests/interaction.spec.ts +++ b/browser_tests/tests/interaction.spec.ts @@ -7,15 +7,16 @@ import { testComfySnapToGridGridSize } from '../fixtures/ComfyPage' import type { ComfyPage } from '../fixtures/ComfyPage' +import { DefaultGraphPositions } from '../fixtures/constants/defaultGraphPositions' import type { NodeReference } from '../fixtures/utils/litegraphUtils' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Item Interaction', { tag: ['@screenshot', '@node'] }, () => { test('Can select/delete all items', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('groups/mixed_graph_items') + await comfyPage.workflow.loadWorkflow('groups/mixed_graph_items') await comfyPage.canvas.press('Control+a') await expect(comfyPage.canvas).toHaveScreenshot('selected-all.png') await comfyPage.canvas.press('Delete') @@ -23,7 +24,7 @@ test.describe('Item Interaction', { tag: ['@screenshot', '@node'] }, () => { }) test('Can pin/unpin items with keyboard shortcut', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('groups/mixed_graph_items') + await comfyPage.workflow.loadWorkflow('groups/mixed_graph_items') await comfyPage.canvas.press('Control+a') await comfyPage.canvas.press('KeyP') await comfyPage.nextFrame() @@ -67,9 +68,15 @@ test.describe('Node Interaction', () => { { tag: '@screenshot' }, async ({ comfyPage }) => { await expect(comfyPage.canvas).toHaveScreenshot('default.png') - await comfyPage.clickTextEncodeNode1() + await comfyPage.canvas.click({ + position: DefaultGraphPositions.textEncodeNode1 + }) + await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot('selected-node1.png') - await comfyPage.clickTextEncodeNode2() + await comfyPage.canvas.click({ + position: DefaultGraphPositions.textEncodeNode2 + }) + await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot('selected-node2.png') } ) @@ -165,8 +172,14 @@ test.describe('Node Interaction', () => { test.describe('Edge Interaction', { tag: '@screenshot' }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.LinkRelease.Action', 'no action') - await comfyPage.setSetting('Comfy.LinkRelease.ActionShift', 'no action') + await comfyPage.settings.setSetting( + 'Comfy.LinkRelease.Action', + 'no action' + ) + await comfyPage.settings.setSetting( + 'Comfy.LinkRelease.ActionShift', + 'no action' + ) }) // Test both directions of edge connection. @@ -188,13 +201,13 @@ test.describe('Node Interaction', () => { test('Can move link', async ({ comfyPage }) => { await comfyPage.canvasOps.dragAndDrop( - comfyPage.clipTextEncodeNode1InputSlot, - comfyPage.emptySpace + DefaultGraphPositions.clipTextEncodeNode1InputSlot, + DefaultGraphPositions.emptySpace ) await expect(comfyPage.canvas).toHaveScreenshot('disconnected-edge.png') await comfyPage.canvasOps.dragAndDrop( - comfyPage.clipTextEncodeNode2InputSlot, - comfyPage.clipTextEncodeNode1InputSlot + DefaultGraphPositions.clipTextEncodeNode2InputSlot, + DefaultGraphPositions.clipTextEncodeNode1InputSlot ) await expect(comfyPage.canvas).toHaveScreenshot('moved-link.png') }) @@ -204,14 +217,14 @@ test.describe('Node Interaction', () => { comfyPage }) => { await comfyPage.canvasOps.dragAndDrop( - comfyPage.clipTextEncodeNode1InputSlot, - comfyPage.emptySpace + DefaultGraphPositions.clipTextEncodeNode1InputSlot, + DefaultGraphPositions.emptySpace ) await expect(comfyPage.canvas).toHaveScreenshot('disconnected-edge.png') await comfyPage.page.keyboard.down('Shift') await comfyPage.canvasOps.dragAndDrop( - comfyPage.clipTextEncodeNode2InputLinkPath, - comfyPage.clipTextEncodeNode1InputSlot + DefaultGraphPositions.clipTextEncodeNode2InputLinkPath, + DefaultGraphPositions.clipTextEncodeNode1InputSlot ) await comfyPage.page.keyboard.up('Shift') await expect(comfyPage.canvas).toHaveScreenshot('copied-link.png') @@ -221,11 +234,11 @@ test.describe('Node Interaction', () => { comfyPage, comfyMouse }) => { - await comfyPage.setSetting('Comfy.Node.AutoSnapLinkToSlot', true) - await comfyPage.setSetting('Comfy.Node.SnapHighlightsNode', true) + await comfyPage.settings.setSetting('Comfy.Node.AutoSnapLinkToSlot', true) + await comfyPage.settings.setSetting('Comfy.Node.SnapHighlightsNode', true) - await comfyMouse.move(comfyPage.clipTextEncodeNode1InputSlot) - await comfyMouse.drag(comfyPage.clipTextEncodeNode2InputSlot) + await comfyMouse.move(DefaultGraphPositions.clipTextEncodeNode1InputSlot) + await comfyMouse.drag(DefaultGraphPositions.clipTextEncodeNode2InputSlot) await expect(comfyPage.canvas).toHaveScreenshot('snapped-highlighted.png') }) }) @@ -242,7 +255,7 @@ test.describe('Node Interaction', () => { ) test('Link snap to slot', { tag: '@screenshot' }, async ({ comfyPage }) => { - await comfyPage.loadWorkflow('links/snap_to_slot') + await comfyPage.workflow.loadWorkflow('links/snap_to_slot') await expect(comfyPage.canvas).toHaveScreenshot('snap_to_slot.png') const outputSlotPos = { @@ -262,7 +275,7 @@ test.describe('Node Interaction', () => { 'Can batch move links by drag with shift', { tag: '@screenshot' }, async ({ comfyPage }) => { - await comfyPage.loadWorkflow('links/batch_move_links') + await comfyPage.workflow.loadWorkflow('links/batch_move_links') await expect(comfyPage.canvas).toHaveScreenshot('batch_move_links.png') const outputSlot1Pos = { @@ -308,12 +321,18 @@ test.describe('Node Interaction', () => { { tag: '@screenshot' }, async ({ comfyPage }) => { await expect(comfyPage.canvas).toHaveScreenshot('default.png') - await comfyPage.clickTextEncodeNodeToggler() + await comfyPage.canvas.click({ + position: DefaultGraphPositions.textEncodeNodeToggler + }) + await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot( 'text-encode-toggled-off.png' ) await comfyPage.delay(1000) - await comfyPage.clickTextEncodeNodeToggler() + await comfyPage.canvas.click({ + position: DefaultGraphPositions.textEncodeNodeToggler + }) + await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot( 'text-encode-toggled-back-open.png' ) @@ -349,7 +368,7 @@ test.describe('Node Interaction', () => { x: 167, y: 143 } - await comfyPage.loadWorkflow('nodes/single_save_image_node') + await comfyPage.workflow.loadWorkflow('nodes/single_save_image_node') await comfyPage.canvas.click({ position: textWidgetPos }) @@ -369,7 +388,7 @@ test.describe('Node Interaction', () => { 'Can double click node title to edit', { tag: '@screenshot' }, async ({ comfyPage }) => { - await comfyPage.loadWorkflow('nodes/single_ksampler') + await comfyPage.workflow.loadWorkflow('nodes/single_ksampler') await comfyPage.canvas.dblclick({ position: { x: 50, @@ -386,7 +405,7 @@ test.describe('Node Interaction', () => { test('Double click node body does not trigger edit', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('nodes/single_ksampler') + await comfyPage.workflow.loadWorkflow('nodes/single_ksampler') await comfyPage.canvas.dblclick({ position: { x: 50, @@ -401,7 +420,10 @@ test.describe('Node Interaction', () => { 'Can group selected nodes', { tag: '@screenshot' }, async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.GroupSelectedNodes.Padding', 10) + await comfyPage.settings.setSetting( + 'Comfy.GroupSelectedNodes.Padding', + 10 + ) await comfyPage.nodeOps.selectNodes(['CLIP Text Encode (Prompt)']) await comfyPage.page.keyboard.down('Control') await comfyPage.page.keyboard.press('KeyG') @@ -420,8 +442,8 @@ test.describe('Node Interaction', () => { 'Can fit group to contents', { tag: '@screenshot' }, async ({ comfyPage }) => { - await comfyPage.loadWorkflow('groups/oversized_group') - await comfyPage.ctrlA() + await comfyPage.workflow.loadWorkflow('groups/oversized_group') + await comfyPage.keyboard.selectAll() await comfyPage.nextFrame() await comfyPage.executeCommand('Comfy.Graph.FitGroupToContents') await comfyPage.nextFrame() @@ -458,7 +480,7 @@ test.describe('Node Interaction', () => { test.describe('Group Interaction', { tag: '@screenshot' }, () => { test('Can double click group title to edit', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('groups/single_group') + await comfyPage.workflow.loadWorkflow('groups/single_group') await comfyPage.canvas.dblclick({ position: { x: 50, @@ -507,7 +529,7 @@ test.describe('Canvas Interaction', { tag: '@screenshot' }, () => { test('Can zoom in/out after decreasing canvas zoom speed setting', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Graph.ZoomSpeed', 1.05) + await comfyPage.settings.setSetting('Comfy.Graph.ZoomSpeed', 1.05) await comfyPage.canvasOps.zoom(-100, 4) await expect(comfyPage.canvas).toHaveScreenshot( 'zoomed-in-low-zoom-speed.png' @@ -516,13 +538,13 @@ test.describe('Canvas Interaction', { tag: '@screenshot' }, () => { await expect(comfyPage.canvas).toHaveScreenshot( 'zoomed-out-low-zoom-speed.png' ) - await comfyPage.setSetting('Comfy.Graph.ZoomSpeed', 1.1) + await comfyPage.settings.setSetting('Comfy.Graph.ZoomSpeed', 1.1) }) test('Can zoom in/out after increasing canvas zoom speed', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Graph.ZoomSpeed', 1.5) + await comfyPage.settings.setSetting('Comfy.Graph.ZoomSpeed', 1.5) await comfyPage.canvasOps.zoom(-100, 4) await expect(comfyPage.canvas).toHaveScreenshot( 'zoomed-in-high-zoom-speed.png' @@ -531,7 +553,7 @@ test.describe('Canvas Interaction', { tag: '@screenshot' }, () => { await expect(comfyPage.canvas).toHaveScreenshot( 'zoomed-out-high-zoom-speed.png' ) - await comfyPage.setSetting('Comfy.Graph.ZoomSpeed', 1.1) + await comfyPage.settings.setSetting('Comfy.Graph.ZoomSpeed', 1.1) }) test('Can pan', async ({ comfyPage }) => { @@ -656,41 +678,41 @@ test.describe('Widget Interaction', () => { await expect(textBox).toHaveValue('') await textBox.fill('Hello World') await expect(textBox).toHaveValue('Hello World') - await comfyPage.ctrlZ(null) + await comfyPage.keyboard.undo(null) await expect(textBox).toHaveValue('') }) test('Undo attention edit', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.EditAttention.Delta', 0.05) + await comfyPage.settings.setSetting('Comfy.EditAttention.Delta', 0.05) const textBox = comfyPage.widgetTextBox await textBox.click() await textBox.fill('1girl') await expect(textBox).toHaveValue('1girl') await textBox.selectText() - await comfyPage.ctrlArrowUp(null) + await comfyPage.keyboard.moveUp(null) await expect(textBox).toHaveValue('(1girl:1.05)') - await comfyPage.ctrlZ(null) + await comfyPage.keyboard.undo(null) await expect(textBox).toHaveValue('1girl') }) }) test.describe('Load workflow', { tag: '@screenshot' }, () => { test('Can load workflow with string node id', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('nodes/string_node_id') + await comfyPage.workflow.loadWorkflow('nodes/string_node_id') await expect(comfyPage.canvas).toHaveScreenshot('string_node_id.png') }) test('Can load workflow with ("STRING",) input node', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('inputs/string_input') + await comfyPage.workflow.loadWorkflow('inputs/string_input') await expect(comfyPage.canvas).toHaveScreenshot('string_input.png') }) test('Restore workflow on reload (switch workflow)', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('nodes/single_ksampler') + await comfyPage.workflow.loadWorkflow('nodes/single_ksampler') await expect(comfyPage.canvas).toHaveScreenshot('single_ksampler.png') await comfyPage.setup({ clearStorage: false }) await expect(comfyPage.canvas).toHaveScreenshot('single_ksampler.png') @@ -699,10 +721,12 @@ test.describe('Load workflow', { tag: '@screenshot' }, () => { test('Restore workflow on reload (modify workflow)', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('nodes/single_ksampler') + await comfyPage.workflow.loadWorkflow('nodes/single_ksampler') const node = (await comfyPage.nodeOps.getFirstNodeRef())! await node.click('collapse') - await comfyPage.clickEmptySpace() + await comfyPage.canvasOps.clickEmptySpace( + DefaultGraphPositions.emptySpaceClick + ) await expect(comfyPage.canvas).toHaveScreenshot( 'single_ksampler_modified.png' ) @@ -720,7 +744,7 @@ test.describe('Load workflow', { tag: '@screenshot' }, () => { `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}${extension}` test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') workflowA = generateUniqueFilename() await comfyPage.menu.topbar.saveWorkflow(workflowA) @@ -738,7 +762,7 @@ test.describe('Load workflow', { tag: '@screenshot' }, () => { test('Restores topbar workflow tabs after reload', async ({ comfyPage }) => { - await comfyPage.setSetting( + await comfyPage.settings.setSetting( 'Comfy.Workflow.WorkflowTabsPosition', 'Topbar' ) @@ -751,7 +775,7 @@ test.describe('Load workflow', { tag: '@screenshot' }, () => { }) test('Restores sidebar workflows after reload', async ({ comfyPage }) => { - await comfyPage.setSetting( + await comfyPage.settings.setSetting( 'Comfy.Workflow.WorkflowTabsPosition', 'Sidebar' ) @@ -774,34 +798,40 @@ test.describe('Load workflow', { tag: '@screenshot' }, () => { }) test('Auto fit view after loading workflow', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.EnableWorkflowViewRestore', false) - await comfyPage.loadWorkflow('nodes/single_ksampler') + await comfyPage.settings.setSetting( + 'Comfy.EnableWorkflowViewRestore', + false + ) + await comfyPage.workflow.loadWorkflow('nodes/single_ksampler') await expect(comfyPage.canvas).toHaveScreenshot('single_ksampler_fit.png') }) }) test.describe('Load duplicate workflow', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') }) test('A workflow can be loaded multiple times in a row', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('nodes/single_ksampler') + await comfyPage.workflow.loadWorkflow('nodes/single_ksampler') await comfyPage.menu.workflowsTab.open() await comfyPage.executeCommand('Comfy.NewBlankWorkflow') - await comfyPage.loadWorkflow('nodes/single_ksampler') + await comfyPage.workflow.loadWorkflow('nodes/single_ksampler') expect(await comfyPage.nodeOps.getGraphNodesCount()).toBe(1) }) }) test.describe('Viewport settings', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') - await comfyPage.setSetting('Comfy.Workflow.WorkflowTabsPosition', 'Topbar') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting( + 'Comfy.Workflow.WorkflowTabsPosition', + 'Topbar' + ) - await comfyPage.setupWorkflowsDirectory({}) + await comfyPage.workflow.setupWorkflowsDirectory({}) }) test('Keeps viewport settings when changing tabs', async ({ @@ -820,11 +850,11 @@ test.describe('Viewport settings', () => { } // Screenshot the canvas element - await comfyPage.setSetting('Comfy.Graph.CanvasMenu', true) + await comfyPage.settings.setSetting('Comfy.Graph.CanvasMenu', true) const toggleButton = comfyPage.page.getByTestId('toggle-minimap-button') await toggleButton.click() - await comfyPage.setSetting('Comfy.Graph.CanvasMenu', false) + await comfyPage.settings.setSetting('Comfy.Graph.CanvasMenu', false) await comfyPage.menu.topbar.saveWorkflow('Workflow A') await comfyPage.nextFrame() @@ -869,7 +899,10 @@ test.describe('Viewport settings', () => { test.describe('Canvas Navigation', { tag: '@screenshot' }, () => { test.describe('Legacy Mode', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Canvas.NavigationMode', 'legacy') + await comfyPage.settings.setSetting( + 'Comfy.Canvas.NavigationMode', + 'legacy' + ) }) test('Left-click drag in empty area should pan canvas', async ({ @@ -911,7 +944,10 @@ test.describe('Canvas Navigation', { tag: '@screenshot' }, () => { }) test('Left-click on node should not pan canvas', async ({ comfyPage }) => { - await comfyPage.clickTextEncodeNode1() + await comfyPage.canvas.click({ + position: DefaultGraphPositions.textEncodeNode1 + }) + await comfyPage.nextFrame() const selectedCount = await comfyPage.nodeOps.getSelectedGraphNodesCount() expect(selectedCount).toBe(1) await expect(comfyPage.canvas).toHaveScreenshot( @@ -922,7 +958,10 @@ test.describe('Canvas Navigation', { tag: '@screenshot' }, () => { test.describe('Standard Mode', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Canvas.NavigationMode', 'standard') + await comfyPage.settings.setSetting( + 'Comfy.Canvas.NavigationMode', + 'standard' + ) }) test('Left-click drag in empty area should select nodes', async ({ @@ -985,7 +1024,10 @@ test.describe('Canvas Navigation', { tag: '@screenshot' }, () => { test('Left-click on node should select node (not start selection box)', async ({ comfyPage }) => { - await comfyPage.clickTextEncodeNode1() + await comfyPage.canvas.click({ + position: DefaultGraphPositions.textEncodeNode1 + }) + await comfyPage.nextFrame() const selectedCount = await comfyPage.nodeOps.getSelectedGraphNodesCount() expect(selectedCount).toBe(1) await expect(comfyPage.canvas).toHaveScreenshot( @@ -1032,7 +1074,9 @@ test.describe('Canvas Navigation', { tag: '@screenshot' }, () => { await comfyPage.nodeOps.getSelectedGraphNodesCount() expect(selectedCountAfterDrag).toBeGreaterThan(0) - await comfyPage.clickEmptySpace() + await comfyPage.canvasOps.clickEmptySpace( + DefaultGraphPositions.emptySpaceClick + ) const selectedCountAfterClear = await comfyPage.nodeOps.getSelectedGraphNodesCount() expect(selectedCountAfterClear).toBe(0) @@ -1059,7 +1103,10 @@ test.describe('Canvas Navigation', { tag: '@screenshot' }, () => { test('Shift + mouse wheel should pan canvas horizontally', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Canvas.MouseWheelScroll', 'panning') + await comfyPage.settings.setSetting( + 'Comfy.Canvas.MouseWheelScroll', + 'panning' + ) await comfyPage.page.click('canvas') await comfyPage.nextFrame() @@ -1097,7 +1144,10 @@ test.describe('Canvas Navigation', { tag: '@screenshot' }, () => { test('Multiple modifier keys work correctly in legacy mode', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Canvas.NavigationMode', 'legacy') + await comfyPage.settings.setSetting( + 'Comfy.Canvas.NavigationMode', + 'legacy' + ) await comfyPage.page.keyboard.down('Alt') await comfyPage.page.keyboard.down('Shift') @@ -1124,7 +1174,10 @@ test.describe('Canvas Navigation', { tag: '@screenshot' }, () => { }) } - await comfyPage.setSetting('Comfy.Canvas.NavigationMode', 'legacy') + await comfyPage.settings.setSetting( + 'Comfy.Canvas.NavigationMode', + 'legacy' + ) await comfyPage.page.mouse.move(50, 50) await comfyPage.page.mouse.down() expect(await getCursorStyle()).toBe('grabbing') diff --git a/browser_tests/tests/keybindings.spec.ts b/browser_tests/tests/keybindings.spec.ts index feb3b0f5d4..a40da0eef3 100644 --- a/browser_tests/tests/keybindings.spec.ts +++ b/browser_tests/tests/keybindings.spec.ts @@ -3,7 +3,7 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Keybindings', { tag: '@keyboard' }, () => { diff --git a/browser_tests/tests/litegraphEvent.spec.ts b/browser_tests/tests/litegraphEvent.spec.ts index 0c2cab4f91..1499acf09d 100644 --- a/browser_tests/tests/litegraphEvent.spec.ts +++ b/browser_tests/tests/litegraphEvent.spec.ts @@ -3,7 +3,7 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) function listenForEvent(): Promise { diff --git a/browser_tests/tests/loadWorkflowInMedia.spec.ts b/browser_tests/tests/loadWorkflowInMedia.spec.ts index 754f373a7b..7254183a74 100644 --- a/browser_tests/tests/loadWorkflowInMedia.spec.ts +++ b/browser_tests/tests/loadWorkflowInMedia.spec.ts @@ -3,7 +3,7 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe( diff --git a/browser_tests/tests/lodThreshold.spec.ts b/browser_tests/tests/lodThreshold.spec.ts index 9c032730be..4741a8e538 100644 --- a/browser_tests/tests/lodThreshold.spec.ts +++ b/browser_tests/tests/lodThreshold.spec.ts @@ -3,7 +3,7 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('LOD Threshold', { tag: ['@screenshot', '@canvas'] }, () => { @@ -11,7 +11,7 @@ test.describe('LOD Threshold', { tag: ['@screenshot', '@canvas'] }, () => { comfyPage }) => { // Load a workflow with some nodes to render - await comfyPage.loadWorkflow('default') + await comfyPage.workflow.loadWorkflow('default') // Get initial LOD state and settings const initialState = await comfyPage.page.evaluate(() => { @@ -84,10 +84,13 @@ test.describe('LOD Threshold', { tag: ['@screenshot', '@canvas'] }, () => { test('Should update threshold when font size setting changes', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('default') + await comfyPage.workflow.loadWorkflow('default') // Change the font size setting to 14px (more aggressive LOD) - await comfyPage.setSetting('LiteGraph.Canvas.MinFontSizeForLOD', 14) + await comfyPage.settings.setSetting( + 'LiteGraph.Canvas.MinFontSizeForLOD', + 14 + ) // Check that font size updated const newState = await comfyPage.page.evaluate(() => { @@ -125,10 +128,10 @@ test.describe('LOD Threshold', { tag: ['@screenshot', '@canvas'] }, () => { test('Should disable LOD when font size is set to 0', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('default') + await comfyPage.workflow.loadWorkflow('default') // Disable LOD by setting font size to 0 - await comfyPage.setSetting('LiteGraph.Canvas.MinFontSizeForLOD', 0) + await comfyPage.settings.setSetting('LiteGraph.Canvas.MinFontSizeForLOD', 0) // Zoom out significantly await comfyPage.canvasOps.zoom(120, 20) // Zoom out 20 steps @@ -154,7 +157,7 @@ test.describe('LOD Threshold', { tag: ['@screenshot', '@canvas'] }, () => { { tag: '@screenshot' }, async ({ comfyPage }) => { // Load a workflow with text-heavy nodes for clear visual difference - await comfyPage.loadWorkflow('default') + await comfyPage.workflow.loadWorkflow('default') // Set zoom level clearly below the threshold to ensure LOD activates const targetZoom = 0.4 // Well below default threshold of ~0.571 @@ -181,7 +184,10 @@ test.describe('LOD Threshold', { tag: ['@screenshot', '@canvas'] }, () => { expect(lowQualityState.lowQuality).toBe(true) // Disable LOD to see high quality at same zoom - await comfyPage.setSetting('LiteGraph.Canvas.MinFontSizeForLOD', 0) + await comfyPage.settings.setSetting( + 'LiteGraph.Canvas.MinFontSizeForLOD', + 0 + ) await comfyPage.nextFrame() // Take snapshot with LOD disabled (full quality at same zoom) diff --git a/browser_tests/tests/menu.spec.ts b/browser_tests/tests/menu.spec.ts index 06ab9a9a88..203ad65f43 100644 --- a/browser_tests/tests/menu.spec.ts +++ b/browser_tests/tests/menu.spec.ts @@ -4,7 +4,7 @@ import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.describe('Menu', { tag: '@ui' }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') }) test('Can register sidebar tab', async ({ comfyPage }) => { @@ -30,11 +30,11 @@ test.describe('Menu', { tag: '@ui' }, () => { test.describe('Workflows topbar tabs', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting( + await comfyPage.settings.setSetting( 'Comfy.Workflow.WorkflowTabsPosition', 'Topbar' ) - await comfyPage.setupWorkflowsDirectory({}) + await comfyPage.workflow.setupWorkflowsDirectory({}) }) test('Can show opened workflows', async ({ comfyPage }) => { @@ -214,7 +214,9 @@ test.describe('Menu', { tag: '@ui' }, () => { await comfyPage.attachScreenshot('theme-menu-light-active') // Verify ColorPalette setting is set to "light" - expect(await comfyPage.getSetting('Comfy.ColorPalette')).toBe('light') + expect(await comfyPage.settings.getSetting('Comfy.ColorPalette')).toBe( + 'light' + ) // Close menu to see theme change await topbar.closeTopbarMenu() @@ -238,7 +240,9 @@ test.describe('Menu', { tag: '@ui' }, () => { await comfyPage.attachScreenshot('theme-menu-dark-active') // Verify ColorPalette setting is set to "dark" - expect(await comfyPage.getSetting('Comfy.ColorPalette')).toBe('dark') + expect(await comfyPage.settings.getSetting('Comfy.ColorPalette')).toBe( + 'dark' + ) // Close menu await topbar.closeTopbarMenu() @@ -251,16 +255,20 @@ test.describe('Menu', { tag: '@ui' }, () => { test(`Can migrate deprecated menu positions (${position})`, async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', position) - expect(await comfyPage.getSetting('Comfy.UseNewMenu')).toBe('Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', position) + expect(await comfyPage.settings.getSetting('Comfy.UseNewMenu')).toBe( + 'Top' + ) }) test(`Can migrate deprecated menu positions on initial load (${position})`, async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', position) + await comfyPage.settings.setSetting('Comfy.UseNewMenu', position) await comfyPage.setup() - expect(await comfyPage.getSetting('Comfy.UseNewMenu')).toBe('Top') + expect(await comfyPage.settings.getSetting('Comfy.UseNewMenu')).toBe( + 'Top' + ) }) }) }) diff --git a/browser_tests/tests/minimap.spec.ts b/browser_tests/tests/minimap.spec.ts index b30adb933a..0e9005ca81 100644 --- a/browser_tests/tests/minimap.spec.ts +++ b/browser_tests/tests/minimap.spec.ts @@ -4,10 +4,10 @@ import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.describe('Minimap', { tag: '@canvas' }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') - await comfyPage.setSetting('Comfy.Minimap.Visible', true) - await comfyPage.setSetting('Comfy.Graph.CanvasMenu', true) - await comfyPage.loadWorkflow('default') + 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') await comfyPage.page.waitForFunction( () => window['app'] && window['app'].canvas ) diff --git a/browser_tests/tests/mobileBaseline.spec.ts b/browser_tests/tests/mobileBaseline.spec.ts index e2f446ea33..521ccf537b 100644 --- a/browser_tests/tests/mobileBaseline.spec.ts +++ b/browser_tests/tests/mobileBaseline.spec.ts @@ -6,7 +6,7 @@ test.describe( { tag: ['@mobile', '@screenshot'] }, () => { test('@mobile empty canvas', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.ConfirmClear', false) + await comfyPage.settings.setSetting('Comfy.ConfirmClear', false) await comfyPage.executeCommand('Comfy.ClearWorkflow') await expect(async () => { expect(await comfyPage.nodeOps.getGraphNodesCount()).toBe(0) @@ -16,7 +16,7 @@ test.describe( }) test('@mobile default workflow', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('default') + await comfyPage.workflow.loadWorkflow('default') await expect(comfyPage.canvas).toHaveScreenshot( 'mobile-default-workflow.png' ) diff --git a/browser_tests/tests/nodeBadge.spec.ts b/browser_tests/tests/nodeBadge.spec.ts index d711f0f599..17955b34bf 100644 --- a/browser_tests/tests/nodeBadge.spec.ts +++ b/browser_tests/tests/nodeBadge.spec.ts @@ -3,9 +3,10 @@ import { expect } from '@playwright/test' import type { ComfyApp } from '../../src/scripts/app' import { NodeBadgeMode } from '../../src/types/nodeSource' import { comfyPageFixture as test } from '../fixtures/ComfyPage' +import { DefaultGraphPositions } from '../fixtures/constants/defaultGraphPositions' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Node Badge', { tag: ['@screenshot', '@smoke', '@node'] }, () => { @@ -73,9 +74,15 @@ test.describe( Object.values(NodeBadgeMode).forEach(async (mode) => { test(`Shows node badges (${mode})`, async ({ comfyPage }) => { // Execution error workflow has both custom node and core node. - await comfyPage.loadWorkflow('nodes/execution_error') - await comfyPage.setSetting('Comfy.NodeBadge.NodeSourceBadgeMode', mode) - await comfyPage.setSetting('Comfy.NodeBadge.NodeIdBadgeMode', mode) + await comfyPage.workflow.loadWorkflow('nodes/execution_error') + await comfyPage.settings.setSetting( + 'Comfy.NodeBadge.NodeSourceBadgeMode', + mode + ) + await comfyPage.settings.setSetting( + 'Comfy.NodeBadge.NodeIdBadgeMode', + mode + ) await comfyPage.nextFrame() await comfyPage.canvasOps.resetView() await expect(comfyPage.canvas).toHaveScreenshot( @@ -93,14 +100,16 @@ test.describe( test('Can show node badge with unknown color palette', async ({ comfyPage }) => { - await comfyPage.setSetting( + await comfyPage.settings.setSetting( 'Comfy.NodeBadge.NodeIdBadgeMode', NodeBadgeMode.ShowAll ) - await comfyPage.setSetting('Comfy.ColorPalette', 'unknown') + await comfyPage.settings.setSetting('Comfy.ColorPalette', 'unknown') await comfyPage.nextFrame() // Click empty space to trigger canvas re-render. - await comfyPage.clickEmptySpace() + await comfyPage.canvasOps.clickEmptySpace( + DefaultGraphPositions.emptySpaceClick + ) await expect(comfyPage.canvas).toHaveScreenshot( 'node-badge-unknown-color-palette.png' ) @@ -109,14 +118,16 @@ test.describe( test('Can show node badge with light color palette', async ({ comfyPage }) => { - await comfyPage.setSetting( + await comfyPage.settings.setSetting( 'Comfy.NodeBadge.NodeIdBadgeMode', NodeBadgeMode.ShowAll ) - await comfyPage.setSetting('Comfy.ColorPalette', 'light') + await comfyPage.settings.setSetting('Comfy.ColorPalette', 'light') await comfyPage.nextFrame() // Click empty space to trigger canvas re-render. - await comfyPage.clickEmptySpace() + await comfyPage.canvasOps.clickEmptySpace( + DefaultGraphPositions.emptySpaceClick + ) await expect(comfyPage.canvas).toHaveScreenshot( 'node-badge-light-color-palette.png' ) diff --git a/browser_tests/tests/nodeDisplay.spec.ts b/browser_tests/tests/nodeDisplay.spec.ts index 4ee96205b7..80a09d38f4 100644 --- a/browser_tests/tests/nodeDisplay.spec.ts +++ b/browser_tests/tests/nodeDisplay.spec.ts @@ -3,39 +3,39 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) // If an input is optional by node definition, it should be shown as // a hollow circle no matter what shape it was defined in the workflow JSON. test.describe('Optional input', { tag: ['@screenshot', '@node'] }, () => { test('No shape specified', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('inputs/optional_input_no_shape') + await comfyPage.workflow.loadWorkflow('inputs/optional_input_no_shape') await expect(comfyPage.canvas).toHaveScreenshot('optional_input.png') }) test('Wrong shape specified', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('inputs/optional_input_wrong_shape') + await comfyPage.workflow.loadWorkflow('inputs/optional_input_wrong_shape') await expect(comfyPage.canvas).toHaveScreenshot('optional_input.png') }) test('Correct shape specified', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('inputs/optional_input_correct_shape') + await comfyPage.workflow.loadWorkflow('inputs/optional_input_correct_shape') await expect(comfyPage.canvas).toHaveScreenshot('optional_input.png') }) test('Force input', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('inputs/force_input') + await comfyPage.workflow.loadWorkflow('inputs/force_input') await expect(comfyPage.canvas).toHaveScreenshot('force_input.png') }) test('Default input', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('inputs/default_input') + await comfyPage.workflow.loadWorkflow('inputs/default_input') await expect(comfyPage.canvas).toHaveScreenshot('default_input.png') }) test('Only optional inputs', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('inputs/only_optional_inputs') + await comfyPage.workflow.loadWorkflow('inputs/only_optional_inputs') expect(await comfyPage.nodeOps.getGraphNodesCount()).toBe(1) await expect( comfyPage.page.locator('.comfy-missing-nodes') @@ -47,7 +47,7 @@ test.describe('Optional input', { tag: ['@screenshot', '@node'] }, () => { ) }) test('Old workflow with converted input', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('inputs/old_workflow_converted_input') + await comfyPage.workflow.loadWorkflow('inputs/old_workflow_converted_input') const node = await comfyPage.nodeOps.getNodeRefById('1') const inputs = await node.getProperty('inputs') const vaeInput = inputs.find((w) => w.name === 'vae') @@ -59,25 +59,30 @@ test.describe('Optional input', { tag: ['@screenshot', '@node'] }, () => { expect(convertedInput.link).not.toBeNull() }) test('Renamed converted input', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('inputs/renamed_converted_widget') + await comfyPage.workflow.loadWorkflow('inputs/renamed_converted_widget') const node = await comfyPage.nodeOps.getNodeRefById('3') const inputs = await node.getProperty('inputs') const renamedInput = inputs.find((w) => w.name === 'breadth') expect(renamedInput).toBeUndefined() }) test('slider', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('inputs/simple_slider') + await comfyPage.workflow.loadWorkflow('inputs/simple_slider') await expect(comfyPage.canvas).toHaveScreenshot('simple_slider.png') }) test('unknown converted widget', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Workflow.ShowMissingNodesWarning', false) - await comfyPage.loadWorkflow('missing/missing_nodes_converted_widget') + await comfyPage.settings.setSetting( + 'Comfy.Workflow.ShowMissingNodesWarning', + false + ) + await comfyPage.workflow.loadWorkflow( + 'missing/missing_nodes_converted_widget' + ) await expect(comfyPage.canvas).toHaveScreenshot( 'missing_nodes_converted_widget.png' ) }) test('dynamically added input', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('inputs/dynamically_added_input') + await comfyPage.workflow.loadWorkflow('inputs/dynamically_added_input') await expect(comfyPage.canvas).toHaveScreenshot( 'dynamically_added_input.png' ) diff --git a/browser_tests/tests/nodeHelp.spec.ts b/browser_tests/tests/nodeHelp.spec.ts index e1134de52b..615da8bb35 100644 --- a/browser_tests/tests/nodeHelp.spec.ts +++ b/browser_tests/tests/nodeHelp.spec.ts @@ -26,14 +26,14 @@ async function selectNodeWithPan(comfyPage: ComfyPage, nodeRef: NodeReference) { test.describe('Node Help', { tag: ['@slow', '@ui'] }, () => { test.beforeEach(async ({ comfyPage }) => { await comfyPage.setup() - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') }) test.describe('Selection Toolbox', () => { test('Should open help menu for selected node', async ({ comfyPage }) => { // Load a workflow with a node - await comfyPage.setSetting('Comfy.Canvas.SelectionToolbox', true) - await comfyPage.loadWorkflow('default') + await comfyPage.settings.setSetting('Comfy.Canvas.SelectionToolbox', true) + await comfyPage.workflow.loadWorkflow('default') // Select a single node (KSampler) using node references const ksamplerNodes = @@ -146,7 +146,7 @@ test.describe('Node Help', { tag: ['@slow', '@ui'] }, () => { test.describe('Help Content', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Canvas.SelectionToolbox', true) + await comfyPage.settings.setSetting('Comfy.Canvas.SelectionToolbox', true) }) test('Should display loading state while fetching help', async ({ @@ -162,7 +162,7 @@ test.describe('Node Help', { tag: ['@slow', '@ui'] }, () => { }) // Load workflow and select a node - await comfyPage.loadWorkflow('default') + await comfyPage.workflow.loadWorkflow('default') const ksamplerNodes = await comfyPage.nodeOps.getNodeRefsByType('KSampler') await selectNodeWithPan(comfyPage, ksamplerNodes[0]) @@ -195,7 +195,7 @@ test.describe('Node Help', { tag: ['@slow', '@ui'] }, () => { }) // Load workflow and select a node - await comfyPage.loadWorkflow('default') + await comfyPage.workflow.loadWorkflow('default') const ksamplerNodes = await comfyPage.nodeOps.getNodeRefsByType('KSampler') await selectNodeWithPan(comfyPage, ksamplerNodes[0]) @@ -233,7 +233,7 @@ test.describe('Node Help', { tag: ['@slow', '@ui'] }, () => { }) }) - await comfyPage.loadWorkflow('default') + await comfyPage.workflow.loadWorkflow('default') const ksamplerNodes = await comfyPage.nodeOps.getNodeRefsByType('KSampler') await selectNodeWithPan(comfyPage, ksamplerNodes[0]) @@ -284,7 +284,7 @@ test.describe('Node Help', { tag: ['@slow', '@ui'] }, () => { }) }) - await comfyPage.loadWorkflow('default') + await comfyPage.workflow.loadWorkflow('default') const ksamplerNodes = await comfyPage.nodeOps.getNodeRefsByType('KSampler') await selectNodeWithPan(comfyPage, ksamplerNodes[0]) @@ -332,7 +332,7 @@ test.describe('Node Help', { tag: ['@slow', '@ui'] }, () => { comfyPage }) => { // First load workflow with custom node - await comfyPage.loadWorkflow('groupnodes/group_node_v1.3.3') + await comfyPage.workflow.loadWorkflow('groupnodes/group_node_v1.3.3') // Mock custom node documentation with fallback await comfyPage.page.route( @@ -402,7 +402,7 @@ This is documentation for a custom node. }) }) - await comfyPage.loadWorkflow('default') + await comfyPage.workflow.loadWorkflow('default') const ksamplerNodes = await comfyPage.nodeOps.getNodeRefsByType('KSampler') await selectNodeWithPan(comfyPage, ksamplerNodes[0]) @@ -470,9 +470,9 @@ This is English documentation. }) // Set locale to Japanese - await comfyPage.setSetting('Comfy.Locale', 'ja') + await comfyPage.settings.setSetting('Comfy.Locale', 'ja') - await comfyPage.loadWorkflow('default') + await comfyPage.workflow.loadWorkflow('default') const ksamplerNodes = await comfyPage.nodeOps.getNodeRefsByType('KSampler') await selectNodeWithPan(comfyPage, ksamplerNodes[0]) @@ -489,7 +489,7 @@ This is English documentation. await expect(helpPage).toContainText('これは日本語のドキュメントです') // Reset locale - await comfyPage.setSetting('Comfy.Locale', 'en') + await comfyPage.settings.setSetting('Comfy.Locale', 'en') }) test('Should handle network errors gracefully', async ({ comfyPage }) => { @@ -498,7 +498,7 @@ This is English documentation. await route.abort('failed') }) - await comfyPage.loadWorkflow('default') + await comfyPage.workflow.loadWorkflow('default') const ksamplerNodes = await comfyPage.nodeOps.getNodeRefsByType('KSampler') await selectNodeWithPan(comfyPage, ksamplerNodes[0]) @@ -542,7 +542,7 @@ This is English documentation. } ) - await comfyPage.loadWorkflow('default') + await comfyPage.workflow.loadWorkflow('default') await fitToViewInstant(comfyPage) // Select KSampler first diff --git a/browser_tests/tests/nodeSearchBox.spec.ts b/browser_tests/tests/nodeSearchBox.spec.ts index 811fd69491..f30fb29aab 100644 --- a/browser_tests/tests/nodeSearchBox.spec.ts +++ b/browser_tests/tests/nodeSearchBox.spec.ts @@ -4,14 +4,20 @@ import { } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Node search box', { tag: '@node' }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.LinkRelease.Action', 'search box') - await comfyPage.setSetting('Comfy.LinkRelease.ActionShift', 'search box') - await comfyPage.setSetting('Comfy.NodeSearchBoxImpl', 'default') + await comfyPage.settings.setSetting( + 'Comfy.LinkRelease.Action', + 'search box' + ) + await comfyPage.settings.setSetting( + 'Comfy.LinkRelease.ActionShift', + 'search box' + ) + await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'default') }) test(`Can trigger on empty canvas double click`, async ({ comfyPage }) => { @@ -20,7 +26,7 @@ test.describe('Node search box', { tag: '@node' }, () => { }) test(`Can trigger on group body double click`, async ({ comfyPage }) => { - await comfyPage.loadWorkflow('groups/single_group_only') + await comfyPage.workflow.loadWorkflow('groups/single_group_only') await comfyPage.page.mouse.dblclick(50, 50, { delay: 5 }) await comfyPage.nextFrame() await expect(comfyPage.searchBox.input).toHaveCount(1) @@ -37,8 +43,8 @@ test.describe('Node search box', { tag: '@node' }, () => { // Start fresh to test new user behavior await comfyPage.setup({ clearStorage: true }) // Simulate new user with 1.24.1+ installed version - await comfyPage.setSetting('Comfy.InstalledVersion', '1.24.1') - await comfyPage.setSetting('Comfy.NodeSearchBoxImpl', 'default') + await comfyPage.settings.setSetting('Comfy.InstalledVersion', '1.24.1') + await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'default') // Don't set LinkRelease settings explicitly to test versioned defaults await comfyPage.disconnectEdge() @@ -66,7 +72,7 @@ test.describe('Node search box', { tag: '@node' }, () => { 'Can auto link batch moved node', { tag: '@screenshot' }, async ({ comfyPage }) => { - await comfyPage.loadWorkflow('links/batch_move_links') + await comfyPage.workflow.loadWorkflow('links/batch_move_links') // Get the CLIP output slot (index 1) from the first CheckpointLoaderSimple node (id: 4) const checkpointNode = await comfyPage.nodeOps.getNodeRefById(4) @@ -117,7 +123,7 @@ test.describe('Node search box', { tag: '@node' }, () => { test('@mobile Can trigger on empty canvas tap', async ({ comfyPage }) => { await comfyPage.closeMenu() - await comfyPage.loadWorkflow('nodes/single_ksampler') + await comfyPage.workflow.loadWorkflow('nodes/single_ksampler') const screenCenter = { x: 200, y: 400 @@ -259,9 +265,15 @@ test.describe('Node search box', { tag: '@node' }, () => { test.describe('Release context menu', { tag: '@node' }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.LinkRelease.Action', 'context menu') - await comfyPage.setSetting('Comfy.LinkRelease.ActionShift', 'search box') - await comfyPage.setSetting('Comfy.NodeSearchBoxImpl', 'default') + await comfyPage.settings.setSetting( + 'Comfy.LinkRelease.Action', + 'context menu' + ) + await comfyPage.settings.setSetting( + 'Comfy.LinkRelease.ActionShift', + 'search box' + ) + await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'default') }) test( @@ -289,7 +301,8 @@ test.describe('Release context menu', { tag: '@node' }, () => { async ({ comfyPage, comfyMouse }) => { await comfyPage.disconnectEdge() await comfyMouse.move({ x: 10, y: 10 }) - await comfyPage.clickContextMenuItem('Search') + await comfyPage.contextMenu.clickMenuItem('Search') + await comfyPage.nextFrame() await comfyPage.searchBox.fillAndSelectFirstNode('CLIP Prompt') await expect(comfyPage.canvas).toHaveScreenshot( 'link-context-menu-search.png' @@ -303,8 +316,8 @@ test.describe('Release context menu', { tag: '@node' }, () => { // Start fresh to test existing user behavior await comfyPage.setup({ clearStorage: true }) // Simulate existing user with pre-1.24.1 version - await comfyPage.setSetting('Comfy.InstalledVersion', '1.23.0') - await comfyPage.setSetting('Comfy.NodeSearchBoxImpl', 'default') + await comfyPage.settings.setSetting('Comfy.InstalledVersion', '1.23.0') + await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'default') // Don't set LinkRelease settings explicitly to test versioned defaults await comfyPage.disconnectEdge() @@ -319,10 +332,13 @@ test.describe('Release context menu', { tag: '@node' }, () => { }) => { // Start fresh and simulate new user who should get search box by default await comfyPage.setup({ clearStorage: true }) - await comfyPage.setSetting('Comfy.InstalledVersion', '1.24.1') + await comfyPage.settings.setSetting('Comfy.InstalledVersion', '1.24.1') // But explicitly set to context menu (overriding versioned default) - await comfyPage.setSetting('Comfy.LinkRelease.Action', 'context menu') - await comfyPage.setSetting('Comfy.NodeSearchBoxImpl', 'default') + await comfyPage.settings.setSetting( + 'Comfy.LinkRelease.Action', + 'context menu' + ) + await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'default') await comfyPage.disconnectEdge() // Context menu should appear due to explicit setting, not search box diff --git a/browser_tests/tests/noteNode.spec.ts b/browser_tests/tests/noteNode.spec.ts index 4bb5519625..c50a533ea5 100644 --- a/browser_tests/tests/noteNode.spec.ts +++ b/browser_tests/tests/noteNode.spec.ts @@ -3,12 +3,12 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Note Node', { tag: '@node' }, () => { test('Can load node nodes', { tag: '@screenshot' }, async ({ comfyPage }) => { - await comfyPage.loadWorkflow('nodes/note_nodes') + await comfyPage.workflow.loadWorkflow('nodes/note_nodes') await expect(comfyPage.canvas).toHaveScreenshot('note_nodes.png') }) }) diff --git a/browser_tests/tests/primitiveNode.spec.ts b/browser_tests/tests/primitiveNode.spec.ts index e6c234fa22..aa0e029e03 100644 --- a/browser_tests/tests/primitiveNode.spec.ts +++ b/browser_tests/tests/primitiveNode.spec.ts @@ -4,19 +4,21 @@ import { comfyPageFixture as test } from '../fixtures/ComfyPage' import type { NodeReference } from '../fixtures/utils/litegraphUtils' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Primitive Node', { tag: ['@screenshot', '@node'] }, () => { test('Can load with correct size', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('primitive/primitive_node') + await comfyPage.workflow.loadWorkflow('primitive/primitive_node') await expect(comfyPage.canvas).toHaveScreenshot('primitive_node.png') }) // When link is dropped on widget, it should automatically convert the widget // to input. test('Can connect to widget', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('primitive/primitive_node_unconnected') + await comfyPage.workflow.loadWorkflow( + 'primitive/primitive_node_unconnected' + ) const primitiveNode: NodeReference = await comfyPage.nodeOps.getNodeRefById(1) const ksamplerNode: NodeReference = @@ -29,7 +31,7 @@ test.describe('Primitive Node', { tag: ['@screenshot', '@node'] }, () => { }) test('Can connect to dom widget', async ({ comfyPage }) => { - await comfyPage.loadWorkflow( + await comfyPage.workflow.loadWorkflow( 'primitive/primitive_node_unconnected_dom_widget' ) const primitiveNode: NodeReference = @@ -43,7 +45,9 @@ test.describe('Primitive Node', { tag: ['@screenshot', '@node'] }, () => { }) test('Can connect to static primitive node', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('primitive/static_primitive_unconnected') + await comfyPage.workflow.loadWorkflow( + 'primitive/static_primitive_unconnected' + ) const primitiveNode: NodeReference = await comfyPage.nodeOps.getNodeRefById(1) const ksamplerNode: NodeReference = @@ -57,7 +61,7 @@ test.describe('Primitive Node', { tag: ['@screenshot', '@node'] }, () => { test('Report missing nodes when connect to missing node', async ({ comfyPage }) => { - await comfyPage.loadWorkflow( + await comfyPage.workflow.loadWorkflow( 'primitive/primitive_node_connect_missing_node' ) // Wait for the element with the .comfy-missing-nodes selector to be visible diff --git a/browser_tests/tests/propertiesPanel/propertiesPanelPosition.spec.ts b/browser_tests/tests/propertiesPanel/propertiesPanelPosition.spec.ts index ee2c85eda0..65f097d413 100644 --- a/browser_tests/tests/propertiesPanel/propertiesPanelPosition.spec.ts +++ b/browser_tests/tests/propertiesPanel/propertiesPanelPosition.spec.ts @@ -12,7 +12,7 @@ test.describe('Properties panel position', () => { test('positions on the right when sidebar is on the left', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Sidebar.Location', 'left') + await comfyPage.settings.setSetting('Comfy.Sidebar.Location', 'left') await comfyPage.nextFrame() const propertiesPanel = comfyPage.page.getByTestId('properties-panel') @@ -36,7 +36,7 @@ test.describe('Properties panel position', () => { test('positions on the left when sidebar is on the right', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Sidebar.Location', 'right') + await comfyPage.settings.setSetting('Comfy.Sidebar.Location', 'right') await comfyPage.nextFrame() const propertiesPanel = comfyPage.page.getByTestId('properties-panel') @@ -63,7 +63,7 @@ test.describe('Properties panel position', () => { const propertiesPanel = comfyPage.page.getByTestId('properties-panel') // When sidebar is on the left, panel is on the right - await comfyPage.setSetting('Comfy.Sidebar.Location', 'left') + await comfyPage.settings.setSetting('Comfy.Sidebar.Location', 'left') await comfyPage.nextFrame() await expect(propertiesPanel).toBeVisible() @@ -74,7 +74,7 @@ test.describe('Properties panel position', () => { await expect(closeButtonLeft).toHaveClass(/lucide--panel-right/) // When sidebar is on the right, panel is on the left - await comfyPage.setSetting('Comfy.Sidebar.Location', 'right') + await comfyPage.settings.setSetting('Comfy.Sidebar.Location', 'right') await comfyPage.nextFrame() const closeButtonRight = propertiesPanel diff --git a/browser_tests/tests/recordAudio.spec.ts b/browser_tests/tests/recordAudio.spec.ts index 4436ecdfba..07d9c48081 100644 --- a/browser_tests/tests/recordAudio.spec.ts +++ b/browser_tests/tests/recordAudio.spec.ts @@ -3,7 +3,7 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Record Audio Node', { tag: '@screenshot' }, () => { diff --git a/browser_tests/tests/releaseNotifications.spec.ts b/browser_tests/tests/releaseNotifications.spec.ts index a45527de7e..472470e8ea 100644 --- a/browser_tests/tests/releaseNotifications.spec.ts +++ b/browser_tests/tests/releaseNotifications.spec.ts @@ -4,7 +4,7 @@ import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.describe('Release Notifications', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') }) test('should show help center with release information', async ({ @@ -135,7 +135,10 @@ test.describe('Release Notifications', () => { comfyPage }) => { // Disable version update notifications - await comfyPage.setSetting('Comfy.Notification.ShowVersionUpdates', false) + await comfyPage.settings.setSetting( + 'Comfy.Notification.ShowVersionUpdates', + false + ) // Mock release API with test data await comfyPage.page.route('**/releases**', async (route) => { @@ -189,7 +192,10 @@ test.describe('Release Notifications', () => { comfyPage }) => { // Disable version update notifications - await comfyPage.setSetting('Comfy.Notification.ShowVersionUpdates', false) + await comfyPage.settings.setSetting( + 'Comfy.Notification.ShowVersionUpdates', + false + ) // Track API calls let apiCallCount = 0 @@ -220,7 +226,10 @@ test.describe('Release Notifications', () => { comfyPage }) => { // Enable version update notifications (default behavior) - await comfyPage.setSetting('Comfy.Notification.ShowVersionUpdates', true) + await comfyPage.settings.setSetting( + 'Comfy.Notification.ShowVersionUpdates', + true + ) // Mock release API with test data await comfyPage.page.route('**/releases**', async (route) => { @@ -299,7 +308,10 @@ test.describe('Release Notifications', () => { }) // Start with notifications enabled - await comfyPage.setSetting('Comfy.Notification.ShowVersionUpdates', true) + await comfyPage.settings.setSetting( + 'Comfy.Notification.ShowVersionUpdates', + true + ) await comfyPage.setup({ mockReleases: false }) // Open help center @@ -315,7 +327,10 @@ test.describe('Release Notifications', () => { await comfyPage.page.click('.help-center-backdrop') // Disable notifications - await comfyPage.setSetting('Comfy.Notification.ShowVersionUpdates', false) + await comfyPage.settings.setSetting( + 'Comfy.Notification.ShowVersionUpdates', + false + ) // Reopen help center await helpCenterButton.click() @@ -328,7 +343,10 @@ test.describe('Release Notifications', () => { comfyPage }) => { // Disable notifications - await comfyPage.setSetting('Comfy.Notification.ShowVersionUpdates', false) + await comfyPage.settings.setSetting( + 'Comfy.Notification.ShowVersionUpdates', + false + ) // Mock empty releases await comfyPage.page.route('**/releases**', async (route) => { diff --git a/browser_tests/tests/remoteWidgets.spec.ts b/browser_tests/tests/remoteWidgets.spec.ts index d5890e122a..e15b76a2d2 100644 --- a/browser_tests/tests/remoteWidgets.spec.ts +++ b/browser_tests/tests/remoteWidgets.spec.ts @@ -52,12 +52,12 @@ test.describe('Remote COMBO Widget', { tag: '@widget' }, () => { } test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') }) test.describe('Loading options', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') await comfyPage.page.route( '**/api/models/checkpoints**', async (route, request) => { @@ -89,7 +89,7 @@ test.describe('Remote COMBO Widget', { tag: '@widget' }, () => { comfyPage }) => { const nodeName = 'Remote Widget Node' - await comfyPage.loadWorkflow('inputs/remote_widget') + await comfyPage.workflow.loadWorkflow('inputs/remote_widget') const node = await comfyPage.page.evaluate((name) => { return window['app'].graph.nodes.find((node) => node.title === name) @@ -176,7 +176,7 @@ test.describe('Remote COMBO Widget', { tag: '@widget' }, () => { test('refresh button is visible in selection toolbar when node is selected', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Canvas.SelectionToolbox', true) + await comfyPage.settings.setSetting('Comfy.Canvas.SelectionToolbox', true) const nodeName = 'Remote Widget Node' await addRemoteWidgetNode(comfyPage, nodeName) diff --git a/browser_tests/tests/rerouteNode.spec.ts b/browser_tests/tests/rerouteNode.spec.ts index 2ab9eace89..93f92d1d50 100644 --- a/browser_tests/tests/rerouteNode.spec.ts +++ b/browser_tests/tests/rerouteNode.spec.ts @@ -5,16 +5,16 @@ import { getMiddlePoint } from '../fixtures/utils/litegraphUtils' test.describe('Reroute Node', { tag: ['@screenshot', '@node'] }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') }) test.afterEach(async ({ comfyPage }) => { - await comfyPage.setupWorkflowsDirectory({}) + await comfyPage.workflow.setupWorkflowsDirectory({}) }) test('loads from inserted workflow', async ({ comfyPage }) => { const workflowName = 'single_connected_reroute_node.json' - await comfyPage.setupWorkflowsDirectory({ + await comfyPage.workflow.setupWorkflowsDirectory({ [workflowName]: 'links/single_connected_reroute_node.json' }) await comfyPage.setup() @@ -43,12 +43,12 @@ test.describe( { tag: ['@screenshot', '@node'] }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') - await comfyPage.setSetting('LiteGraph.Reroute.SplineOffset', 80) + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('LiteGraph.Reroute.SplineOffset', 80) }) test('loads from workflow', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('reroute/native_reroute') + await comfyPage.workflow.loadWorkflow('reroute/native_reroute') await expect(comfyPage.canvas).toHaveScreenshot('native_reroute.png') }) @@ -109,7 +109,7 @@ test.describe( comfyPage }) => { // https://github.com/Comfy-Org/ComfyUI_frontend/issues/4695 - await comfyPage.loadWorkflow( + await comfyPage.workflow.loadWorkflow( 'reroute/single-native-reroute-default-workflow' ) diff --git a/browser_tests/tests/rightClickMenu.spec.ts b/browser_tests/tests/rightClickMenu.spec.ts index 44af79089b..757b131f41 100644 --- a/browser_tests/tests/rightClickMenu.spec.ts +++ b/browser_tests/tests/rightClickMenu.spec.ts @@ -4,7 +4,7 @@ import { NodeBadgeMode } from '../../src/types/nodeSource' import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe( @@ -37,7 +37,10 @@ test.describe( await comfyPage.nodeOps.selectNodes(['CLIP Text Encode (Prompt)']) await expect(comfyPage.canvas).toHaveScreenshot('selected-2-nodes.png') await comfyPage.canvasOps.rightClick() - await comfyPage.clickContextMenuItem('Convert to Group Node (Deprecated)') + await comfyPage.contextMenu.clickMenuItem( + 'Convert to Group Node (Deprecated)' + ) + await comfyPage.nextFrame() await comfyPage.promptDialogInput.fill('GroupNode2CLIP') await comfyPage.page.keyboard.press('Enter') await comfyPage.promptDialogInput.waitFor({ state: 'hidden' }) @@ -51,7 +54,12 @@ test.describe( test.describe('Node Right Click Menu', { tag: ['@screenshot', '@ui'] }, () => { test('Can open properties panel', async ({ comfyPage }) => { - await comfyPage.rightClickEmptyLatentNode() + await comfyPage.canvas.click({ + position: { x: 724, y: 645 }, + button: 'right' + }) + await comfyPage.page.mouse.move(10, 10) + await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot('right-click-node.png') await comfyPage.page.getByText('Properties Panel').click() await comfyPage.nextFrame() @@ -61,7 +69,12 @@ test.describe('Node Right Click Menu', { tag: ['@screenshot', '@ui'] }, () => { }) test('Can collapse', async ({ comfyPage }) => { - await comfyPage.rightClickEmptyLatentNode() + await comfyPage.canvas.click({ + position: { x: 724, y: 645 }, + button: 'right' + }) + await comfyPage.page.mouse.move(10, 10) + await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot('right-click-node.png') await comfyPage.page.getByText('Collapse').click() await comfyPage.nextFrame() @@ -71,16 +84,21 @@ test.describe('Node Right Click Menu', { tag: ['@screenshot', '@ui'] }, () => { }) test('Can collapse (Node Badge)', async ({ comfyPage }) => { - await comfyPage.setSetting( + await comfyPage.settings.setSetting( 'Comfy.NodeBadge.NodeIdBadgeMode', NodeBadgeMode.ShowAll ) - await comfyPage.setSetting( + await comfyPage.settings.setSetting( 'Comfy.NodeBadge.NodeSourceBadgeMode', NodeBadgeMode.ShowAll ) - await comfyPage.rightClickEmptyLatentNode() + await comfyPage.canvas.click({ + position: { x: 724, y: 645 }, + button: 'right' + }) + await comfyPage.page.mouse.move(10, 10) + await comfyPage.nextFrame() await comfyPage.page.getByText('Collapse').click() await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot( @@ -89,7 +107,12 @@ test.describe('Node Right Click Menu', { tag: ['@screenshot', '@ui'] }, () => { }) test('Can bypass', async ({ comfyPage }) => { - await comfyPage.rightClickEmptyLatentNode() + await comfyPage.canvas.click({ + position: { x: 724, y: 645 }, + button: 'right' + }) + await comfyPage.page.mouse.move(10, 10) + await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot('right-click-node.png') await comfyPage.page.getByText('Bypass').click() await comfyPage.nextFrame() @@ -99,7 +122,12 @@ test.describe('Node Right Click Menu', { tag: ['@screenshot', '@ui'] }, () => { }) test('Can pin and unpin', async ({ comfyPage }) => { - await comfyPage.rightClickEmptyLatentNode() + await comfyPage.canvas.click({ + position: { x: 724, y: 645 }, + button: 'right' + }) + await comfyPage.page.mouse.move(10, 10) + await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot('right-click-node.png') await comfyPage.page.click('.litemenu-entry:has-text("Pin")') await comfyPage.nextFrame() @@ -109,23 +137,43 @@ test.describe('Node Right Click Menu', { tag: ['@screenshot', '@ui'] }, () => { const titlePos = await emptyLatentNode.getTitlePosition() await comfyPage.canvasOps.dragAndDrop(titlePos, { x: 16, y: 16 }) await expect(comfyPage.canvas).toHaveScreenshot('node-pinned.png') - await comfyPage.rightClickEmptyLatentNode() + await comfyPage.canvas.click({ + position: { x: 724, y: 645 }, + button: 'right' + }) + await comfyPage.page.mouse.move(10, 10) + await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot( 'right-click-pinned-node.png' ) await comfyPage.page.click('.litemenu-entry:has-text("Unpin")') await comfyPage.nextFrame() - await comfyPage.rightClickEmptyLatentNode() + await comfyPage.canvas.click({ + position: { x: 724, y: 645 }, + button: 'right' + }) + await comfyPage.page.mouse.move(10, 10) + await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot( 'right-click-unpinned-node.png' ) }) test('Can move after unpin', async ({ comfyPage }) => { - await comfyPage.rightClickEmptyLatentNode() + await comfyPage.canvas.click({ + position: { x: 724, y: 645 }, + button: 'right' + }) + await comfyPage.page.mouse.move(10, 10) + await comfyPage.nextFrame() await comfyPage.page.click('.litemenu-entry:has-text("Pin")') await comfyPage.nextFrame() - await comfyPage.rightClickEmptyLatentNode() + await comfyPage.canvas.click({ + position: { x: 724, y: 645 }, + button: 'right' + }) + await comfyPage.page.mouse.move(10, 10) + await comfyPage.nextFrame() await comfyPage.page.click('.litemenu-entry:has-text("Unpin")') await comfyPage.nextFrame() @@ -141,12 +189,22 @@ test.describe('Node Right Click Menu', { tag: ['@screenshot', '@ui'] }, () => { test('Can pin/unpin selected nodes', async ({ comfyPage }) => { await comfyPage.nodeOps.selectNodes(['CLIP Text Encode (Prompt)']) await comfyPage.page.keyboard.down('Control') - await comfyPage.rightClickEmptyLatentNode() + await comfyPage.canvas.click({ + position: { x: 724, y: 645 }, + button: 'right' + }) + await comfyPage.page.mouse.move(10, 10) + await comfyPage.nextFrame() await comfyPage.page.click('.litemenu-entry:has-text("Pin")') await comfyPage.page.keyboard.up('Control') await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot('selected-nodes-pinned.png') - await comfyPage.rightClickEmptyLatentNode() + await comfyPage.canvas.click({ + position: { x: 724, y: 645 }, + button: 'right' + }) + await comfyPage.page.mouse.move(10, 10) + await comfyPage.nextFrame() await comfyPage.page.click('.litemenu-entry:has-text("Unpin")') await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot( diff --git a/browser_tests/tests/selectionToolbox.spec.ts b/browser_tests/tests/selectionToolbox.spec.ts index f31ba34acf..fb0966d808 100644 --- a/browser_tests/tests/selectionToolbox.spec.ts +++ b/browser_tests/tests/selectionToolbox.spec.ts @@ -5,14 +5,14 @@ import { comfyPageFixture } from '../fixtures/ComfyPage' const test = comfyPageFixture test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) const BLUE_COLOR = 'rgb(51, 51, 85)' const RED_COLOR = 'rgb(85, 51, 51)' test.describe('Selection Toolbox', { tag: ['@screenshot', '@ui'] }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Canvas.SelectionToolbox', true) + await comfyPage.settings.setSetting('Comfy.Canvas.SelectionToolbox', true) }) test('shows selection toolbox', async ({ comfyPage }) => { @@ -36,11 +36,11 @@ test.describe('Selection Toolbox', { tag: ['@screenshot', '@ui'] }, () => { test('shows at correct position when node is pasted', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('nodes/single_ksampler') + await comfyPage.workflow.loadWorkflow('nodes/single_ksampler') await comfyPage.nodeOps.selectNodes(['KSampler']) - await comfyPage.ctrlC() + await comfyPage.clipboard.copy() await comfyPage.page.mouse.move(100, 100) - await comfyPage.ctrlV() + await comfyPage.clipboard.paste() const toolboxContainer = comfyPage.selectionToolbox await expect(toolboxContainer).toBeVisible() @@ -57,7 +57,7 @@ test.describe('Selection Toolbox', { tag: ['@screenshot', '@ui'] }, () => { test('hide when select and drag happen at the same time', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('nodes/single_ksampler') + await comfyPage.workflow.loadWorkflow('nodes/single_ksampler') const node = (await comfyPage.nodeOps.getNodeRefsByTitle('KSampler'))[0] const nodePos = await node.getPosition() @@ -104,7 +104,7 @@ test.describe('Selection Toolbox', { tag: ['@screenshot', '@ui'] }, () => { comfyPage }) => { // A group + a KSampler node - await comfyPage.loadWorkflow('groups/single_group') + await comfyPage.workflow.loadWorkflow('groups/single_group') // Select group + node should show bypass button await comfyPage.page.focus('canvas') diff --git a/browser_tests/tests/selectionToolboxSubmenus.spec.ts b/browser_tests/tests/selectionToolboxSubmenus.spec.ts index c80384d1e5..7fbc5a7deb 100644 --- a/browser_tests/tests/selectionToolboxSubmenus.spec.ts +++ b/browser_tests/tests/selectionToolboxSubmenus.spec.ts @@ -4,7 +4,7 @@ import { comfyPageFixture as test } from '../fixtures/ComfyPage' import type { ComfyPage } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe( @@ -12,8 +12,8 @@ test.describe( { tag: '@ui' }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Canvas.SelectionToolbox', true) - await comfyPage.loadWorkflow('nodes/single_ksampler') + await comfyPage.settings.setSetting('Comfy.Canvas.SelectionToolbox', true) + await comfyPage.workflow.loadWorkflow('nodes/single_ksampler') await comfyPage.nextFrame() await comfyPage.nodeOps.selectNodes(['KSampler']) await comfyPage.nextFrame() diff --git a/browser_tests/tests/sidebar/nodeLibrary.spec.ts b/browser_tests/tests/sidebar/nodeLibrary.spec.ts index b5ad059b18..1049a236c1 100644 --- a/browser_tests/tests/sidebar/nodeLibrary.spec.ts +++ b/browser_tests/tests/sidebar/nodeLibrary.spec.ts @@ -4,9 +4,12 @@ import { comfyPageFixture as test } from '../../fixtures/ComfyPage' test.describe('Node library sidebar', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') - await comfyPage.setSetting('Comfy.NodeLibrary.Bookmarks.V2', []) - await comfyPage.setSetting('Comfy.NodeLibrary.BookmarksCustomization', {}) + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.NodeLibrary.Bookmarks.V2', []) + await comfyPage.settings.setSetting( + 'Comfy.NodeLibrary.BookmarksCustomization', + {} + ) // Open the sidebar const tab = comfyPage.menu.nodeLibraryTab await tab.open() @@ -58,7 +61,7 @@ test.describe('Node library sidebar', () => { // Verify the bookmark is added to the bookmarks tab expect( - await comfyPage.getSetting('Comfy.NodeLibrary.Bookmarks.V2') + await comfyPage.settings.getSetting('Comfy.NodeLibrary.Bookmarks.V2') ).toEqual(['KSamplerAdvanced']) // Verify the bookmark node with the same name is added to the tree. expect(await tab.getNode('KSampler (Advanced)').count()).toBe(2) @@ -69,7 +72,9 @@ test.describe('Node library sidebar', () => { }) test('Ignores unrecognized node', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.NodeLibrary.Bookmarks.V2', ['foo']) + await comfyPage.settings.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [ + 'foo' + ]) const tab = comfyPage.menu.nodeLibraryTab expect(await tab.getFolder('sampling').count()).toBe(1) @@ -77,7 +82,9 @@ test.describe('Node library sidebar', () => { }) test('Displays empty bookmarks folder', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.NodeLibrary.Bookmarks.V2', ['foo/']) + await comfyPage.settings.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [ + 'foo/' + ]) const tab = comfyPage.menu.nodeLibraryTab expect(await tab.getFolder('foo').count()).toBe(1) }) @@ -91,12 +98,14 @@ test.describe('Node library sidebar', () => { await textInput.press('Enter') expect(await tab.getFolder('New Folder').count()).toBe(1) expect( - await comfyPage.getSetting('Comfy.NodeLibrary.Bookmarks.V2') + await comfyPage.settings.getSetting('Comfy.NodeLibrary.Bookmarks.V2') ).toEqual(['New Folder/']) }) test('Can add nested bookmark folder', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.NodeLibrary.Bookmarks.V2', ['foo/']) + await comfyPage.settings.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [ + 'foo/' + ]) const tab = comfyPage.menu.nodeLibraryTab await tab.getFolder('foo').click({ button: 'right' }) @@ -108,24 +117,28 @@ test.describe('Node library sidebar', () => { expect(await tab.getFolder('bar').count()).toBe(1) expect( - await comfyPage.getSetting('Comfy.NodeLibrary.Bookmarks.V2') + await comfyPage.settings.getSetting('Comfy.NodeLibrary.Bookmarks.V2') ).toEqual(['foo/', 'foo/bar/']) }) test('Can delete bookmark folder', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.NodeLibrary.Bookmarks.V2', ['foo/']) + await comfyPage.settings.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [ + 'foo/' + ]) const tab = comfyPage.menu.nodeLibraryTab await tab.getFolder('foo').click({ button: 'right' }) await comfyPage.page.getByLabel('Delete').click() expect( - await comfyPage.getSetting('Comfy.NodeLibrary.Bookmarks.V2') + await comfyPage.settings.getSetting('Comfy.NodeLibrary.Bookmarks.V2') ).toEqual([]) }) test('Can rename bookmark folder', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.NodeLibrary.Bookmarks.V2', ['foo/']) + await comfyPage.settings.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [ + 'foo/' + ]) const tab = comfyPage.menu.nodeLibraryTab await tab.getFolder('foo').click({ button: 'right' }) @@ -136,14 +149,16 @@ test.describe('Node library sidebar', () => { await comfyPage.page.keyboard.press('Enter') expect( - await comfyPage.getSetting('Comfy.NodeLibrary.Bookmarks.V2') + await comfyPage.settings.getSetting('Comfy.NodeLibrary.Bookmarks.V2') ).toEqual(['bar/']) }) test('Can add bookmark by dragging node to bookmark folder', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.NodeLibrary.Bookmarks.V2', ['foo/']) + await comfyPage.settings.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [ + 'foo/' + ]) const tab = comfyPage.menu.nodeLibraryTab await tab.getFolder('sampling').click() await comfyPage.page.dragAndDrop( @@ -151,7 +166,7 @@ test.describe('Node library sidebar', () => { tab.folderSelector('foo') ) expect( - await comfyPage.getSetting('Comfy.NodeLibrary.Bookmarks.V2') + await comfyPage.settings.getSetting('Comfy.NodeLibrary.Bookmarks.V2') ).toEqual(['foo/', 'foo/KSamplerAdvanced']) }) @@ -162,23 +177,23 @@ test.describe('Node library sidebar', () => { await tab.getFolder('sampling').click() await tab.getNode('KSampler (Advanced)').locator('.bookmark-button').click() expect( - await comfyPage.getSetting('Comfy.NodeLibrary.Bookmarks.V2') + await comfyPage.settings.getSetting('Comfy.NodeLibrary.Bookmarks.V2') ).toEqual(['KSamplerAdvanced']) }) test('Can unbookmark node (Top level bookmark)', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [ + await comfyPage.settings.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [ 'KSamplerAdvanced' ]) const tab = comfyPage.menu.nodeLibraryTab await tab.getNode('KSampler (Advanced)').locator('.bookmark-button').click() expect( - await comfyPage.getSetting('Comfy.NodeLibrary.Bookmarks.V2') + await comfyPage.settings.getSetting('Comfy.NodeLibrary.Bookmarks.V2') ).toEqual([]) }) test('Can unbookmark node (Library node bookmark)', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [ + await comfyPage.settings.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [ 'KSamplerAdvanced' ]) const tab = comfyPage.menu.nodeLibraryTab @@ -188,11 +203,13 @@ test.describe('Node library sidebar', () => { .locator('.bookmark-button') .click() expect( - await comfyPage.getSetting('Comfy.NodeLibrary.Bookmarks.V2') + await comfyPage.settings.getSetting('Comfy.NodeLibrary.Bookmarks.V2') ).toEqual([]) }) test('Can customize icon', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.NodeLibrary.Bookmarks.V2', ['foo/']) + await comfyPage.settings.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [ + 'foo/' + ]) const tab = comfyPage.menu.nodeLibraryTab await tab.getFolder('foo').click({ button: 'right' }) await comfyPage.page.getByLabel('Customize').click() @@ -201,7 +218,9 @@ test.describe('Node library sidebar', () => { await comfyPage.page.getByRole('button', { name: 'Confirm' }).click() await comfyPage.nextFrame() expect( - await comfyPage.getSetting('Comfy.NodeLibrary.BookmarksCustomization') + await comfyPage.settings.getSetting( + 'Comfy.NodeLibrary.BookmarksCustomization' + ) ).toEqual({ 'foo/': { icon: 'pi-folder', @@ -211,7 +230,9 @@ test.describe('Node library sidebar', () => { }) // If color is left as default, it should not be saved test('Can customize icon (default field)', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.NodeLibrary.Bookmarks.V2', ['foo/']) + await comfyPage.settings.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [ + 'foo/' + ]) const tab = comfyPage.menu.nodeLibraryTab await tab.getFolder('foo').click({ button: 'right' }) await comfyPage.page.getByLabel('Customize').click() @@ -219,7 +240,9 @@ test.describe('Node library sidebar', () => { await comfyPage.page.getByRole('button', { name: 'Confirm' }).click() await comfyPage.nextFrame() expect( - await comfyPage.getSetting('Comfy.NodeLibrary.BookmarksCustomization') + await comfyPage.settings.getSetting( + 'Comfy.NodeLibrary.BookmarksCustomization' + ) ).toEqual({ 'foo/': { icon: 'pi-folder' @@ -231,7 +254,9 @@ test.describe('Node library sidebar', () => { comfyPage }) => { // Open customization dialog - await comfyPage.setSetting('Comfy.NodeLibrary.Bookmarks.V2', ['foo/']) + await comfyPage.settings.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [ + 'foo/' + ]) const tab = comfyPage.menu.nodeLibraryTab await tab.getFolder('foo').click({ button: 'right' }) await comfyPage.page.getByLabel('Customize').click() @@ -256,7 +281,7 @@ test.describe('Node library sidebar', () => { await comfyPage.nextFrame() // Verify the color selection is saved - const setting = await comfyPage.getSetting( + const setting = await comfyPage.settings.getSetting( 'Comfy.NodeLibrary.BookmarksCustomization' ) await expect(setting).toHaveProperty(['foo/', 'color']) @@ -266,13 +291,18 @@ test.describe('Node library sidebar', () => { }) test('Can rename customized bookmark folder', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.NodeLibrary.Bookmarks.V2', ['foo/']) - await comfyPage.setSetting('Comfy.NodeLibrary.BookmarksCustomization', { - 'foo/': { - icon: 'pi-folder', - color: '#007bff' + await comfyPage.settings.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [ + 'foo/' + ]) + await comfyPage.settings.setSetting( + 'Comfy.NodeLibrary.BookmarksCustomization', + { + 'foo/': { + icon: 'pi-folder', + color: '#007bff' + } } - }) + ) const tab = comfyPage.menu.nodeLibraryTab await tab.getFolder('foo').click({ button: 'right' }) await comfyPage.page @@ -283,10 +313,12 @@ test.describe('Node library sidebar', () => { await comfyPage.nextFrame() await expect(async () => { expect( - await comfyPage.getSetting('Comfy.NodeLibrary.Bookmarks.V2') + await comfyPage.settings.getSetting('Comfy.NodeLibrary.Bookmarks.V2') ).toEqual(['bar/']) expect( - await comfyPage.getSetting('Comfy.NodeLibrary.BookmarksCustomization') + await comfyPage.settings.getSetting( + 'Comfy.NodeLibrary.BookmarksCustomization' + ) ).toEqual({ 'bar/': { icon: 'pi-folder', @@ -299,27 +331,34 @@ test.describe('Node library sidebar', () => { }) test('Can delete customized bookmark folder', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.NodeLibrary.Bookmarks.V2', ['foo/']) - await comfyPage.setSetting('Comfy.NodeLibrary.BookmarksCustomization', { - 'foo/': { - icon: 'pi-folder', - color: '#007bff' + await comfyPage.settings.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [ + 'foo/' + ]) + await comfyPage.settings.setSetting( + 'Comfy.NodeLibrary.BookmarksCustomization', + { + 'foo/': { + icon: 'pi-folder', + color: '#007bff' + } } - }) + ) const tab = comfyPage.menu.nodeLibraryTab await tab.getFolder('foo').click({ button: 'right' }) await comfyPage.page.getByLabel('Delete').click() await comfyPage.nextFrame() expect( - await comfyPage.getSetting('Comfy.NodeLibrary.Bookmarks.V2') + await comfyPage.settings.getSetting('Comfy.NodeLibrary.Bookmarks.V2') ).toEqual([]) expect( - await comfyPage.getSetting('Comfy.NodeLibrary.BookmarksCustomization') + await comfyPage.settings.getSetting( + 'Comfy.NodeLibrary.BookmarksCustomization' + ) ).toEqual({}) }) test('Can filter nodes in both trees', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [ + await comfyPage.settings.setSetting('Comfy.NodeLibrary.Bookmarks.V2', [ 'foo/', 'foo/KSamplerAdvanced', 'KSampler' diff --git a/browser_tests/tests/sidebar/workflows.spec.ts b/browser_tests/tests/sidebar/workflows.spec.ts index 5c1f8113f3..a706fc80a4 100644 --- a/browser_tests/tests/sidebar/workflows.spec.ts +++ b/browser_tests/tests/sidebar/workflows.spec.ts @@ -4,8 +4,11 @@ import { comfyPageFixture as test } from '../../fixtures/ComfyPage' test.describe('Workflows sidebar', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') - await comfyPage.setSetting('Comfy.Workflow.WorkflowTabsPosition', 'Sidebar') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting( + 'Comfy.Workflow.WorkflowTabsPosition', + 'Sidebar' + ) // Open the sidebar const tab = comfyPage.menu.workflowsTab @@ -13,7 +16,7 @@ test.describe('Workflows sidebar', () => { }) test.afterEach(async ({ comfyPage }) => { - await comfyPage.setupWorkflowsDirectory({}) + await comfyPage.workflow.setupWorkflowsDirectory({}) }) test('Can create new blank workflow', async ({ comfyPage }) => { @@ -30,7 +33,7 @@ test.describe('Workflows sidebar', () => { }) test('Can show top level saved workflows', async ({ comfyPage }) => { - await comfyPage.setupWorkflowsDirectory({ + await comfyPage.workflow.setupWorkflowsDirectory({ 'workflow1.json': 'default.json', 'workflow2.json': 'default.json' }) @@ -73,7 +76,7 @@ test.describe('Workflows sidebar', () => { }) test('Can open workflow after insert', async ({ comfyPage }) => { - await comfyPage.setupWorkflowsDirectory({ + await comfyPage.workflow.setupWorkflowsDirectory({ 'workflow1.json': 'nodes/single_ksampler.json' }) @@ -96,7 +99,7 @@ test.describe('Workflows sidebar', () => { test('Can rename nested workflow from opened workflow item', async ({ comfyPage }) => { - await comfyPage.setupWorkflowsDirectory({ + await comfyPage.workflow.setupWorkflowsDirectory({ foo: { 'bar.json': 'default.json' } @@ -136,7 +139,7 @@ test.describe('Workflows sidebar', () => { test('Exported workflow does not contain localized slot names', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('default') + await comfyPage.workflow.loadWorkflow('default') const exportedWorkflow = await comfyPage.getExportedWorkflow({ api: false }) @@ -156,7 +159,7 @@ test.describe('Workflows sidebar', () => { test('Can export same workflow with different locales', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('default') + await comfyPage.workflow.loadWorkflow('default') // Setup download listener before triggering the export const downloadPromise = comfyPage.page.waitForEvent('download') @@ -171,7 +174,7 @@ test.describe('Workflows sidebar', () => { api: false }) - await comfyPage.setSetting('Comfy.Locale', 'zh') + await comfyPage.settings.setSetting('Comfy.Locale', 'zh') await comfyPage.setup() const downloadedContentZh = await comfyPage.getExportedWorkflow({ @@ -240,8 +243,12 @@ test.describe('Workflows sidebar', () => { test('Does not report warning when switching between opened workflows', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('missing/missing_nodes') - await comfyPage.closeDialog() + await comfyPage.workflow.loadWorkflow('missing/missing_nodes') + await comfyPage.page + .locator('.p-dialog') + .getByRole('button', { name: 'Close' }) + .click({ force: true }) + await comfyPage.page.locator('.p-dialog').waitFor({ state: 'hidden' }) // Load blank workflow await comfyPage.menu.workflowsTab.open() @@ -280,7 +287,7 @@ test.describe('Workflows sidebar', () => { }) test('Can delete workflows (confirm disabled)', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Workflow.ConfirmDelete', false) + await comfyPage.settings.setSetting('Comfy.Workflow.ConfirmDelete', false) const { topbar, workflowsTab } = comfyPage.menu @@ -290,7 +297,8 @@ test.describe('Workflows sidebar', () => { await workflowsTab.getOpenedItem(filename).click({ button: 'right' }) await comfyPage.nextFrame() - await comfyPage.clickContextMenuItem('Delete') + await comfyPage.contextMenu.clickMenuItem('Delete') + await comfyPage.nextFrame() await expect(workflowsTab.getOpenedItem(filename)).not.toBeVisible() expect(await workflowsTab.getOpenedWorkflowNames()).toEqual([ @@ -306,7 +314,8 @@ test.describe('Workflows sidebar', () => { expect(await workflowsTab.getOpenedWorkflowNames()).toEqual([filename]) await workflowsTab.getOpenedItem(filename).click({ button: 'right' }) - await comfyPage.clickContextMenuItem('Delete') + await comfyPage.contextMenu.clickMenuItem('Delete') + await comfyPage.nextFrame() await comfyPage.confirmDialog.click('delete') @@ -317,7 +326,7 @@ test.describe('Workflows sidebar', () => { }) test('Can duplicate workflow from context menu', async ({ comfyPage }) => { - await comfyPage.setupWorkflowsDirectory({ + await comfyPage.workflow.setupWorkflowsDirectory({ 'workflow1.json': 'default.json' }) @@ -327,7 +336,8 @@ test.describe('Workflows sidebar', () => { await workflowsTab .getPersistedItem('workflow1.json') .click({ button: 'right' }) - await comfyPage.clickContextMenuItem('Duplicate') + await comfyPage.contextMenu.clickMenuItem('Duplicate') + await comfyPage.nextFrame() expect(await workflowsTab.getOpenedWorkflowNames()).toEqual([ '*Unsaved Workflow.json', @@ -336,7 +346,7 @@ test.describe('Workflows sidebar', () => { }) test('Can drop workflow from workflows sidebar', async ({ comfyPage }) => { - await comfyPage.setupWorkflowsDirectory({ + await comfyPage.workflow.setupWorkflowsDirectory({ 'workflow1.json': 'default.json' }) diff --git a/browser_tests/tests/subgraph-rename-dialog.spec.ts b/browser_tests/tests/subgraph-rename-dialog.spec.ts index 8aa0846f09..a59fec671f 100644 --- a/browser_tests/tests/subgraph-rename-dialog.spec.ts +++ b/browser_tests/tests/subgraph-rename-dialog.spec.ts @@ -14,13 +14,13 @@ const SELECTORS = { test.describe('Subgraph Slot Rename Dialog', { tag: '@subgraph' }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test('Shows current slot label (not stale) in rename dialog', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/basic-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph') const subgraphNode = await comfyPage.nodeOps.getNodeRefById('2') await subgraphNode.navigateIntoSubgraph() @@ -33,7 +33,8 @@ test.describe('Subgraph Slot Rename Dialog', { tag: '@subgraph' }, () => { // First rename await comfyPage.subgraph.rightClickInputSlot(initialInputLabel) - await comfyPage.clickLitegraphContextMenuItem('Rename Slot') + await comfyPage.contextMenu.clickLitegraphMenuItem('Rename Slot') + await comfyPage.nextFrame() await comfyPage.page.waitForSelector(SELECTORS.promptDialog, { state: 'visible' @@ -68,7 +69,8 @@ test.describe('Subgraph Slot Rename Dialog', { tag: '@subgraph' }, () => { // Now rename again - this is where the bug would show // We need to use the index-based approach since the method looks for slot.name await comfyPage.subgraph.rightClickInputSlot() - await comfyPage.clickLitegraphContextMenuItem('Rename Slot') + await comfyPage.contextMenu.clickLitegraphMenuItem('Rename Slot') + await comfyPage.nextFrame() await comfyPage.page.waitForSelector(SELECTORS.promptDialog, { state: 'visible' @@ -106,7 +108,7 @@ test.describe('Subgraph Slot Rename Dialog', { tag: '@subgraph' }, () => { test('Shows current output slot label in rename dialog', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/basic-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph') const subgraphNode = await comfyPage.nodeOps.getNodeRefById('2') await subgraphNode.navigateIntoSubgraph() @@ -119,7 +121,8 @@ test.describe('Subgraph Slot Rename Dialog', { tag: '@subgraph' }, () => { // First rename await comfyPage.subgraph.rightClickOutputSlot(initialOutputLabel) - await comfyPage.clickLitegraphContextMenuItem('Rename Slot') + await comfyPage.contextMenu.clickLitegraphMenuItem('Rename Slot') + await comfyPage.nextFrame() await comfyPage.page.waitForSelector(SELECTORS.promptDialog, { state: 'visible' @@ -142,7 +145,8 @@ test.describe('Subgraph Slot Rename Dialog', { tag: '@subgraph' }, () => { // Now rename again to check for stale content // We need to use the index-based approach since the method looks for slot.name await comfyPage.subgraph.rightClickOutputSlot() - await comfyPage.clickLitegraphContextMenuItem('Rename Slot') + await comfyPage.contextMenu.clickLitegraphMenuItem('Rename Slot') + await comfyPage.nextFrame() await comfyPage.page.waitForSelector(SELECTORS.promptDialog, { state: 'visible' diff --git a/browser_tests/tests/subgraph.spec.ts b/browser_tests/tests/subgraph.spec.ts index 1b3dfeec6b..334f37f74a 100644 --- a/browser_tests/tests/subgraph.spec.ts +++ b/browser_tests/tests/subgraph.spec.ts @@ -18,7 +18,7 @@ const SELECTORS = { test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) // Helper to get subgraph slot count @@ -52,7 +52,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { test.describe('I/O Slot Management', () => { test('Can add input slots to subgraph', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/basic-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph') const subgraphNode = await comfyPage.nodeOps.getNodeRefById('2') await subgraphNode.navigateIntoSubgraph() @@ -68,7 +68,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { }) test('Can add output slots to subgraph', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/basic-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph') const subgraphNode = await comfyPage.nodeOps.getNodeRefById('2') await subgraphNode.navigateIntoSubgraph() @@ -84,7 +84,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { }) test('Can remove input slots from subgraph', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/basic-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph') const subgraphNode = await comfyPage.nodeOps.getNodeRefById('2') await subgraphNode.navigateIntoSubgraph() @@ -93,7 +93,8 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { expect(initialCount).toBeGreaterThan(0) await comfyPage.subgraph.rightClickInputSlot() - await comfyPage.clickLitegraphContextMenuItem('Remove Slot') + await comfyPage.contextMenu.clickLitegraphMenuItem('Remove Slot') + await comfyPage.nextFrame() // Force re-render await comfyPage.canvas.click({ position: { x: 100, y: 100 } }) @@ -104,7 +105,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { }) test('Can remove output slots from subgraph', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/basic-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph') const subgraphNode = await comfyPage.nodeOps.getNodeRefById('2') await subgraphNode.navigateIntoSubgraph() @@ -113,7 +114,8 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { expect(initialCount).toBeGreaterThan(0) await comfyPage.subgraph.rightClickOutputSlot() - await comfyPage.clickLitegraphContextMenuItem('Remove Slot') + await comfyPage.contextMenu.clickLitegraphMenuItem('Remove Slot') + await comfyPage.nextFrame() // Force re-render await comfyPage.canvas.click({ position: { x: 100, y: 100 } }) @@ -124,7 +126,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { }) test('Can rename I/O slots', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/basic-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph') const subgraphNode = await comfyPage.nodeOps.getNodeRefById('2') await subgraphNode.navigateIntoSubgraph() @@ -135,7 +137,8 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { }) await comfyPage.subgraph.rightClickInputSlot(initialInputLabel) - await comfyPage.clickLitegraphContextMenuItem('Rename Slot') + await comfyPage.contextMenu.clickLitegraphMenuItem('Rename Slot') + await comfyPage.nextFrame() await comfyPage.page.waitForSelector(SELECTORS.promptDialog, { state: 'visible' @@ -157,7 +160,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { }) test('Can rename input slots via double-click', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/basic-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph') const subgraphNode = await comfyPage.nodeOps.getNodeRefById('2') await subgraphNode.navigateIntoSubgraph() @@ -189,7 +192,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { }) test('Can rename output slots via double-click', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/basic-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph') const subgraphNode = await comfyPage.nodeOps.getNodeRefById('2') await subgraphNode.navigateIntoSubgraph() @@ -224,7 +227,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { test('Right-click context menu still works alongside double-click', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/basic-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph') const subgraphNode = await comfyPage.nodeOps.getNodeRefById('2') await subgraphNode.navigateIntoSubgraph() @@ -236,7 +239,8 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { // Test that right-click still works for renaming await comfyPage.subgraph.rightClickInputSlot(initialInputLabel) - await comfyPage.clickLitegraphContextMenuItem('Rename Slot') + await comfyPage.contextMenu.clickLitegraphMenuItem('Rename Slot') + await comfyPage.nextFrame() await comfyPage.page.waitForSelector(SELECTORS.promptDialog, { state: 'visible' @@ -261,7 +265,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { test('Can double-click on slot label text to rename', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/basic-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph') const subgraphNode = await comfyPage.nodeOps.getNodeRefById('2') await subgraphNode.navigateIntoSubgraph() @@ -332,7 +336,9 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { test('Can create widget from link with compressed target_slot', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/subgraph-compressed-target-slot') + await comfyPage.workflow.loadWorkflow( + 'subgraphs/subgraph-compressed-target-slot' + ) const step = await comfyPage.page.evaluate(() => { return window['app'].graph.nodes[0].widgets[0].options.step }) @@ -342,11 +348,11 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { test.describe('Subgraph Creation and Deletion', () => { test('Can create subgraph from selected nodes', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('default') + await comfyPage.workflow.loadWorkflow('default') const initialNodeCount = await getGraphNodeCount(comfyPage) - await comfyPage.ctrlA() + await comfyPage.keyboard.selectAll() await comfyPage.nextFrame() const node = await comfyPage.nodeOps.getNodeRefById('5') @@ -362,7 +368,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { }) test('Can delete subgraph node', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/basic-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph') const subgraphNode = await comfyPage.nodeOps.getNodeRefById('2') expect(await subgraphNode.exists()).toBe(true) @@ -384,7 +390,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { test('Can copy subgraph node by dragging + alt', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/basic-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph') const subgraphNode = await comfyPage.nodeOps.getNodeRefById('2') @@ -413,7 +419,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { test('Copying subgraph node by dragging + alt creates a new subgraph node with unique type', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/basic-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph') const subgraphNode = await comfyPage.nodeOps.getNodeRefById('2') @@ -445,7 +451,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { test.describe('Operations Inside Subgraphs', () => { test('Can copy and paste nodes in subgraph', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/basic-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph') const subgraphNode = await comfyPage.nodeOps.getNodeRefById('2') await subgraphNode.navigateIntoSubgraph() @@ -476,7 +482,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { }) test('Can undo and redo operations in subgraph', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/basic-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph') const subgraphNode = await comfyPage.nodeOps.getNodeRefById('2') await subgraphNode.navigateIntoSubgraph() @@ -490,14 +496,14 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { const initialCount = await getGraphNodeCount(comfyPage) // Undo - await comfyPage.ctrlZ() + await comfyPage.keyboard.undo() await comfyPage.nextFrame() const afterUndoCount = await getGraphNodeCount(comfyPage) expect(afterUndoCount).toBe(initialCount - 1) // Redo - await comfyPage.ctrlY() + await comfyPage.keyboard.redo() await comfyPage.nextFrame() const afterRedoCount = await getGraphNodeCount(comfyPage) @@ -507,13 +513,13 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { test.describe('Subgraph Navigation and UI', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') }) test('Breadcrumb updates when subgraph node title is changed', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/nested-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/nested-subgraph') await comfyPage.nextFrame() const subgraphNode = await comfyPage.nodeOps.getNodeRefById('10') @@ -565,7 +571,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { test('DOM widget visibility persists through subgraph navigation', async ({ comfyPage }) => { - await comfyPage.loadWorkflow( + await comfyPage.workflow.loadWorkflow( 'subgraphs/subgraph-with-promoted-text-widget' ) await comfyPage.nextFrame() @@ -598,7 +604,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { test('DOM widget content is preserved through navigation', async ({ comfyPage }) => { - await comfyPage.loadWorkflow( + await comfyPage.workflow.loadWorkflow( 'subgraphs/subgraph-with-promoted-text-widget' ) @@ -621,7 +627,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { test('DOM elements are cleaned up when subgraph node is removed', async ({ comfyPage }) => { - await comfyPage.loadWorkflow( + await comfyPage.workflow.loadWorkflow( 'subgraphs/subgraph-with-promoted-text-widget' ) @@ -646,10 +652,10 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { comfyPage }) => { // Enable new menu for breadcrumb navigation - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') const workflowName = 'subgraphs/subgraph-with-promoted-text-widget' - await comfyPage.loadWorkflow(workflowName) + await comfyPage.workflow.loadWorkflow(workflowName) const textareaCount = await comfyPage.page .locator(SELECTORS.domWidget) @@ -662,7 +668,8 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { await subgraphNode.navigateIntoSubgraph() await comfyPage.subgraph.rightClickInputSlot('text') - await comfyPage.clickLitegraphContextMenuItem('Remove Slot') + await comfyPage.contextMenu.clickLitegraphMenuItem('Remove Slot') + await comfyPage.nextFrame() // Wait for breadcrumb to be visible await comfyPage.page.waitForSelector(SELECTORS.breadcrumb, { @@ -691,7 +698,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { test('Multiple promoted widgets are handled correctly', async ({ comfyPage }) => { - await comfyPage.loadWorkflow( + await comfyPage.workflow.loadWorkflow( 'subgraphs/subgraph-with-multiple-promoted-widgets' ) @@ -720,15 +727,15 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { test.describe('Navigation Hotkeys', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') }) test('Navigation hotkey can be customized', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/basic-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph') await comfyPage.nextFrame() // Change the Exit Subgraph keybinding from Escape to Alt+Q - await comfyPage.setSetting('Comfy.Keybinding.NewBindings', [ + await comfyPage.settings.setSetting('Comfy.Keybinding.NewBindings', [ { commandId: 'Comfy.Graph.ExitSubgraph', combo: { @@ -740,7 +747,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { } ]) - await comfyPage.setSetting('Comfy.Keybinding.UnsetBindings', [ + await comfyPage.settings.setSetting('Comfy.Keybinding.UnsetBindings', [ { commandId: 'Comfy.Graph.ExitSubgraph', combo: { @@ -780,7 +787,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { test('Escape prioritizes closing dialogs over exiting subgraph', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('subgraphs/basic-subgraph') + await comfyPage.workflow.loadWorkflow('subgraphs/basic-subgraph') await comfyPage.nextFrame() const subgraphNode = await comfyPage.nodeOps.getNodeRefById('2') diff --git a/browser_tests/tests/templates.spec.ts b/browser_tests/tests/templates.spec.ts index 311153306a..63cfb04789 100644 --- a/browser_tests/tests/templates.spec.ts +++ b/browser_tests/tests/templates.spec.ts @@ -15,8 +15,11 @@ async function checkTemplateFileExists( test.describe('Templates', { tag: ['@slow', '@workflow'] }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') - await comfyPage.setSetting('Comfy.Workflow.ShowMissingModelsWarning', false) + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting( + 'Comfy.Workflow.ShowMissingModelsWarning', + false + ) }) test('should have a JSON workflow file for each template', async ({ @@ -97,7 +100,7 @@ test.describe('Templates', { tag: ['@slow', '@workflow'] }, () => { comfyPage }) => { // Set the tutorial as not completed to mark the user as a first-time user - await comfyPage.setSetting('Comfy.TutorialCompleted', false) + await comfyPage.settings.setSetting('Comfy.TutorialCompleted', false) // Load the page await comfyPage.setup({ clearStorage: true }) @@ -107,7 +110,7 @@ test.describe('Templates', { tag: ['@slow', '@workflow'] }, () => { }) test('Uses proper locale files for templates', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Locale', 'fr') + await comfyPage.settings.setSetting('Comfy.Locale', 'fr') await comfyPage.executeCommand('Comfy.BrowseTemplates') @@ -134,7 +137,7 @@ test.describe('Templates', { tag: ['@slow', '@workflow'] }, () => { comfyPage }) => { // Set locale to a language that doesn't have a template file - await comfyPage.setSetting('Comfy.Locale', 'de') // German - no index.de.json exists + await comfyPage.settings.setSetting('Comfy.Locale', 'de') // German - no index.de.json exists // Wait for the German request (expected to 404) const germanRequestPromise = comfyPage.page.waitForRequest( diff --git a/browser_tests/tests/useSettingSearch.spec.ts b/browser_tests/tests/useSettingSearch.spec.ts index 845f656f57..ca595fc482 100644 --- a/browser_tests/tests/useSettingSearch.spec.ts +++ b/browser_tests/tests/useSettingSearch.spec.ts @@ -3,7 +3,7 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Settings Search functionality', { tag: '@settings' }, () => { diff --git a/browser_tests/tests/versionMismatchWarnings.spec.ts b/browser_tests/tests/versionMismatchWarnings.spec.ts index c5f6e2c122..6c0a89034a 100644 --- a/browser_tests/tests/versionMismatchWarnings.spec.ts +++ b/browser_tests/tests/versionMismatchWarnings.spec.ts @@ -37,8 +37,8 @@ test.describe('Version Mismatch Warnings', { tag: '@slow' }, () => { } test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') - await comfyPage.setSetting( + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting( 'Comfy.VersionCompatibility.DisableWarnings', false ) diff --git a/browser_tests/tests/viewport.spec.ts b/browser_tests/tests/viewport.spec.ts index c0d65ca38c..b7320ee0ec 100644 --- a/browser_tests/tests/viewport.spec.ts +++ b/browser_tests/tests/viewport.spec.ts @@ -6,7 +6,9 @@ test.describe('Viewport', { tag: ['@screenshot', '@smoke', '@canvas'] }, () => { test('Fits view to nodes when saved viewport position is offscreen', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('viewport/default-viewport-saved-offscreen') + await comfyPage.workflow.loadWorkflow( + 'viewport/default-viewport-saved-offscreen' + ) // Wait a few frames for rendering to stabilize for (let i = 0; i < 5; i++) { diff --git a/browser_tests/tests/vueNodes/groups/groups.spec.ts b/browser_tests/tests/vueNodes/groups/groups.spec.ts index 19404f7d4b..da17a0b25a 100644 --- a/browser_tests/tests/vueNodes/groups/groups.spec.ts +++ b/browser_tests/tests/vueNodes/groups/groups.spec.ts @@ -7,8 +7,8 @@ const CREATE_GROUP_HOTKEY = 'Control+g' test.describe('Vue Node Groups', { tag: '@screenshot' }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) - await comfyPage.setSetting('Comfy.Minimap.ShowGroups', true) + await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true) + await comfyPage.settings.setSetting('Comfy.Minimap.ShowGroups', true) await comfyPage.vueNodes.waitForNodes() }) @@ -24,8 +24,8 @@ test.describe('Vue Node Groups', { tag: '@screenshot' }, () => { test('should allow fitting group to contents', async ({ comfyPage }) => { await comfyPage.setup() - await comfyPage.loadWorkflow('groups/oversized_group') - await comfyPage.ctrlA() + await comfyPage.workflow.loadWorkflow('groups/oversized_group') + await comfyPage.keyboard.selectAll() await comfyPage.executeCommand('Comfy.Graph.FitGroupToContents') await comfyPage.nextFrame() await expect(comfyPage.canvas).toHaveScreenshot( @@ -36,7 +36,7 @@ test.describe('Vue Node Groups', { tag: '@screenshot' }, () => { test('should move nested groups together when dragging outer group', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('groups/nested-groups-1-inner-node') + await comfyPage.workflow.loadWorkflow('groups/nested-groups-1-inner-node') // Get initial positions with null guards const outerInitial = await comfyPage.getGroupPosition('Outer Group') diff --git a/browser_tests/tests/vueNodes/interactions/canvas/pan.spec.ts b/browser_tests/tests/vueNodes/interactions/canvas/pan.spec.ts index 557c8db620..c7f5ce92c0 100644 --- a/browser_tests/tests/vueNodes/interactions/canvas/pan.spec.ts +++ b/browser_tests/tests/vueNodes/interactions/canvas/pan.spec.ts @@ -5,7 +5,7 @@ import { test.describe('Vue Nodes Canvas Pan', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) + await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true) await comfyPage.vueNodes.waitForNodes() }) diff --git a/browser_tests/tests/vueNodes/interactions/canvas/zoom.spec.ts b/browser_tests/tests/vueNodes/interactions/canvas/zoom.spec.ts index 959b0b7ff9..e391c289d4 100644 --- a/browser_tests/tests/vueNodes/interactions/canvas/zoom.spec.ts +++ b/browser_tests/tests/vueNodes/interactions/canvas/zoom.spec.ts @@ -5,8 +5,8 @@ import { test.describe('Vue Nodes Zoom', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) - await comfyPage.setSetting('LiteGraph.Canvas.MinFontSizeForLOD', 8) + await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true) + await comfyPage.settings.setSetting('LiteGraph.Canvas.MinFontSizeForLOD', 8) await comfyPage.vueNodes.waitForNodes() }) diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts index f5f08d0bc1..58c26d1257 100644 --- a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts +++ b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts @@ -100,10 +100,10 @@ async function connectSlots( test.describe('Vue Node Link Interaction', { tag: '@screenshot' }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true) // await comfyPage.setup() - await comfyPage.loadWorkflow('vueNodes/simple-triple') + await comfyPage.workflow.loadWorkflow('vueNodes/simple-triple') await comfyPage.vueNodes.waitForNodes() await fitToViewInstant(comfyPage) }) @@ -872,7 +872,7 @@ test.describe('Vue Node Link Interaction', { tag: '@screenshot' }, () => { comfyPage, comfyMouse }) => { - await comfyPage.setSetting( + await comfyPage.settings.setSetting( 'Comfy.LinkRelease.ActionShift', 'context menu' ) @@ -924,11 +924,11 @@ test.describe('Vue Node Link Interaction', { tag: '@screenshot' }, () => { comfyPage, comfyMouse }) => { - await comfyPage.setSetting( + await comfyPage.settings.setSetting( 'Comfy.LinkRelease.ActionShift', 'context menu' ) - await comfyPage.setSetting('Comfy.NodeSearchBoxImpl', 'default') + await comfyPage.settings.setSetting('Comfy.NodeSearchBoxImpl', 'default') const samplerNode = ( await comfyPage.nodeOps.getNodeRefsByType('KSampler') @@ -953,7 +953,8 @@ test.describe('Vue Node Link Interaction', { tag: '@screenshot' }, () => { } // Open Search from the context menu - await comfyPage.clickContextMenuItem('Search') + await comfyPage.contextMenu.clickMenuItem('Search') + await comfyPage.nextFrame() // Search box opens with prefilled type filter based on link type (LATENT) await expect(comfyPage.searchBox.input).toBeVisible() @@ -989,7 +990,10 @@ test.describe('Vue Node Link Interaction', { tag: '@screenshot' }, () => { comfyPage, comfyMouse }) => { - await comfyPage.setSetting('Comfy.LinkRelease.ActionShift', 'search box') + await comfyPage.settings.setSetting( + 'Comfy.LinkRelease.ActionShift', + 'search box' + ) const samplerNode = ( await comfyPage.nodeOps.getNodeRefsByType('KSampler') diff --git a/browser_tests/tests/vueNodes/interactions/node/bringToFront.spec.ts b/browser_tests/tests/vueNodes/interactions/node/bringToFront.spec.ts index a9e0e0dd65..402b314662 100644 --- a/browser_tests/tests/vueNodes/interactions/node/bringToFront.spec.ts +++ b/browser_tests/tests/vueNodes/interactions/node/bringToFront.spec.ts @@ -7,9 +7,9 @@ import { fitToViewInstant } from '../../../../helpers/fitToView' test.describe('Vue Node Bring to Front', { tag: '@screenshot' }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) - await comfyPage.loadWorkflow('vueNodes/simple-triple') + 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) }) diff --git a/browser_tests/tests/vueNodes/interactions/node/move.spec.ts b/browser_tests/tests/vueNodes/interactions/node/move.spec.ts index e0421fcc8f..42f8557beb 100644 --- a/browser_tests/tests/vueNodes/interactions/node/move.spec.ts +++ b/browser_tests/tests/vueNodes/interactions/node/move.spec.ts @@ -7,7 +7,7 @@ import type { Position } from '../../../../fixtures/types' test.describe('Vue Node Moving', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) + await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true) await comfyPage.vueNodes.waitForNodes() }) @@ -52,7 +52,7 @@ test.describe('Vue Node Moving', () => { { tag: '@screenshot' }, async ({ comfyPage }) => { // Disable minimap (gets in way of the node on small screens) - await comfyPage.setSetting('Comfy.Minimap.Visible', false) + await comfyPage.settings.setSetting('Comfy.Minimap.Visible', false) const loadCheckpointHeaderPos = await getLoadCheckpointHeaderPos(comfyPage) diff --git a/browser_tests/tests/vueNodes/interactions/node/remove.spec.ts b/browser_tests/tests/vueNodes/interactions/node/remove.spec.ts index 7050b012d0..342b3fb2d6 100644 --- a/browser_tests/tests/vueNodes/interactions/node/remove.spec.ts +++ b/browser_tests/tests/vueNodes/interactions/node/remove.spec.ts @@ -3,14 +3,14 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../../../../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Vue Nodes - Delete Key Interaction', () => { test.beforeEach(async ({ comfyPage }) => { // Enable Vue nodes rendering - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) - await comfyPage.setSetting('Comfy.Graph.CanvasMenu', false) + await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true) + await comfyPage.settings.setSetting('Comfy.Graph.CanvasMenu', false) await comfyPage.setup() }) @@ -24,7 +24,7 @@ test.describe('Vue Nodes - Delete Key Interaction', () => { expect(initialNodeCount).toBeGreaterThan(0) // Select all Vue nodes - await comfyPage.ctrlA() + await comfyPage.keyboard.selectAll() // Verify all Vue nodes are selected const selectedCount = await comfyPage.vueNodes.getSelectedNodeCount() diff --git a/browser_tests/tests/vueNodes/interactions/node/rename.spec.ts b/browser_tests/tests/vueNodes/interactions/node/rename.spec.ts index 5cd6b2feaa..19960454f4 100644 --- a/browser_tests/tests/vueNodes/interactions/node/rename.spec.ts +++ b/browser_tests/tests/vueNodes/interactions/node/rename.spec.ts @@ -5,8 +5,8 @@ import { test.describe('Vue Nodes Renaming', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Graph.CanvasMenu', false) - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) + await comfyPage.settings.setSetting('Comfy.Graph.CanvasMenu', false) + await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true) await comfyPage.setup() await comfyPage.vueNodes.waitForNodes() }) diff --git a/browser_tests/tests/vueNodes/interactions/node/resize.spec.ts b/browser_tests/tests/vueNodes/interactions/node/resize.spec.ts index c8e015ffa4..fc61081955 100644 --- a/browser_tests/tests/vueNodes/interactions/node/resize.spec.ts +++ b/browser_tests/tests/vueNodes/interactions/node/resize.spec.ts @@ -5,7 +5,7 @@ import { test.describe('Vue Node Resizing', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) + await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true) await comfyPage.vueNodes.waitForNodes() }) diff --git a/browser_tests/tests/vueNodes/interactions/node/select.spec.ts b/browser_tests/tests/vueNodes/interactions/node/select.spec.ts index 514c88d48d..4541072e14 100644 --- a/browser_tests/tests/vueNodes/interactions/node/select.spec.ts +++ b/browser_tests/tests/vueNodes/interactions/node/select.spec.ts @@ -4,12 +4,12 @@ import { } from '../../../../fixtures/ComfyPage' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Vue Node Selection', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) + await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true) await comfyPage.vueNodes.waitForNodes() }) diff --git a/browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts b/browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts index fb9ff28725..0a88b3a97c 100644 --- a/browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts +++ b/browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts @@ -8,10 +8,10 @@ const BYPASS_CLASS = /before:bg-bypass\/60/ test.describe('Vue Node Bypass', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') - await comfyPage.setSetting('Comfy.Minimap.Visible', false) - await comfyPage.setSetting('Comfy.Graph.CanvasMenu', true) + 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() }) diff --git a/browser_tests/tests/vueNodes/nodeStates/collapse.spec.ts b/browser_tests/tests/vueNodes/nodeStates/collapse.spec.ts index 8e8e22995a..bb3b722d6e 100644 --- a/browser_tests/tests/vueNodes/nodeStates/collapse.spec.ts +++ b/browser_tests/tests/vueNodes/nodeStates/collapse.spec.ts @@ -5,9 +5,9 @@ import { test.describe('Vue Node Collapse', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.Graph.CanvasMenu', false) - await comfyPage.setSetting('Comfy.EnableTooltips', true) - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) + 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() }) diff --git a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts index 369c7e195d..dfdd173b95 100644 --- a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts +++ b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts @@ -5,9 +5,9 @@ import { test.describe('Vue Node Custom Colors', { tag: '@screenshot' }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') - await comfyPage.setSetting('Comfy.Canvas.SelectionToolbox', true) - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) + 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() }) @@ -31,7 +31,7 @@ test.describe('Vue Node Custom Colors', { tag: '@screenshot' }, () => { }) test('should load node colors from workflow', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('nodes/every_node_color') + await comfyPage.workflow.loadWorkflow('nodes/every_node_color') await expect(comfyPage.canvas).toHaveScreenshot( 'vue-node-custom-colors-dark-all-colors.png' ) @@ -40,8 +40,8 @@ test.describe('Vue Node Custom Colors', { tag: '@screenshot' }, () => { test('should show brightened node colors on light theme', async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.ColorPalette', 'light') - await comfyPage.loadWorkflow('nodes/every_node_color') + await comfyPage.settings.setSetting('Comfy.ColorPalette', 'light') + await comfyPage.workflow.loadWorkflow('nodes/every_node_color') await expect(comfyPage.canvas).toHaveScreenshot( 'vue-node-custom-colors-light-all-colors.png' ) diff --git a/browser_tests/tests/vueNodes/nodeStates/error.spec.ts b/browser_tests/tests/vueNodes/nodeStates/error.spec.ts index b8c718239c..a9623039c5 100644 --- a/browser_tests/tests/vueNodes/nodeStates/error.spec.ts +++ b/browser_tests/tests/vueNodes/nodeStates/error.spec.ts @@ -7,7 +7,7 @@ const ERROR_CLASS = /border-node-stroke-error/ test.describe('Vue Node Error', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) + await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true) await comfyPage.vueNodes.waitForNodes() }) @@ -15,7 +15,7 @@ test.describe('Vue Node Error', () => { comfyPage }) => { await comfyPage.setup() - await comfyPage.loadWorkflow('missing/missing_nodes') + await comfyPage.workflow.loadWorkflow('missing/missing_nodes') // Expect error state on missing unknown node const unknownNode = comfyPage.page.locator('[data-node-id]').filter({ @@ -28,7 +28,7 @@ test.describe('Vue Node Error', () => { comfyPage }) => { await comfyPage.setup() - await comfyPage.loadWorkflow('nodes/execution_error') + await comfyPage.workflow.loadWorkflow('nodes/execution_error') await comfyPage.runButton.click() const raiseErrorNode = comfyPage.vueNodes.getNodeByTitle('Raise Error') diff --git a/browser_tests/tests/vueNodes/nodeStates/mute.spec.ts b/browser_tests/tests/vueNodes/nodeStates/mute.spec.ts index e59d79cfd7..b4b4fd8c45 100644 --- a/browser_tests/tests/vueNodes/nodeStates/mute.spec.ts +++ b/browser_tests/tests/vueNodes/nodeStates/mute.spec.ts @@ -8,7 +8,7 @@ const MUTE_OPACITY = '0.5' test.describe('Vue Node Mute', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) + await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true) await comfyPage.vueNodes.waitForNodes() }) diff --git a/browser_tests/tests/vueNodes/nodeStates/pin.spec.ts b/browser_tests/tests/vueNodes/nodeStates/pin.spec.ts index 15af2d1c65..f8f174fae4 100644 --- a/browser_tests/tests/vueNodes/nodeStates/pin.spec.ts +++ b/browser_tests/tests/vueNodes/nodeStates/pin.spec.ts @@ -8,7 +8,7 @@ const PIN_INDICATOR = '[data-testid="node-pin-indicator"]' test.describe('Vue Node Pin', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) + await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true) await comfyPage.vueNodes.waitForNodes() }) diff --git a/browser_tests/tests/vueNodes/widgets/int/integerWidget.spec.ts b/browser_tests/tests/vueNodes/widgets/int/integerWidget.spec.ts index ee6b6bbfb2..90e1f17da2 100644 --- a/browser_tests/tests/vueNodes/widgets/int/integerWidget.spec.ts +++ b/browser_tests/tests/vueNodes/widgets/int/integerWidget.spec.ts @@ -5,14 +5,14 @@ import { test.describe('Vue Integer Widget', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) + await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true) await comfyPage.setup() }) test('should be disabled and not allow changing value when link connected to slot', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('vueNodes/linked-int-widget') + await comfyPage.workflow.loadWorkflow('vueNodes/linked-int-widget') await comfyPage.vueNodes.waitForNodes() const seedWidget = comfyPage.vueNodes diff --git a/browser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts b/browser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts index 2ae178d221..c7186e2d6f 100644 --- a/browser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts +++ b/browser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts @@ -5,7 +5,7 @@ import { test.describe('Vue Upload Widgets', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) + await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true) await comfyPage.vueNodes.waitForNodes() }) @@ -14,7 +14,7 @@ test.describe('Vue Upload Widgets', () => { { tag: '@screenshot' }, async ({ comfyPage }) => { await comfyPage.setup() - await comfyPage.loadWorkflow('widgets/all_load_widgets') + await comfyPage.workflow.loadWorkflow('widgets/all_load_widgets') await comfyPage.vueNodes.waitForNodes() await expect(comfyPage.canvas).toHaveScreenshot( diff --git a/browser_tests/tests/vueNodes/widgets/text/multilineStringWidget.spec.ts b/browser_tests/tests/vueNodes/widgets/text/multilineStringWidget.spec.ts index bb08232a29..096caf2245 100644 --- a/browser_tests/tests/vueNodes/widgets/text/multilineStringWidget.spec.ts +++ b/browser_tests/tests/vueNodes/widgets/text/multilineStringWidget.spec.ts @@ -1,12 +1,9 @@ -import { - type ComfyPage, - comfyExpect as expect, - comfyPageFixture as test -} from '../../../../fixtures/ComfyPage' +import { comfyExpect as expect, comfyPageFixture as test } from '../../../../fixtures/ComfyPage'; +import type { ComfyPage } from '../../../../fixtures/ComfyPage'; test.describe('Vue Multiline String Widget', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) + await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true) await comfyPage.vueNodes.waitForNodes() }) diff --git a/browser_tests/tests/vueNodes/widgets/widgetReactivity.spec.ts b/browser_tests/tests/vueNodes/widgets/widgetReactivity.spec.ts index 6f3701c127..deeba0cbd9 100644 --- a/browser_tests/tests/vueNodes/widgets/widgetReactivity.spec.ts +++ b/browser_tests/tests/vueNodes/widgets/widgetReactivity.spec.ts @@ -5,7 +5,7 @@ import { test.describe('Vue Widget Reactivity', () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.VueNodes.Enabled', true) + await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true) await comfyPage.vueNodes.waitForNodes() }) test('Should display added widgets', async ({ comfyPage }) => { diff --git a/browser_tests/tests/widget.spec.ts b/browser_tests/tests/widget.spec.ts index 00a323196c..51e7d26d5d 100644 --- a/browser_tests/tests/widget.spec.ts +++ b/browser_tests/tests/widget.spec.ts @@ -1,33 +1,55 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' +import { DefaultGraphPositions } from '../fixtures/constants/defaultGraphPositions' test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Disabled') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') }) test.describe('Combo text widget', { tag: ['@screenshot', '@widget'] }, () => { test('Truncates text when resized', async ({ comfyPage }) => { - await comfyPage.resizeLoadCheckpointNode(0.2, 1) + await comfyPage.nodeOps.resizeNode( + DefaultGraphPositions.loadCheckpoint.pos, + DefaultGraphPositions.loadCheckpoint.size, + 0.2, + 1 + ) await expect(comfyPage.canvas).toHaveScreenshot( 'load-checkpoint-resized-min-width.png' ) await comfyPage.closeMenu() - await comfyPage.resizeKsamplerNode(0.2, 1) + await comfyPage.nodeOps.resizeNode( + DefaultGraphPositions.ksampler.pos, + DefaultGraphPositions.ksampler.size, + 0.2, + 1 + ) await expect(comfyPage.canvas).toHaveScreenshot( `ksampler-resized-min-width.png` ) }) test("Doesn't truncate when space still available", async ({ comfyPage }) => { - await comfyPage.resizeEmptyLatentNode(0.8, 0.8) + await comfyPage.nodeOps.resizeNode( + DefaultGraphPositions.emptyLatent.pos, + DefaultGraphPositions.emptyLatent.size, + 0.8, + 0.8 + ) await expect(comfyPage.canvas).toHaveScreenshot( 'empty-latent-resized-80-percent.png' ) }) test('Can revert to full text', async ({ comfyPage }) => { - await comfyPage.resizeLoadCheckpointNode(0.8, 1, true) + await comfyPage.nodeOps.resizeNode( + DefaultGraphPositions.loadCheckpoint.pos, + DefaultGraphPositions.loadCheckpoint.size, + 0.8, + 1, + true + ) await expect(comfyPage.canvas).toHaveScreenshot('resized-to-original.png') }) @@ -42,7 +64,7 @@ test.describe('Combo text widget', { tag: ['@screenshot', '@widget'] }, () => { .options.values }) - await comfyPage.loadWorkflow('inputs/optional_combo_input') + await comfyPage.workflow.loadWorkflow('inputs/optional_combo_input') const initialComboValues = await getComboValues() // Focus canvas @@ -61,7 +83,7 @@ test.describe('Combo text widget', { tag: ['@screenshot', '@widget'] }, () => { test('Should refresh combo values of nodes with v2 combo input spec', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('inputs/node_with_v2_combo_input') + await comfyPage.workflow.loadWorkflow('inputs/node_with_v2_combo_input') // click canvas to focus await comfyPage.page.mouse.click(400, 300) // press R to trigger refresh @@ -81,7 +103,7 @@ test.describe('Combo text widget', { tag: ['@screenshot', '@widget'] }, () => { test.describe('Boolean widget', { tag: ['@screenshot', '@widget'] }, () => { test('Can toggle', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('widgets/boolean_widget') + await comfyPage.workflow.loadWorkflow('widgets/boolean_widget') await expect(comfyPage.canvas).toHaveScreenshot('boolean_widget.png') const node = (await comfyPage.nodeOps.getFirstNodeRef())! const widget = await node.getWidget(0) @@ -94,7 +116,7 @@ test.describe('Boolean widget', { tag: ['@screenshot', '@widget'] }, () => { test.describe('Slider widget', { tag: ['@screenshot', '@widget'] }, () => { test('Can drag adjust value', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('inputs/simple_slider') + await comfyPage.workflow.loadWorkflow('inputs/simple_slider') const node = (await comfyPage.nodeOps.getFirstNodeRef())! const widget = await node.getWidget(0) @@ -115,7 +137,7 @@ test.describe('Slider widget', { tag: ['@screenshot', '@widget'] }, () => { test.describe('Number widget', { tag: ['@screenshot', '@widget'] }, () => { test('Can drag adjust value', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('widgets/seed_widget') + await comfyPage.workflow.loadWorkflow('widgets/seed_widget') const node = (await comfyPage.nodeOps.getFirstNodeRef())! const widget = await node.getWidget(0) @@ -141,7 +163,7 @@ test.describe( test('Auto expand node when widget is added dynamically', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('nodes/single_ksampler') + await comfyPage.workflow.loadWorkflow('nodes/single_ksampler') await comfyPage.page.evaluate(() => { window['graph'].nodes[0].addWidget('number', 'new_widget', 10) @@ -157,12 +179,12 @@ test.describe( test.describe('Image widget', { tag: ['@screenshot', '@widget'] }, () => { test('Can load image', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('widgets/load_image_widget') + await comfyPage.workflow.loadWorkflow('widgets/load_image_widget') await expect(comfyPage.canvas).toHaveScreenshot('load_image_widget.png') }) test('Can drag and drop image', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('widgets/load_image_widget') + await comfyPage.workflow.loadWorkflow('widgets/load_image_widget') // Get position of the load image node const nodes = await comfyPage.nodeOps.getNodeRefsByType('LoadImage') @@ -188,7 +210,7 @@ test.describe('Image widget', { tag: ['@screenshot', '@widget'] }, () => { test('Can change image by changing the filename combo value', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('widgets/load_image_widget') + await comfyPage.workflow.loadWorkflow('widgets/load_image_widget') const nodes = await comfyPage.nodeOps.getNodeRefsByType('LoadImage') const loadImageNode = nodes[0] @@ -250,7 +272,7 @@ test.describe( test.skip('Shows preview of uploaded animated image', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('widgets/load_animated_webp') + await comfyPage.workflow.loadWorkflow('widgets/load_animated_webp') // Get position of the load animated webp node const nodes = await comfyPage.nodeOps.getNodeRefsByType( @@ -279,7 +301,7 @@ test.describe( }) test('Can drag-and-drop animated webp image', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('widgets/load_animated_webp') + await comfyPage.workflow.loadWorkflow('widgets/load_animated_webp') // Get position of the load animated webp node const nodes = await comfyPage.nodeOps.getNodeRefsByType( @@ -301,7 +323,7 @@ test.describe( }) test('Can preview saved animated webp image', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('widgets/save_animated_webp') + await comfyPage.workflow.loadWorkflow('widgets/save_animated_webp') // Get position of the load animated webp node const loadNodes = await comfyPage.nodeOps.getNodeRefsByType( @@ -341,7 +363,7 @@ test.describe( test.describe('Load audio widget', { tag: ['@screenshot', '@widget'] }, () => { test('Can load audio', async ({ comfyPage }) => { - await comfyPage.loadWorkflow('widgets/load_audio_widget') + await comfyPage.workflow.loadWorkflow('widgets/load_audio_widget') // Wait for the audio widget to be rendered in the DOM await comfyPage.page.waitForSelector('.comfy-audio', { state: 'attached' }) await comfyPage.nextFrame() @@ -354,7 +376,7 @@ test.describe('Unserialized widgets', { tag: '@widget' }, () => { comfyPage }) => { // Add workflow w/ LoadImage node, which contains file upload and image preview widgets (not serialized) - await comfyPage.loadWorkflow('widgets/load_image_widget') + await comfyPage.workflow.loadWorkflow('widgets/load_image_widget') // Move mouse and click to trigger the `graphEqual` check in `changeTracker.ts` await comfyPage.page.mouse.move(10, 10) diff --git a/browser_tests/tests/workflowTabThumbnail.spec.ts b/browser_tests/tests/workflowTabThumbnail.spec.ts index d1e1b8cce1..9b288129ae 100644 --- a/browser_tests/tests/workflowTabThumbnail.spec.ts +++ b/browser_tests/tests/workflowTabThumbnail.spec.ts @@ -5,8 +5,11 @@ import type { ComfyPage } from '../fixtures/ComfyPage' test.describe('Workflow Tab Thumbnails', { tag: '@workflow' }, () => { test.beforeEach(async ({ comfyPage }) => { - await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') - await comfyPage.setSetting('Comfy.Workflow.WorkflowTabsPosition', 'Topbar') + await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.settings.setSetting( + 'Comfy.Workflow.WorkflowTabsPosition', + 'Topbar' + ) await comfyPage.setup() })