mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-05 23:50:08 +00:00
[Test] [Performance] Apply perf monitor wrappers to test files (4/4) (#4127)
Co-authored-by: Comfy Org PR Bot <snomiao+comfy-pr@gmail.com>
This commit is contained in:
12
CLAUDE.md
12
CLAUDE.md
@@ -4,7 +4,7 @@
|
||||
- When trying to set tailwind classes for dark theme, use "dark-theme:" prefix rather than "dark:"
|
||||
- Never add lines to PR descriptions that say "Generated with Claude Code"
|
||||
- When making PR names and commit messages, if you are going to add a prefix like "docs:", "feat:", "bugfix:", use square brackets around the prefix term and do not use a colon (e.g., should be "[docs]" rather than "docs:").
|
||||
- When I reference GitHub Repos related to Comfy-Org, you should proactively fetch or read the associated information in the repo. To do so, you should exhaust all options: (1) Check if we have a local copy of the repo, (2) Use the GitHub API to fetch the information; you may want to do this IN ADDITION to the other options, especially for reading speicifc branches/PRs/comments/reviews/metadata, and (3) curl the GitHub website and parse the html or json responses
|
||||
- When I reference GitHub Repos related to Comfy-Org, you should proactively fetch or read the associated information in the repo. To do so, you should exhaust all options: (1) Check if we have a local copy of the repo, (2) Use the GitHub API to fetch the information; you may want to do this IN ADDITION to the other options, especially for reading specific branches/PRs/comments/reviews/metadata, and (3) curl the GitHub website and parse the html or json responses
|
||||
- For information about ComfyUI, ComfyUI_frontend, or ComfyUI-Manager, you can web search or download these wikis: https://deepwiki.com/Comfy-Org/ComfyUI-Manager, https://deepwiki.com/Comfy-Org/ComfyUI_frontend/1-overview, https://deepwiki.com/comfyanonymous/ComfyUI/2-core-architecture
|
||||
- If a question/project is related to Comfy-Org, Comfy, or ComfyUI ecosystem, you should proactively use the Comfy docs to answer the question. The docs may be referenced with URLs like https://docs.comfy.org
|
||||
- When operating inside a repo, check for README files at key locations in the repo detailing info about the contents of that folder. E.g., top-level key folders like tests-ui, browser_tests, composables, extensions/core, stores, services often have their own README.md files. When writing code, make sure to frequently reference these README files to understand the overall architecture and design of the project. Pay close attention to the snippets to learn particular patterns that seem to be there for a reason, as you should emulate those.
|
||||
@@ -12,7 +12,7 @@
|
||||
- If using a lesser known or complex CLI tool, run the --help to see the documentation before deciding what to run, even if just for double-checking or verifying things.
|
||||
- IMPORTANT: the most important goal when writing code is to create clean, best-practices, sustainable, and scalable public APIs and interfaces. Our app is used by thousands of users and we have thousands of mods/extensions that are constantly changing and updating; and we are also always updating. That's why it is IMPORTANT that we design systems and write code that follows practices of domain-driven design, object-oriented design, and design patterns (such that you can assure stability while allowing for all components around you to change and evolve). We ABSOLUTELY prioritize clean APIs and public interfaces that clearly define and restrict how/what the mods/extensions can access.
|
||||
- If any of these technologies are referenced, you can proactively read their docs at these locations: https://primevue.org/theming, https://primevue.org/forms/, https://www.electronjs.org/docs/latest/api/browser-window, https://vitest.dev/guide/browser/, https://atlassian.design/components/pragmatic-drag-and-drop/core-package/drop-targets/, https://playwright.dev/docs/api/class-test, https://playwright.dev/docs/api/class-electron, https://www.algolia.com/doc/api-reference/rest-api/, https://pyav.org/docs/develop/cookbook/basics.html
|
||||
- IMPORTANT: Never add Co-Authored by Claude or any refrence to Claude or Claude Code in commit messages, PR descriptions, titles, or any documentation whatsoever
|
||||
- IMPORTANT: Never add Co-Authored by Claude or any reference to Claude or Claude Code in commit messages, PR descriptions, titles, or any documentation whatsoever
|
||||
- The npm script to type check is called "typecheck" NOT "type check"
|
||||
- Use the Vue 3 Composition API instead of the Options API when writing Vue components. An exception is when overriding or extending a PrimeVue component for compatibility, you may use the Options API.
|
||||
- when we are solving an issue we know the link/number for, we should add "Fixes #n" (where n is the issue number) to the PR description.
|
||||
@@ -46,3 +46,11 @@
|
||||
* `TabMenu` → Use `Tabs` without panels
|
||||
* `Steps` → Use `Stepper` without panels
|
||||
* `InlineMessage` → Use `Message` component
|
||||
* Use `api.apiURL()` for all backend API calls and routes
|
||||
- Actual API endpoints like /prompt, /queue, /view, etc.
|
||||
- Image previews: `api.apiURL('/view?...')`
|
||||
- Any backend-generated content or dynamic routes
|
||||
* Use `api.fileURL()` for static files served from the public folder:
|
||||
- Templates: `api.fileURL('/templates/default.json')`
|
||||
- Extensions: `api.fileURL(extensionPath)` for loading JS modules
|
||||
- Any static assets that exist in the public directory
|
||||
|
||||
@@ -3,6 +3,7 @@ import {
|
||||
comfyExpect as expect,
|
||||
comfyPageFixture as test
|
||||
} from '../fixtures/ComfyPage'
|
||||
import { PerformanceMonitor } from '../helpers/performanceMonitor'
|
||||
|
||||
async function beforeChange(comfyPage: ComfyPage) {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
@@ -22,93 +23,161 @@ test.describe('Change Tracker', () => {
|
||||
await comfyPage.setupWorkflowsDirectory({})
|
||||
})
|
||||
|
||||
test('Can undo multiple operations', async ({ comfyPage }) => {
|
||||
test('@perf Can undo multiple operations', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'undo-multiple-operations'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
expect(await comfyPage.getUndoQueueSize()).toBe(0)
|
||||
expect(await comfyPage.getRedoQueueSize()).toBe(0)
|
||||
|
||||
// Save, confirm no errors & workflow modified flag removed
|
||||
await comfyPage.menu.topbar.saveWorkflow('undo-redo-test')
|
||||
await perfMonitor.measureOperation('save-workflow', async () => {
|
||||
await comfyPage.menu.topbar.saveWorkflow('undo-redo-test')
|
||||
})
|
||||
expect(await comfyPage.getToastErrorCount()).toBe(0)
|
||||
expect(await comfyPage.isCurrentWorkflowModified()).toBe(false)
|
||||
expect(await comfyPage.getUndoQueueSize()).toBe(0)
|
||||
expect(await comfyPage.getRedoQueueSize()).toBe(0)
|
||||
|
||||
const node = (await comfyPage.getFirstNodeRef())!
|
||||
await node.click('title')
|
||||
await node.click('collapse')
|
||||
|
||||
await perfMonitor.measureOperation('click-node-title', async () => {
|
||||
await node.click('title')
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('collapse-node', async () => {
|
||||
await node.click('collapse')
|
||||
})
|
||||
await expect(node).toBeCollapsed()
|
||||
expect(await comfyPage.isCurrentWorkflowModified()).toBe(true)
|
||||
expect(await comfyPage.getUndoQueueSize()).toBe(1)
|
||||
expect(await comfyPage.getRedoQueueSize()).toBe(0)
|
||||
|
||||
await comfyPage.ctrlB()
|
||||
await perfMonitor.measureOperation('bypass-node', async () => {
|
||||
await comfyPage.ctrlB()
|
||||
})
|
||||
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 perfMonitor.markEvent('before-undo-operations')
|
||||
|
||||
await perfMonitor.measureOperation('undo-bypass', async () => {
|
||||
await comfyPage.ctrlZ()
|
||||
})
|
||||
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 perfMonitor.measureOperation('undo-collapse', async () => {
|
||||
await comfyPage.ctrlZ()
|
||||
})
|
||||
await expect(node).not.toBeCollapsed()
|
||||
expect(await comfyPage.isCurrentWorkflowModified()).toBe(false)
|
||||
expect(await comfyPage.getUndoQueueSize()).toBe(0)
|
||||
expect(await comfyPage.getRedoQueueSize()).toBe(2)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
test('Can group multiple change actions into a single transaction', async ({
|
||||
test('@perf Can group multiple change actions into a single transaction', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'group-change-transactions'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
const node = (await comfyPage.getFirstNodeRef())!
|
||||
expect(node).toBeTruthy()
|
||||
await expect(node).not.toBeCollapsed()
|
||||
await expect(node).not.toBeBypassed()
|
||||
|
||||
await perfMonitor.markEvent('individual-changes-start')
|
||||
|
||||
// Make changes outside set
|
||||
// Bypass + collapse node
|
||||
await node.click('title')
|
||||
await node.click('collapse')
|
||||
await comfyPage.ctrlB()
|
||||
await perfMonitor.measureOperation('click-node-title', async () => {
|
||||
await node.click('title')
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('collapse-node', async () => {
|
||||
await node.click('collapse')
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('bypass-node', async () => {
|
||||
await comfyPage.ctrlB()
|
||||
})
|
||||
await expect(node).toBeCollapsed()
|
||||
await expect(node).toBeBypassed()
|
||||
|
||||
// Undo, undo, ensure both changes undone
|
||||
await comfyPage.ctrlZ()
|
||||
await perfMonitor.measureOperation('undo-bypass', async () => {
|
||||
await comfyPage.ctrlZ()
|
||||
})
|
||||
await expect(node).not.toBeBypassed()
|
||||
await expect(node).toBeCollapsed()
|
||||
await comfyPage.ctrlZ()
|
||||
|
||||
await perfMonitor.measureOperation('undo-collapse', async () => {
|
||||
await comfyPage.ctrlZ()
|
||||
})
|
||||
await expect(node).not.toBeBypassed()
|
||||
await expect(node).not.toBeCollapsed()
|
||||
|
||||
// Prevent clicks registering a double-click
|
||||
await comfyPage.clickEmptySpace()
|
||||
await node.click('title')
|
||||
await perfMonitor.measureOperation('click-empty-space', async () => {
|
||||
await comfyPage.clickEmptySpace()
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('click-node-title-again', async () => {
|
||||
await node.click('title')
|
||||
})
|
||||
|
||||
await perfMonitor.markEvent('transaction-changes-start')
|
||||
|
||||
// Run again, but within a change transaction
|
||||
await beforeChange(comfyPage)
|
||||
await perfMonitor.measureOperation('begin-change-transaction', async () => {
|
||||
await beforeChange(comfyPage)
|
||||
})
|
||||
|
||||
await node.click('collapse')
|
||||
await comfyPage.ctrlB()
|
||||
await perfMonitor.measureOperation('collapse-in-transaction', async () => {
|
||||
await node.click('collapse')
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('bypass-in-transaction', async () => {
|
||||
await comfyPage.ctrlB()
|
||||
})
|
||||
await expect(node).toBeCollapsed()
|
||||
await expect(node).toBeBypassed()
|
||||
|
||||
// End transaction
|
||||
await afterChange(comfyPage)
|
||||
await perfMonitor.measureOperation('end-change-transaction', async () => {
|
||||
await afterChange(comfyPage)
|
||||
})
|
||||
|
||||
// Ensure undo reverts both changes
|
||||
await comfyPage.ctrlZ()
|
||||
await perfMonitor.measureOperation('undo-transaction', async () => {
|
||||
await comfyPage.ctrlZ()
|
||||
})
|
||||
await expect(node).not.toBeBypassed()
|
||||
await expect(node).not.toBeCollapsed()
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Can nest multiple change transactions without adding undo steps', async ({
|
||||
test('@perf Can nest multiple change transactions without adding undo steps', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'nested-change-transactions'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
const node = (await comfyPage.getFirstNodeRef())!
|
||||
const bypassAndPin = async () => {
|
||||
await beforeChange(comfyPage)
|
||||
@@ -136,32 +205,66 @@ test.describe('Change Tracker', () => {
|
||||
await afterChange(comfyPage)
|
||||
}
|
||||
|
||||
await multipleChanges()
|
||||
await perfMonitor.measureOperation(
|
||||
'execute-nested-transactions',
|
||||
async () => {
|
||||
await multipleChanges()
|
||||
}
|
||||
)
|
||||
|
||||
await comfyPage.ctrlZ()
|
||||
await perfMonitor.measureOperation('undo-all-changes', async () => {
|
||||
await comfyPage.ctrlZ()
|
||||
})
|
||||
await expect(node).not.toBeBypassed()
|
||||
await expect(node).not.toBePinned()
|
||||
await expect(node).not.toBeCollapsed()
|
||||
|
||||
await comfyPage.ctrlY()
|
||||
await perfMonitor.measureOperation('redo-all-changes', async () => {
|
||||
await comfyPage.ctrlY()
|
||||
})
|
||||
await expect(node).toBeBypassed()
|
||||
await expect(node).toBePinned()
|
||||
await expect(node).toBeCollapsed()
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Can detect changes in workflow.extra', async ({ comfyPage }) => {
|
||||
test('@perf Can detect changes in workflow.extra', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'detect-workflow-extra-changes'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
expect(await comfyPage.getUndoQueueSize()).toBe(0)
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['app'].graph.extra.foo = 'bar'
|
||||
|
||||
await perfMonitor.measureOperation('modify-workflow-extra', async () => {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['app'].graph.extra.foo = 'bar'
|
||||
})
|
||||
})
|
||||
|
||||
// Click empty space to trigger a change detection.
|
||||
await comfyPage.clickEmptySpace()
|
||||
await perfMonitor.measureOperation('trigger-change-detection', async () => {
|
||||
await comfyPage.clickEmptySpace()
|
||||
})
|
||||
expect(await comfyPage.getUndoQueueSize()).toBe(1)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Ignores changes in workflow.ds', async ({ comfyPage }) => {
|
||||
test('@perf Ignores changes in workflow.ds', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'ignore-workflow-ds-changes'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
expect(await comfyPage.getUndoQueueSize()).toBe(0)
|
||||
await comfyPage.pan({ x: 10, y: 10 })
|
||||
|
||||
await perfMonitor.measureOperation('pan-canvas', async () => {
|
||||
await comfyPage.pan({ x: 10, y: 10 })
|
||||
})
|
||||
expect(await comfyPage.getUndoQueueSize()).toBe(0)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -2,6 +2,7 @@ import { expect } from '@playwright/test'
|
||||
|
||||
import type { Palette } from '../../src/schemas/colorPaletteSchema'
|
||||
import { comfyPageFixture as test } from '../fixtures/ComfyPage'
|
||||
import { PerformanceMonitor } from '../helpers/performanceMonitor'
|
||||
|
||||
const customColorPalettes: Record<string, Palette> = {
|
||||
obsidian: {
|
||||
@@ -148,45 +149,99 @@ const customColorPalettes: Record<string, Palette> = {
|
||||
}
|
||||
|
||||
test.describe('Color Palette', () => {
|
||||
test('Can show custom color palette', async ({ comfyPage }) => {
|
||||
await comfyPage.setSetting('Comfy.CustomColorPalettes', customColorPalettes)
|
||||
test('@perf Can show custom color palette', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'show-custom-color-palette'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('set-custom-palettes', async () => {
|
||||
await comfyPage.setSetting(
|
||||
'Comfy.CustomColorPalettes',
|
||||
customColorPalettes
|
||||
)
|
||||
})
|
||||
|
||||
// Reload to apply the new setting. Setting Comfy.CustomColorPalettes directly
|
||||
// doesn't update the store immediately.
|
||||
await comfyPage.setup()
|
||||
await perfMonitor.measureOperation('reload-page', async () => {
|
||||
await comfyPage.setup()
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('load-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('every_node_color')
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation(
|
||||
'apply-obsidian-dark-palette',
|
||||
async () => {
|
||||
await comfyPage.setSetting('Comfy.ColorPalette', 'obsidian_dark')
|
||||
}
|
||||
)
|
||||
|
||||
await comfyPage.loadWorkflow('every_node_color')
|
||||
await comfyPage.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.nextFrame()
|
||||
|
||||
await perfMonitor.measureOperation('apply-light-red-palette', async () => {
|
||||
await comfyPage.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.nextFrame()
|
||||
await perfMonitor.measureOperation(
|
||||
'apply-default-dark-palette',
|
||||
async () => {
|
||||
await comfyPage.setSetting('Comfy.ColorPalette', 'dark')
|
||||
await comfyPage.nextFrame()
|
||||
}
|
||||
)
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('default-color-palette.png')
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Can add custom color palette', async ({ comfyPage }) => {
|
||||
await comfyPage.page.evaluate((p) => {
|
||||
window['app'].extensionManager.colorPalette.addCustomColorPalette(p)
|
||||
}, customColorPalettes.obsidian_dark)
|
||||
test('@perf Can add custom color palette', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'add-custom-color-palette'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('add-palette-via-api', async () => {
|
||||
await comfyPage.page.evaluate((p) => {
|
||||
window['app'].extensionManager.colorPalette.addCustomColorPalette(p)
|
||||
}, customColorPalettes.obsidian_dark)
|
||||
})
|
||||
|
||||
expect(await comfyPage.getToastErrorCount()).toBe(0)
|
||||
|
||||
await comfyPage.setSetting('Comfy.ColorPalette', 'obsidian_dark')
|
||||
await comfyPage.nextFrame()
|
||||
await perfMonitor.measureOperation('apply-custom-palette', async () => {
|
||||
await comfyPage.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.nextFrame()
|
||||
await perfMonitor.measureOperation(
|
||||
'apply-custom-palette-legacy-prefix',
|
||||
async () => {
|
||||
await comfyPage.setSetting('Comfy.ColorPalette', 'custom_obsidian_dark')
|
||||
await comfyPage.nextFrame()
|
||||
}
|
||||
)
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'custom-color-palette-obsidian-dark.png'
|
||||
)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -195,58 +250,120 @@ test.describe('Node Color Adjustments', () => {
|
||||
await comfyPage.loadWorkflow('every_node_color')
|
||||
})
|
||||
|
||||
test('should adjust opacity via node opacity setting', async ({
|
||||
test('@perf should adjust opacity via node opacity setting', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.setSetting('Comfy.Node.Opacity', 0.5)
|
||||
await comfyPage.page.waitForTimeout(128)
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'adjust-node-opacity'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('set-opacity-0-5', async () => {
|
||||
await comfyPage.setSetting('Comfy.Node.Opacity', 0.5)
|
||||
await comfyPage.page.waitForTimeout(128)
|
||||
})
|
||||
|
||||
// Drag mouse to force canvas to redraw
|
||||
await comfyPage.page.mouse.move(0, 0)
|
||||
await perfMonitor.measureOperation('redraw-canvas', async () => {
|
||||
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.page.waitForTimeout(128)
|
||||
await perfMonitor.measureOperation('set-opacity-1-0', async () => {
|
||||
await comfyPage.setSetting('Comfy.Node.Opacity', 1.0)
|
||||
await comfyPage.page.waitForTimeout(128)
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation(
|
||||
'redraw-canvas-full-opacity',
|
||||
async () => {
|
||||
await comfyPage.page.mouse.move(8, 8)
|
||||
}
|
||||
)
|
||||
|
||||
await comfyPage.page.mouse.move(8, 8)
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('node-opacity-1.png')
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('should persist color adjustments when changing themes', async ({
|
||||
test('@perf 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.nextFrame()
|
||||
await comfyPage.page.mouse.move(0, 0)
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'persist-opacity-across-themes'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('set-opacity-and-theme', async () => {
|
||||
await comfyPage.setSetting('Comfy.Node.Opacity', 0.2)
|
||||
await comfyPage.setSetting('Comfy.ColorPalette', 'arc')
|
||||
await comfyPage.nextFrame()
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('redraw-canvas-with-theme', async () => {
|
||||
await comfyPage.page.mouse.move(0, 0)
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'node-opacity-0.2-arc-theme.png'
|
||||
)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('should not serialize color adjustments in workflow', async ({
|
||||
test('@perf should not serialize color adjustments in workflow', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.setSetting('Comfy.Node.Opacity', 0.5)
|
||||
await comfyPage.setSetting('Comfy.ColorPalette', 'light')
|
||||
const saveWorkflowInterval = 1000
|
||||
await comfyPage.page.waitForTimeout(saveWorkflowInterval)
|
||||
const workflow = await comfyPage.page.evaluate(() => {
|
||||
return localStorage.getItem('workflow')
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'workflow-serialization-color-adjustments'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('apply-color-settings', async () => {
|
||||
await comfyPage.setSetting('Comfy.Node.Opacity', 0.5)
|
||||
await comfyPage.setSetting('Comfy.ColorPalette', 'light')
|
||||
})
|
||||
for (const node of JSON.parse(workflow ?? '{}').nodes) {
|
||||
|
||||
const saveWorkflowInterval = 1000
|
||||
await perfMonitor.measureOperation('wait-for-workflow-save', async () => {
|
||||
await comfyPage.page.waitForTimeout(saveWorkflowInterval)
|
||||
})
|
||||
|
||||
let workflow: string | null
|
||||
await perfMonitor.measureOperation(
|
||||
'get-workflow-from-storage',
|
||||
async () => {
|
||||
workflow = await comfyPage.page.evaluate(() => {
|
||||
return localStorage.getItem('workflow')
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
for (const node of JSON.parse(workflow! ?? '{}').nodes) {
|
||||
if (node.bgcolor) expect(node.bgcolor).not.toMatch(/hsla/)
|
||||
if (node.color) expect(node.color).not.toMatch(/hsla/)
|
||||
}
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('should lighten node colors when switching to light theme', async ({
|
||||
test('@perf should lighten node colors when switching to light theme', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.setSetting('Comfy.ColorPalette', 'light')
|
||||
await comfyPage.nextFrame()
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'lighten-colors-light-theme'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('apply-light-theme', async () => {
|
||||
await comfyPage.setSetting('Comfy.ColorPalette', 'light')
|
||||
await comfyPage.nextFrame()
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('node-lightened-colors.png')
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test.describe('Context menu color adjustments', () => {
|
||||
@@ -257,26 +374,48 @@ test.describe('Node Color Adjustments', () => {
|
||||
await node?.clickContextMenuOption('Colors')
|
||||
})
|
||||
|
||||
test('should persist color adjustments when changing custom node colors', async ({
|
||||
test('@perf should persist color adjustments when changing custom node colors', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.page
|
||||
.locator('.litemenu-entry.submenu span:has-text("red")')
|
||||
.click()
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'persist-opacity-color-change'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
// Context menu interaction - monitor the node color change operation
|
||||
await perfMonitor.measureOperation('select-red-color', async () => {
|
||||
await comfyPage.page
|
||||
.locator('.litemenu-entry.submenu span:has-text("red")')
|
||||
.click()
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'node-opacity-0.3-color-changed.png'
|
||||
)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('should persist color adjustments when removing custom node color', async ({
|
||||
test('@perf should persist color adjustments when removing custom node color', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.page
|
||||
.locator('.litemenu-entry.submenu span:has-text("No color")')
|
||||
.click()
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'persist-opacity-color-removal'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
// Context menu interaction - monitor the node color removal operation
|
||||
await perfMonitor.measureOperation('remove-node-color', async () => {
|
||||
await comfyPage.page
|
||||
.locator('.litemenu-entry.submenu span:has-text("No color")')
|
||||
.click()
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'node-opacity-0.3-color-removed.png'
|
||||
)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,6 +2,7 @@ import {
|
||||
comfyExpect as expect,
|
||||
comfyPageFixture as test
|
||||
} from '../fixtures/ComfyPage'
|
||||
import { PerformanceMonitor } from '../helpers/performanceMonitor'
|
||||
|
||||
test.describe('Node search box', () => {
|
||||
test.beforeEach(async ({ comfyPage }) => {
|
||||
@@ -27,24 +28,61 @@ test.describe('Node search box', () => {
|
||||
await expect(comfyPage.searchBox.input).toHaveCount(1)
|
||||
})
|
||||
|
||||
test('Can add node', async ({ comfyPage }) => {
|
||||
await comfyPage.doubleClickCanvas()
|
||||
await expect(comfyPage.searchBox.input).toHaveCount(1)
|
||||
await comfyPage.searchBox.fillAndSelectFirstNode('KSampler')
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('added-node.png')
|
||||
})
|
||||
test('@perf Can add node', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'add-node-via-search'
|
||||
|
||||
test('Can auto link node', async ({ comfyPage }) => {
|
||||
await comfyPage.disconnectEdge()
|
||||
// Select the second item as the first item is always reroute
|
||||
await comfyPage.searchBox.fillAndSelectFirstNode('CLIPTextEncode', {
|
||||
suggestionIndex: 0
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('double-click-canvas', async () => {
|
||||
await comfyPage.doubleClickCanvas()
|
||||
})
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('auto-linked-node.png')
|
||||
|
||||
await expect(comfyPage.searchBox.input).toHaveCount(1)
|
||||
|
||||
await perfMonitor.measureOperation('search-and-add-node', async () => {
|
||||
await comfyPage.searchBox.fillAndSelectFirstNode('KSampler')
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('added-node.png')
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Can auto link batch moved node', async ({ comfyPage }) => {
|
||||
await comfyPage.loadWorkflow('batch_move_links')
|
||||
test('@perf Can auto link node', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'auto-link-node'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('disconnect-edge', async () => {
|
||||
await comfyPage.disconnectEdge()
|
||||
})
|
||||
|
||||
// Select the second item as the first item is always reroute
|
||||
await perfMonitor.measureOperation(
|
||||
'search-and-auto-link-node',
|
||||
async () => {
|
||||
await comfyPage.searchBox.fillAndSelectFirstNode('CLIPTextEncode', {
|
||||
suggestionIndex: 0
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('auto-linked-node.png')
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('@perf Can auto link batch moved node', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'auto-link-batch-moved-node'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('load-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('batch_move_links')
|
||||
})
|
||||
|
||||
const outputSlot1Pos = {
|
||||
x: 304,
|
||||
@@ -54,29 +92,57 @@ test.describe('Node search box', () => {
|
||||
x: 5,
|
||||
y: 5
|
||||
}
|
||||
await comfyPage.page.keyboard.down('Shift')
|
||||
await comfyPage.dragAndDrop(outputSlot1Pos, emptySpacePos)
|
||||
await comfyPage.page.keyboard.up('Shift')
|
||||
|
||||
await perfMonitor.measureOperation('batch-move-links', async () => {
|
||||
await comfyPage.page.keyboard.down('Shift')
|
||||
await comfyPage.dragAndDrop(outputSlot1Pos, emptySpacePos)
|
||||
await comfyPage.page.keyboard.up('Shift')
|
||||
})
|
||||
|
||||
// Select the second item as the first item is always reroute
|
||||
await comfyPage.searchBox.fillAndSelectFirstNode('Load Checkpoint', {
|
||||
suggestionIndex: 0
|
||||
})
|
||||
await perfMonitor.measureOperation(
|
||||
'search-and-auto-link-batch-node',
|
||||
async () => {
|
||||
await comfyPage.searchBox.fillAndSelectFirstNode('Load Checkpoint', {
|
||||
suggestionIndex: 0
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'auto-linked-node-batch.png'
|
||||
)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Link release connecting to node with no slots', async ({
|
||||
test('@perf Link release connecting to node with no slots', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.disconnectEdge()
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'link-release-no-slots'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('disconnect-edge', async () => {
|
||||
await comfyPage.disconnectEdge()
|
||||
})
|
||||
|
||||
await expect(comfyPage.searchBox.input).toHaveCount(1)
|
||||
await comfyPage.page.locator('.p-chip-remove-icon').click()
|
||||
await comfyPage.searchBox.fillAndSelectFirstNode('KSampler')
|
||||
|
||||
await perfMonitor.measureOperation('remove-filter-chip', async () => {
|
||||
await comfyPage.page.locator('.p-chip-remove-icon').click()
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('add-node-no-connection', async () => {
|
||||
await comfyPage.searchBox.fillAndSelectFirstNode('KSampler')
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'added-node-no-connection.png'
|
||||
)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Has correct aria-labels on search results', async ({ comfyPage }) => {
|
||||
@@ -172,10 +238,10 @@ test.describe('Node search box', () => {
|
||||
await comfyPage.page.mouse.click(panelBounds!.x - 10, panelBounds!.y - 10)
|
||||
|
||||
// Verify the filter selection panel is hidden
|
||||
expect(panel.header).not.toBeVisible()
|
||||
await expect(panel.header).not.toBeVisible()
|
||||
|
||||
// Verify the node search dialog is still visible
|
||||
expect(comfyPage.searchBox.input).toBeVisible()
|
||||
await expect(comfyPage.searchBox.input).toBeVisible()
|
||||
})
|
||||
|
||||
test('Can add multiple filters', async ({ comfyPage }) => {
|
||||
@@ -252,16 +318,38 @@ test.describe('Release context menu', () => {
|
||||
)
|
||||
})
|
||||
|
||||
test('Can search and add node from context menu', async ({
|
||||
test('@perf Can search and add node from context menu', async ({
|
||||
comfyPage,
|
||||
comfyMouse
|
||||
}) => {
|
||||
await comfyPage.disconnectEdge()
|
||||
await comfyMouse.move({ x: 10, y: 10 })
|
||||
await comfyPage.clickContextMenuItem('Search')
|
||||
await comfyPage.searchBox.fillAndSelectFirstNode('CLIP Prompt')
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'context-menu-search-add-node'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('disconnect-edge', async () => {
|
||||
await comfyPage.disconnectEdge()
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('position-mouse', async () => {
|
||||
await comfyMouse.move({ x: 10, y: 10 })
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation(
|
||||
'click-context-menu-search',
|
||||
async () => {
|
||||
await comfyPage.clickContextMenuItem('Search')
|
||||
}
|
||||
)
|
||||
|
||||
await perfMonitor.measureOperation('search-and-add-node', async () => {
|
||||
await comfyPage.searchBox.fillAndSelectFirstNode('CLIP Prompt')
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'link-context-menu-search.png'
|
||||
)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,35 +1,83 @@
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
import { comfyPageFixture as test } from '../fixtures/ComfyPage'
|
||||
import { PerformanceMonitor } from '../helpers/performanceMonitor'
|
||||
|
||||
test.describe('Combo text widget', () => {
|
||||
test('Truncates text when resized', async ({ comfyPage }) => {
|
||||
await comfyPage.resizeLoadCheckpointNode(0.2, 1)
|
||||
test('@perf Truncates text when resized', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'combo-widget-resize-truncation'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation(
|
||||
'resize-load-checkpoint-node',
|
||||
async () => {
|
||||
await comfyPage.resizeLoadCheckpointNode(0.2, 1)
|
||||
}
|
||||
)
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'load-checkpoint-resized-min-width.png'
|
||||
)
|
||||
await comfyPage.closeMenu()
|
||||
await comfyPage.resizeKsamplerNode(0.2, 1)
|
||||
|
||||
await perfMonitor.measureOperation('close-menu', async () => {
|
||||
await comfyPage.closeMenu()
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('resize-ksampler-node', async () => {
|
||||
await comfyPage.resizeKsamplerNode(0.2, 1)
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
`ksampler-resized-min-width.png`
|
||||
)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test("Doesn't truncate when space still available", async ({ comfyPage }) => {
|
||||
await comfyPage.resizeEmptyLatentNode(0.8, 0.8)
|
||||
test("@perf Doesn't truncate when space still available", async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'combo-widget-no-truncation'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('resize-empty-latent-node', async () => {
|
||||
await comfyPage.resizeEmptyLatentNode(0.8, 0.8)
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'empty-latent-resized-80-percent.png'
|
||||
)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Can revert to full text', async ({ comfyPage }) => {
|
||||
await comfyPage.resizeLoadCheckpointNode(0.8, 1, true)
|
||||
test('@perf Can revert to full text', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'combo-widget-revert-text'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('resize-to-original', async () => {
|
||||
await comfyPage.resizeLoadCheckpointNode(0.8, 1, true)
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('resized-to-original.png')
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('should refresh combo values of optional inputs', async ({
|
||||
test('@perf should refresh combo values of optional inputs', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'combo-widget-refresh-optional-inputs'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
const getComboValues = async () =>
|
||||
comfyPage.page.evaluate(() => {
|
||||
return window['app'].graph.nodes
|
||||
@@ -38,171 +86,334 @@ test.describe('Combo text widget', () => {
|
||||
.options.values
|
||||
})
|
||||
|
||||
await comfyPage.loadWorkflow('optional_combo_input')
|
||||
const initialComboValues = await getComboValues()
|
||||
await perfMonitor.measureOperation('load-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('optional_combo_input')
|
||||
})
|
||||
|
||||
// Focus canvas
|
||||
await comfyPage.page.mouse.click(400, 300)
|
||||
let initialComboValues: any
|
||||
await perfMonitor.measureOperation('get-initial-combo-values', async () => {
|
||||
initialComboValues = await getComboValues()
|
||||
})
|
||||
|
||||
// Press R to trigger refresh
|
||||
await comfyPage.page.keyboard.press('r')
|
||||
await perfMonitor.measureOperation('focus-canvas', async () => {
|
||||
await comfyPage.page.mouse.click(400, 300)
|
||||
})
|
||||
|
||||
// Wait for nodes' widgets to be updated
|
||||
await comfyPage.nextFrame()
|
||||
await perfMonitor.measureOperation('trigger-refresh', async () => {
|
||||
await comfyPage.page.keyboard.press('r')
|
||||
})
|
||||
|
||||
const refreshedComboValues = await getComboValues()
|
||||
expect(refreshedComboValues).not.toEqual(initialComboValues)
|
||||
await perfMonitor.measureOperation('wait-for-update', async () => {
|
||||
await comfyPage.nextFrame()
|
||||
})
|
||||
|
||||
let refreshedComboValues: any
|
||||
await perfMonitor.measureOperation(
|
||||
'get-refreshed-combo-values',
|
||||
async () => {
|
||||
refreshedComboValues = await getComboValues()
|
||||
}
|
||||
)
|
||||
|
||||
expect(refreshedComboValues).not.toEqual(initialComboValues!)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Should refresh combo values of nodes with v2 combo input spec', async ({
|
||||
test('@perf Should refresh combo values of nodes with v2 combo input spec', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.loadWorkflow('node_with_v2_combo_input')
|
||||
// click canvas to focus
|
||||
await comfyPage.page.mouse.click(400, 300)
|
||||
// press R to trigger refresh
|
||||
await comfyPage.page.keyboard.press('r')
|
||||
// wait for nodes' widgets to be updated
|
||||
await comfyPage.page.mouse.click(400, 300)
|
||||
await comfyPage.nextFrame()
|
||||
// get the combo widget's values
|
||||
const comboValues = await comfyPage.page.evaluate(() => {
|
||||
return window['app'].graph.nodes
|
||||
.find((node) => node.title === 'Node With V2 Combo Input')
|
||||
.widgets.find((widget) => widget.name === 'combo_input').options.values
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'combo-widget-v2-refresh'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('load-v2-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('node_with_v2_combo_input')
|
||||
})
|
||||
expect(comboValues).toEqual(['A', 'B'])
|
||||
|
||||
await perfMonitor.measureOperation('focus-canvas', async () => {
|
||||
await comfyPage.page.mouse.click(400, 300)
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('trigger-refresh', async () => {
|
||||
await comfyPage.page.keyboard.press('r')
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('wait-for-update', async () => {
|
||||
await comfyPage.page.mouse.click(400, 300)
|
||||
await comfyPage.nextFrame()
|
||||
})
|
||||
|
||||
let comboValues: any
|
||||
await perfMonitor.measureOperation('get-combo-values', async () => {
|
||||
comboValues = await comfyPage.page.evaluate(() => {
|
||||
return window['app'].graph.nodes
|
||||
.find((node) => node.title === 'Node With V2 Combo Input')
|
||||
.widgets.find((widget) => widget.name === 'combo_input').options
|
||||
.values
|
||||
})
|
||||
})
|
||||
|
||||
expect(comboValues!).toEqual(['A', 'B'])
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Boolean widget', () => {
|
||||
test('Can toggle', async ({ comfyPage }) => {
|
||||
await comfyPage.loadWorkflow('widgets/boolean_widget')
|
||||
test('@perf Can toggle', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'boolean-widget-toggle'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('load-boolean-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('widgets/boolean_widget')
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('boolean_widget.png')
|
||||
const node = (await comfyPage.getFirstNodeRef())!
|
||||
const widget = await node.getWidget(0)
|
||||
await widget.click()
|
||||
|
||||
let node: any
|
||||
await perfMonitor.measureOperation('get-node-reference', async () => {
|
||||
node = (await comfyPage.getFirstNodeRef())!
|
||||
})
|
||||
|
||||
let widget: any
|
||||
await perfMonitor.measureOperation('get-widget-reference', async () => {
|
||||
widget = await node.getWidget(0)
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('toggle-boolean-widget', async () => {
|
||||
await widget.click()
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'boolean_widget_toggled.png'
|
||||
)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Slider widget', () => {
|
||||
test('Can drag adjust value', async ({ comfyPage }) => {
|
||||
await comfyPage.loadWorkflow('simple_slider')
|
||||
await comfyPage.page.waitForTimeout(300)
|
||||
const node = (await comfyPage.getFirstNodeRef())!
|
||||
const widget = await node.getWidget(0)
|
||||
test('@perf Can drag adjust value', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'slider-widget-drag-value'
|
||||
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const widget = window['app'].graph.nodes[0].widgets[0]
|
||||
widget.callback = (value: number) => {
|
||||
window['widgetValue'] = value
|
||||
}
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('load-slider-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('simple_slider')
|
||||
await comfyPage.page.waitForTimeout(300)
|
||||
})
|
||||
await widget.dragHorizontal(50)
|
||||
|
||||
let node: any
|
||||
await perfMonitor.measureOperation('get-node-reference', async () => {
|
||||
node = (await comfyPage.getFirstNodeRef())!
|
||||
})
|
||||
|
||||
let widget: any
|
||||
await perfMonitor.measureOperation('get-widget-reference', async () => {
|
||||
widget = await node.getWidget(0)
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('setup-widget-callback', async () => {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const widget = window['app'].graph.nodes[0].widgets[0]
|
||||
widget.callback = (value: number) => {
|
||||
window['widgetValue'] = value
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('drag-slider-widget', async () => {
|
||||
await widget.dragHorizontal(50)
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('slider_widget_dragged.png')
|
||||
|
||||
expect(
|
||||
await comfyPage.page.evaluate(() => window['widgetValue'])
|
||||
).toBeDefined()
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Number widget', () => {
|
||||
test('Can drag adjust value', async ({ comfyPage }) => {
|
||||
await comfyPage.loadWorkflow('widgets/seed_widget')
|
||||
await comfyPage.page.waitForTimeout(300)
|
||||
test('@perf Can drag adjust value', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'number-widget-drag-value'
|
||||
|
||||
const node = (await comfyPage.getFirstNodeRef())!
|
||||
const widget = await node.getWidget(0)
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const widget = window['app'].graph.nodes[0].widgets[0]
|
||||
widget.callback = (value: number) => {
|
||||
window['widgetValue'] = value
|
||||
}
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('load-seed-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('widgets/seed_widget')
|
||||
await comfyPage.page.waitForTimeout(300)
|
||||
})
|
||||
await widget.dragHorizontal(50)
|
||||
|
||||
let node: any
|
||||
await perfMonitor.measureOperation('get-node-reference', async () => {
|
||||
node = (await comfyPage.getFirstNodeRef())!
|
||||
})
|
||||
|
||||
let widget: any
|
||||
await perfMonitor.measureOperation('get-widget-reference', async () => {
|
||||
widget = await node.getWidget(0)
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('setup-widget-callback', async () => {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const widget = window['app'].graph.nodes[0].widgets[0]
|
||||
widget.callback = (value: number) => {
|
||||
window['widgetValue'] = value
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('drag-number-widget', async () => {
|
||||
await widget.dragHorizontal(50)
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('seed_widget_dragged.png')
|
||||
|
||||
expect(
|
||||
await comfyPage.page.evaluate(() => window['widgetValue'])
|
||||
).toBeDefined()
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Dynamic widget manipulation', () => {
|
||||
test('Auto expand node when widget is added dynamically', async ({
|
||||
test('@perf Auto expand node when widget is added dynamically', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.loadWorkflow('single_ksampler')
|
||||
await comfyPage.page.waitForTimeout(300)
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'dynamic-widget-addition'
|
||||
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['graph'].nodes[0].addWidget('number', 'new_widget', 10)
|
||||
window['graph'].setDirtyCanvas(true, true)
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('load-ksampler-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('single_ksampler')
|
||||
await comfyPage.page.waitForTimeout(300)
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('add-dynamic-widget', async () => {
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['graph'].nodes[0].addWidget('number', 'new_widget', 10)
|
||||
window['graph'].setDirtyCanvas(true, true)
|
||||
})
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('ksampler_widget_added.png')
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Image widget', () => {
|
||||
test('Can load image', async ({ comfyPage }) => {
|
||||
await comfyPage.loadWorkflow('widgets/load_image_widget')
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('load_image_widget.png')
|
||||
})
|
||||
test('@perf Can load image', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'image-widget-load'
|
||||
|
||||
test('Can drag and drop image', async ({ comfyPage }) => {
|
||||
await comfyPage.loadWorkflow('widgets/load_image_widget')
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
// Get position of the load image node
|
||||
const nodes = await comfyPage.getNodeRefsByType('LoadImage')
|
||||
const loadImageNode = nodes[0]
|
||||
const { x, y } = await loadImageNode.getPosition()
|
||||
|
||||
// Drag and drop image file onto the load image node
|
||||
await comfyPage.dragAndDropFile('image32x32.webp', {
|
||||
dropPosition: { x, y }
|
||||
await perfMonitor.measureOperation('load-image-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('widgets/load_image_widget')
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('load_image_widget.png')
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('@perf Can drag and drop image', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'image-widget-drag-drop'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('load-image-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('widgets/load_image_widget')
|
||||
})
|
||||
|
||||
let nodes: any
|
||||
let loadImageNode: any
|
||||
let position: any
|
||||
await perfMonitor.measureOperation('get-load-image-node', async () => {
|
||||
nodes = await comfyPage.getNodeRefsByType('LoadImage')
|
||||
loadImageNode = nodes[0]
|
||||
position = await loadImageNode.getPosition()
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('drag-drop-image-file', async () => {
|
||||
await comfyPage.dragAndDropFile('image32x32.webp', {
|
||||
dropPosition: { x: position.x, y: position.y }
|
||||
})
|
||||
})
|
||||
|
||||
// Expect the image preview to change automatically
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'image_preview_drag_and_dropped.png'
|
||||
)
|
||||
|
||||
// Expect the filename combo value to be updated
|
||||
const fileComboWidget = await loadImageNode.getWidget(0)
|
||||
const filename = await fileComboWidget.getValue()
|
||||
expect(filename).toBe('image32x32.webp')
|
||||
let fileComboWidget: any
|
||||
let filename: any
|
||||
await perfMonitor.measureOperation('get-updated-filename', async () => {
|
||||
fileComboWidget = await loadImageNode.getWidget(0)
|
||||
filename = await fileComboWidget.getValue()
|
||||
})
|
||||
|
||||
expect(filename!).toBe('image32x32.webp')
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Can change image by changing the filename combo value', async ({
|
||||
test('@perf Can change image by changing the filename combo value', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.loadWorkflow('widgets/load_image_widget')
|
||||
const nodes = await comfyPage.getNodeRefsByType('LoadImage')
|
||||
const loadImageNode = nodes[0]
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'image-widget-combo-change'
|
||||
|
||||
// Click the combo widget used to select the image filename
|
||||
const fileComboWidget = await loadImageNode.getWidget(0)
|
||||
await fileComboWidget.click()
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
// Select a new image filename value from the combo context menu
|
||||
const comboEntry = comfyPage.page.getByRole('menuitem', {
|
||||
name: 'image32x32.webp'
|
||||
await perfMonitor.measureOperation('load-image-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('widgets/load_image_widget')
|
||||
})
|
||||
|
||||
let nodes: any
|
||||
let loadImageNode: any
|
||||
await perfMonitor.measureOperation('get-load-image-node', async () => {
|
||||
nodes = await comfyPage.getNodeRefsByType('LoadImage')
|
||||
loadImageNode = nodes[0]
|
||||
})
|
||||
|
||||
let fileComboWidget: any
|
||||
await perfMonitor.measureOperation('click-combo-widget', async () => {
|
||||
fileComboWidget = await loadImageNode.getWidget(0)
|
||||
await fileComboWidget.click()
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('select-combo-entry', async () => {
|
||||
const comboEntry = comfyPage.page.getByRole('menuitem', {
|
||||
name: 'image32x32.webp'
|
||||
})
|
||||
await comboEntry.click({ noWaitAfter: true })
|
||||
})
|
||||
await comboEntry.click({ noWaitAfter: true })
|
||||
|
||||
// Expect the image preview to change automatically
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'image_preview_changed_by_combo_value.png'
|
||||
)
|
||||
|
||||
// Expect the filename combo value to be updated
|
||||
const filename = await fileComboWidget.getValue()
|
||||
expect(filename).toBe('image32x32.webp')
|
||||
let filename: any
|
||||
await perfMonitor.measureOperation('get-updated-filename', async () => {
|
||||
filename = await fileComboWidget.getValue()
|
||||
})
|
||||
|
||||
expect(filename!).toBe('image32x32.webp')
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -242,91 +453,164 @@ test.describe('Animated image widget', () => {
|
||||
)
|
||||
})
|
||||
|
||||
test('Can drag-and-drop animated webp image', async ({ comfyPage }) => {
|
||||
await comfyPage.loadWorkflow('widgets/load_animated_webp')
|
||||
test('@perf Can drag-and-drop animated webp image', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'animated-image-widget-drag-drop'
|
||||
|
||||
// Get position of the load animated webp node
|
||||
const nodes = await comfyPage.getNodeRefsByType(
|
||||
'DevToolsLoadAnimatedImageTest'
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation(
|
||||
'load-animated-webp-workflow',
|
||||
async () => {
|
||||
await comfyPage.loadWorkflow('widgets/load_animated_webp')
|
||||
}
|
||||
)
|
||||
const loadAnimatedWebpNode = nodes[0]
|
||||
const { x, y } = await loadAnimatedWebpNode.getPosition()
|
||||
|
||||
// Drag and drop image file onto the load animated webp node
|
||||
await comfyPage.dragAndDropFile('animated_webp.webp', {
|
||||
dropPosition: { x, y }
|
||||
let nodes: any
|
||||
let loadAnimatedWebpNode: any
|
||||
let position: any
|
||||
await perfMonitor.measureOperation('get-animated-webp-node', async () => {
|
||||
nodes = await comfyPage.getNodeRefsByType('DevToolsLoadAnimatedImageTest')
|
||||
loadAnimatedWebpNode = nodes[0]
|
||||
position = await loadAnimatedWebpNode.getPosition()
|
||||
})
|
||||
|
||||
// Expect the filename combo value to be updated
|
||||
const fileComboWidget = await loadAnimatedWebpNode.getWidget(0)
|
||||
const filename = await fileComboWidget.getValue()
|
||||
expect(filename).toContain('animated_webp.webp')
|
||||
await perfMonitor.measureOperation('drag-drop-animated-webp', async () => {
|
||||
await comfyPage.dragAndDropFile('animated_webp.webp', {
|
||||
dropPosition: { x: position.x, y: position.y }
|
||||
})
|
||||
})
|
||||
|
||||
let fileComboWidget: any
|
||||
let filename: any
|
||||
await perfMonitor.measureOperation('get-updated-filename', async () => {
|
||||
fileComboWidget = await loadAnimatedWebpNode.getWidget(0)
|
||||
filename = await fileComboWidget.getValue()
|
||||
})
|
||||
|
||||
expect(filename!).toContain('animated_webp.webp')
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Can preview saved animated webp image', async ({ comfyPage }) => {
|
||||
await comfyPage.loadWorkflow('widgets/save_animated_webp')
|
||||
test('@perf Can preview saved animated webp image', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'animated-image-widget-save-preview'
|
||||
|
||||
// Get position of the load animated webp node
|
||||
const loadNodes = await comfyPage.getNodeRefsByType(
|
||||
'DevToolsLoadAnimatedImageTest'
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation(
|
||||
'load-save-animated-workflow',
|
||||
async () => {
|
||||
await comfyPage.loadWorkflow('widgets/save_animated_webp')
|
||||
}
|
||||
)
|
||||
const loadAnimatedWebpNode = loadNodes[0]
|
||||
const { x, y } = await loadAnimatedWebpNode.getPosition()
|
||||
|
||||
// Drag and drop image file onto the load animated webp node
|
||||
await comfyPage.dragAndDropFile('animated_webp.webp', {
|
||||
dropPosition: { x, y }
|
||||
let loadNodes: any
|
||||
let loadAnimatedWebpNode: any
|
||||
let position: any
|
||||
await perfMonitor.measureOperation('get-load-node', async () => {
|
||||
loadNodes = await comfyPage.getNodeRefsByType(
|
||||
'DevToolsLoadAnimatedImageTest'
|
||||
)
|
||||
loadAnimatedWebpNode = loadNodes[0]
|
||||
position = await loadAnimatedWebpNode.getPosition()
|
||||
})
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
// Get the SaveAnimatedWEBP node
|
||||
const saveNodes = await comfyPage.getNodeRefsByType('SaveAnimatedWEBP')
|
||||
const saveAnimatedWebpNode = saveNodes[0]
|
||||
if (!saveAnimatedWebpNode)
|
||||
throw new Error('SaveAnimatedWEBP node not found')
|
||||
await perfMonitor.measureOperation('drag-drop-animated-file', async () => {
|
||||
await comfyPage.dragAndDropFile('animated_webp.webp', {
|
||||
dropPosition: { x: position.x, y: position.y }
|
||||
})
|
||||
await comfyPage.nextFrame()
|
||||
})
|
||||
|
||||
// Simulate the graph executing
|
||||
await comfyPage.page.evaluate(
|
||||
([loadId, saveId]) => {
|
||||
// Set the output of the SaveAnimatedWEBP node to equal the loader node's image
|
||||
window['app'].nodeOutputs[saveId] = window['app'].nodeOutputs[loadId]
|
||||
},
|
||||
[loadAnimatedWebpNode.id, saveAnimatedWebpNode.id]
|
||||
)
|
||||
await comfyPage.nextFrame()
|
||||
let saveNodes: any
|
||||
let saveAnimatedWebpNode: any
|
||||
await perfMonitor.measureOperation('get-save-node', async () => {
|
||||
saveNodes = await comfyPage.getNodeRefsByType('SaveAnimatedWEBP')
|
||||
saveAnimatedWebpNode = saveNodes[0]
|
||||
if (!saveAnimatedWebpNode)
|
||||
throw new Error('SaveAnimatedWEBP node not found')
|
||||
})
|
||||
|
||||
// Wait for animation to go to next frame
|
||||
await comfyPage.page.waitForTimeout(512)
|
||||
await perfMonitor.measureOperation('simulate-graph-execution', async () => {
|
||||
await comfyPage.page.evaluate(
|
||||
([loadId, saveId]) => {
|
||||
// Set the output of the SaveAnimatedWEBP node to equal the loader node's image
|
||||
window['app'].nodeOutputs[saveId] = window['app'].nodeOutputs[loadId]
|
||||
},
|
||||
[loadAnimatedWebpNode.id, saveAnimatedWebpNode.id]
|
||||
)
|
||||
await comfyPage.nextFrame()
|
||||
})
|
||||
|
||||
// Move mouse and click on canvas to trigger render
|
||||
await comfyPage.page.mouse.click(64, 64)
|
||||
await perfMonitor.measureOperation('wait-for-animation-frame', async () => {
|
||||
await comfyPage.page.waitForTimeout(512)
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('trigger-render', async () => {
|
||||
await comfyPage.page.mouse.click(64, 64)
|
||||
})
|
||||
|
||||
// Expect the SaveAnimatedWEBP node to have an output preview
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'animated_image_preview_saved_webp.png'
|
||||
)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Load audio widget', () => {
|
||||
test('Can load audio', async ({ comfyPage }) => {
|
||||
await comfyPage.loadWorkflow('widgets/load_audio_widget')
|
||||
test('@perf Can load audio', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'audio-widget-load'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('load-audio-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('widgets/load_audio_widget')
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('load_audio_widget.png')
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
test.describe('Unserialized widgets', () => {
|
||||
test('Unserialized widgets values do not mark graph as modified', async ({
|
||||
test('@perf Unserialized widgets values do not mark graph as modified', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
// Add workflow w/ LoadImage node, which contains file upload and image preview widgets (not serialized)
|
||||
await comfyPage.loadWorkflow('widgets/load_image_widget')
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'unserialized-widget-modification-check'
|
||||
|
||||
// Move mouse and click to trigger the `graphEqual` check in `changeTracker.ts`
|
||||
await comfyPage.page.mouse.move(10, 10)
|
||||
await comfyPage.page.mouse.click(10, 10)
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
// Expect the graph to not be modified
|
||||
expect(await comfyPage.isCurrentWorkflowModified()).toBe(false)
|
||||
await perfMonitor.measureOperation(
|
||||
'load-image-widget-workflow',
|
||||
async () => {
|
||||
await comfyPage.loadWorkflow('widgets/load_image_widget')
|
||||
}
|
||||
)
|
||||
|
||||
await perfMonitor.measureOperation(
|
||||
'trigger-graph-equal-check',
|
||||
async () => {
|
||||
await comfyPage.page.mouse.move(10, 10)
|
||||
await comfyPage.page.mouse.click(10, 10)
|
||||
}
|
||||
)
|
||||
|
||||
let isModified: any
|
||||
await perfMonitor.measureOperation(
|
||||
'check-workflow-modified-status',
|
||||
async () => {
|
||||
isModified = await comfyPage.isCurrentWorkflowModified()
|
||||
}
|
||||
)
|
||||
|
||||
expect(isModified!).toBe(false)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user