mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-21 07:14:11 +00:00
refactor: remove ComfyPage wrapper methods, use helpers directly
- Remove 27 deprecated/wrapper methods from ComfyPage - Migrate callers to use helper classes directly: - keyboard.selectAll/bypass/undo/redo/moveUp/moveDown - clipboard.copy/paste - settings.setSetting/getSetting - workflow.loadWorkflow/deleteWorkflow/setupWorkflowsDirectory - contextMenu.clickMenuItem/clickLitegraphMenuItem - nodeOps.resizeNode with DefaultGraphPositions - canvasOps.clickEmptySpace with DefaultGraphPositions - Replace deprecated node click methods with direct canvas clicks - Replace position getter properties with DefaultGraphPositions imports Amp-Thread-ID: https://ampcode.com/threads/T-019c15e7-2319-76ec-855e-098ec75ef18a Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -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<void> {
|
||||
return this.settings.setSetting(settingId, settingValue)
|
||||
}
|
||||
|
||||
async getSetting<T = unknown>(settingId: string): Promise<T> {
|
||||
return this.settings.getSetting<T>(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<void> {
|
||||
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<void> {
|
||||
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}")`
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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')
|
||||
})
|
||||
|
||||
/**
|
||||
|
||||
@@ -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('')
|
||||
|
||||
@@ -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 }) => {
|
||||
|
||||
@@ -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 }) => {
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
|
||||
|
||||
@@ -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<string, Palette> = {
|
||||
@@ -153,23 +153,26 @@ const customColorPalettes: Record<string, Palette> = {
|
||||
|
||||
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')
|
||||
})
|
||||
|
||||
@@ -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' }, () => {
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
|
||||
@@ -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 }) => {
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 ({
|
||||
|
||||
@@ -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'] }, () => {
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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' }, () => {
|
||||
|
||||
@@ -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<Event> {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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'
|
||||
)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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'
|
||||
)
|
||||
|
||||
@@ -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'
|
||||
)
|
||||
|
||||
@@ -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'
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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' }, () => {
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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'
|
||||
)
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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'
|
||||
})
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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' }, () => {
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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++) {
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
|
||||
@@ -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'
|
||||
)
|
||||
|
||||
@@ -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')
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
|
||||
|
||||
@@ -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 }) => {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user