mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-11 02:20:08 +00:00
[Test] [Performance] Apply perf monitor wrappers to test files (2/4) (#4125)
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
import { comfyPageFixture as test } from '../fixtures/ComfyPage'
|
||||
import { PerformanceMonitor } from '../helpers/performanceMonitor'
|
||||
|
||||
test.describe('Background Image Upload', () => {
|
||||
test.beforeEach(async ({ comfyPage }) => {
|
||||
@@ -44,9 +45,14 @@ test.describe('Background Image Upload', () => {
|
||||
await expect(clearButton).toBeDisabled() // Should be disabled when no image
|
||||
})
|
||||
|
||||
test('should upload image file and set as background', async ({
|
||||
test('@perf should upload image file and set as background', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'upload-background-image-file'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
// Open settings dialog
|
||||
await comfyPage.page.keyboard.press('Control+,')
|
||||
|
||||
@@ -63,16 +69,18 @@ test.describe('Background Image Upload', () => {
|
||||
'button:has(.pi-upload)'
|
||||
)
|
||||
|
||||
// Set up file upload handler
|
||||
const fileChooserPromise = comfyPage.page.waitForEvent('filechooser')
|
||||
await uploadButton.click()
|
||||
const fileChooser = await fileChooserPromise
|
||||
|
||||
// Upload the test image
|
||||
await fileChooser.setFiles(comfyPage.assetPath('image32x32.webp'))
|
||||
// Set up file upload handler and upload
|
||||
await perfMonitor.measureOperation('trigger-file-upload', async () => {
|
||||
const fileChooserPromise = comfyPage.page.waitForEvent('filechooser')
|
||||
await uploadButton.click()
|
||||
const fileChooser = await fileChooserPromise
|
||||
await fileChooser.setFiles(comfyPage.assetPath('image32x32.webp'))
|
||||
})
|
||||
|
||||
// Wait for upload to complete and verify the setting was updated
|
||||
await comfyPage.page.waitForTimeout(500) // Give time for file reading
|
||||
await perfMonitor.measureOperation('process-uploaded-file', async () => {
|
||||
await comfyPage.page.waitForTimeout(500) // Give time for file reading
|
||||
})
|
||||
|
||||
// Verify the URL input now has an API URL
|
||||
const urlInput = backgroundImageSetting.locator('input[type="text"]')
|
||||
@@ -88,11 +96,18 @@ test.describe('Background Image Upload', () => {
|
||||
'Comfy.Canvas.BackgroundImage'
|
||||
)
|
||||
expect(settingValue).toMatch(/^\/api\/view\?.*subfolder=backgrounds/)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('should accept URL input for background image', async ({
|
||||
test('@perf should accept URL input for background image', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'input-background-image-url'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
const testImageUrl = 'https://example.com/test-image.png'
|
||||
|
||||
// Open settings dialog
|
||||
@@ -106,12 +121,13 @@ test.describe('Background Image Upload', () => {
|
||||
const backgroundImageSetting = comfyPage.page.locator(
|
||||
'#Comfy\\.Canvas\\.BackgroundImage'
|
||||
)
|
||||
|
||||
// Enter URL in the input field
|
||||
const urlInput = backgroundImageSetting.locator('input[type="text"]')
|
||||
await urlInput.fill(testImageUrl)
|
||||
|
||||
// Trigger blur event to ensure the value is set
|
||||
await urlInput.blur()
|
||||
await perfMonitor.measureOperation('input-url-text', async () => {
|
||||
await urlInput.fill(testImageUrl)
|
||||
await urlInput.blur()
|
||||
})
|
||||
|
||||
// Verify clear button is now enabled
|
||||
const clearButton = backgroundImageSetting.locator('button:has(.pi-trash)')
|
||||
@@ -122,15 +138,24 @@ test.describe('Background Image Upload', () => {
|
||||
'Comfy.Canvas.BackgroundImage'
|
||||
)
|
||||
expect(settingValue).toBe(testImageUrl)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('should clear background image when clear button is clicked', async ({
|
||||
test('@perf should clear background image when clear button is clicked', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'clear-background-image'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
const testImageUrl = 'https://example.com/test-image.png'
|
||||
|
||||
// First set a background image
|
||||
await comfyPage.setSetting('Comfy.Canvas.BackgroundImage', testImageUrl)
|
||||
await perfMonitor.measureOperation('set-initial-setting', async () => {
|
||||
await comfyPage.setSetting('Comfy.Canvas.BackgroundImage', testImageUrl)
|
||||
})
|
||||
|
||||
// Open settings dialog
|
||||
await comfyPage.page.keyboard.press('Control+,')
|
||||
@@ -152,7 +177,9 @@ test.describe('Background Image Upload', () => {
|
||||
await expect(clearButton).toBeEnabled()
|
||||
|
||||
// Click the clear button
|
||||
await clearButton.click()
|
||||
await perfMonitor.measureOperation('click-clear-button', async () => {
|
||||
await clearButton.click()
|
||||
})
|
||||
|
||||
// Verify the input is now empty
|
||||
await expect(urlInput).toHaveValue('')
|
||||
@@ -165,6 +192,8 @@ test.describe('Background Image Upload', () => {
|
||||
'Comfy.Canvas.BackgroundImage'
|
||||
)
|
||||
expect(settingValue).toBe('')
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('should show tooltip on upload and clear buttons', async ({
|
||||
@@ -211,9 +240,14 @@ test.describe('Background Image Upload', () => {
|
||||
await expect(clearTooltip).toBeVisible()
|
||||
})
|
||||
|
||||
test('should maintain reactive updates between URL input and clear button state', async ({
|
||||
test('@perf should maintain reactive updates between URL input and clear button state', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'reactive-widget-updates'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
// Open settings dialog
|
||||
await comfyPage.page.keyboard.press('Control+,')
|
||||
|
||||
@@ -232,20 +266,30 @@ test.describe('Background Image Upload', () => {
|
||||
await expect(clearButton).toBeDisabled()
|
||||
|
||||
// Type some text - clear button should become enabled
|
||||
await urlInput.fill('test')
|
||||
await perfMonitor.measureOperation('input-partial-text', async () => {
|
||||
await urlInput.fill('test')
|
||||
})
|
||||
await expect(clearButton).toBeEnabled()
|
||||
|
||||
// Clear the text manually - clear button should become disabled again
|
||||
await urlInput.fill('')
|
||||
await perfMonitor.measureOperation('clear-input-manually', async () => {
|
||||
await urlInput.fill('')
|
||||
})
|
||||
await expect(clearButton).toBeDisabled()
|
||||
|
||||
// Add text again - clear button should become enabled
|
||||
await urlInput.fill('https://example.com/image.png')
|
||||
await perfMonitor.measureOperation('input-full-url', async () => {
|
||||
await urlInput.fill('https://example.com/image.png')
|
||||
})
|
||||
await expect(clearButton).toBeEnabled()
|
||||
|
||||
// Use clear button - should clear input and disable itself
|
||||
await clearButton.click()
|
||||
await perfMonitor.measureOperation('clear-via-button', async () => {
|
||||
await clearButton.click()
|
||||
})
|
||||
await expect(urlInput).toHaveValue('')
|
||||
await expect(clearButton).toBeDisabled()
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Page, expect } from '@playwright/test'
|
||||
|
||||
import { comfyPageFixture as test } from '../fixtures/ComfyPage'
|
||||
import { PerformanceMonitor } from '../helpers/performanceMonitor'
|
||||
|
||||
interface ChatHistoryEntry {
|
||||
prompt: string
|
||||
@@ -42,49 +43,65 @@ test.describe('Chat History Widget', () => {
|
||||
await comfyPage.page.waitForSelector('.pi-pencil')
|
||||
})
|
||||
|
||||
test('displays chat history when receiving display_component message', async ({
|
||||
test('@perf displays chat history when receiving display_component message', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'display-chat-history-component'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
// Verify the chat history is displayed correctly
|
||||
await expect(comfyPage.page.getByText('Hello')).toBeVisible()
|
||||
await expect(comfyPage.page.getByText('World')).toBeVisible()
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('handles message editing interaction', async ({ comfyPage }) => {
|
||||
test('@perf handles message editing interaction', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'message-editing-interaction'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
// Get first node's ID
|
||||
nodeId = await comfyPage.page.evaluate(() => {
|
||||
const node = window['app'].graph.nodes[0]
|
||||
await perfMonitor.measureOperation('setup-node-widgets', async () => {
|
||||
nodeId = await comfyPage.page.evaluate(() => {
|
||||
const node = window['app'].graph.nodes[0]
|
||||
|
||||
// Make sure the node has a prompt widget (for editing functionality)
|
||||
if (!node.widgets) {
|
||||
node.widgets = []
|
||||
}
|
||||
// Make sure the node has a prompt widget (for editing functionality)
|
||||
if (!node.widgets) {
|
||||
node.widgets = []
|
||||
}
|
||||
|
||||
// Add a prompt widget if it doesn't exist
|
||||
if (!node.widgets.find((w) => w.name === 'prompt')) {
|
||||
node.widgets.push({
|
||||
name: 'prompt',
|
||||
type: 'text',
|
||||
value: 'Original prompt'
|
||||
})
|
||||
}
|
||||
// Add a prompt widget if it doesn't exist
|
||||
if (!node.widgets.find((w) => w.name === 'prompt')) {
|
||||
node.widgets.push({
|
||||
name: 'prompt',
|
||||
type: 'text',
|
||||
value: 'Original prompt'
|
||||
})
|
||||
}
|
||||
|
||||
return node.id
|
||||
return node.id
|
||||
})
|
||||
})
|
||||
|
||||
await renderChatHistory(comfyPage.page, [
|
||||
{
|
||||
prompt: 'Message 1',
|
||||
response: 'Response 1',
|
||||
response_id: '123'
|
||||
},
|
||||
{
|
||||
prompt: 'Message 2',
|
||||
response: 'Response 2',
|
||||
response_id: '456'
|
||||
}
|
||||
])
|
||||
await comfyPage.page.waitForSelector('.pi-pencil')
|
||||
await perfMonitor.measureOperation('render-chat-history', async () => {
|
||||
await renderChatHistory(comfyPage.page, [
|
||||
{
|
||||
prompt: 'Message 1',
|
||||
response: 'Response 1',
|
||||
response_id: '123'
|
||||
},
|
||||
{
|
||||
prompt: 'Message 2',
|
||||
response: 'Response 2',
|
||||
response_id: '456'
|
||||
}
|
||||
])
|
||||
await comfyPage.page.waitForSelector('.pi-pencil')
|
||||
})
|
||||
|
||||
const originalTextAreaInput = await comfyPage.page
|
||||
.getByPlaceholder('text')
|
||||
@@ -92,48 +109,73 @@ test.describe('Chat History Widget', () => {
|
||||
.inputValue()
|
||||
|
||||
// Click edit button on first message
|
||||
await comfyPage.page.getByLabel('Edit').first().click()
|
||||
await comfyPage.nextFrame()
|
||||
await perfMonitor.measureOperation('click-edit-button', async () => {
|
||||
await comfyPage.page.getByLabel('Edit').first().click()
|
||||
await comfyPage.nextFrame()
|
||||
})
|
||||
|
||||
// Verify cancel button appears
|
||||
await expect(comfyPage.page.getByLabel('Cancel')).toBeVisible()
|
||||
|
||||
// Click cancel edit
|
||||
await comfyPage.page.getByLabel('Cancel').click()
|
||||
await perfMonitor.measureOperation('click-cancel-button', async () => {
|
||||
await comfyPage.page.getByLabel('Cancel').click()
|
||||
})
|
||||
|
||||
// Verify prompt input is restored
|
||||
await expect(comfyPage.page.getByPlaceholder('text').nth(1)).toHaveValue(
|
||||
originalTextAreaInput
|
||||
)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('handles real-time updates to chat history', async ({ comfyPage }) => {
|
||||
test('@perf handles real-time updates to chat history', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'real-time-chat-history-updates'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
// Send initial history
|
||||
await renderChatHistory(comfyPage.page, [
|
||||
{
|
||||
prompt: 'Initial message',
|
||||
response: 'Initial response',
|
||||
response_id: '123'
|
||||
}
|
||||
])
|
||||
await comfyPage.page.waitForSelector('.pi-pencil')
|
||||
await perfMonitor.measureOperation('render-initial-history', async () => {
|
||||
await renderChatHistory(comfyPage.page, [
|
||||
{
|
||||
prompt: 'Initial message',
|
||||
response: 'Initial response',
|
||||
response_id: '123'
|
||||
}
|
||||
])
|
||||
await comfyPage.page.waitForSelector('.pi-pencil')
|
||||
})
|
||||
|
||||
await perfMonitor.markEvent('before-history-update')
|
||||
|
||||
// Update history with additional messages
|
||||
await renderChatHistory(comfyPage.page, [
|
||||
{
|
||||
prompt: 'Follow-up',
|
||||
response: 'New response',
|
||||
response_id: '456'
|
||||
}
|
||||
])
|
||||
await comfyPage.page.waitForSelector('.pi-pencil')
|
||||
await perfMonitor.measureOperation('update-chat-history', async () => {
|
||||
await renderChatHistory(comfyPage.page, [
|
||||
{
|
||||
prompt: 'Follow-up',
|
||||
response: 'New response',
|
||||
response_id: '456'
|
||||
}
|
||||
])
|
||||
await comfyPage.page.waitForSelector('.pi-pencil')
|
||||
})
|
||||
|
||||
// Move mouse over the canvas to force update
|
||||
await comfyPage.page.mouse.move(100, 100)
|
||||
await comfyPage.nextFrame()
|
||||
await perfMonitor.measureOperation('trigger-canvas-update', async () => {
|
||||
await comfyPage.page.mouse.move(100, 100)
|
||||
await comfyPage.nextFrame()
|
||||
})
|
||||
|
||||
await perfMonitor.markEvent('after-canvas-update')
|
||||
|
||||
// Verify new messages appear
|
||||
await expect(comfyPage.page.getByText('Follow-up')).toBeVisible()
|
||||
await expect(comfyPage.page.getByText('New response')).toBeVisible()
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Locator, expect } from '@playwright/test'
|
||||
|
||||
import type { Keybinding } from '../../src/schemas/keyBindingSchema'
|
||||
import { comfyPageFixture as test } from '../fixtures/ComfyPage'
|
||||
import { PerformanceMonitor } from '../helpers/performanceMonitor'
|
||||
|
||||
test.describe('Load workflow warning', () => {
|
||||
test('Should display a warning when loading a workflow with missing nodes', async ({
|
||||
@@ -15,46 +16,89 @@ test.describe('Load workflow warning', () => {
|
||||
})
|
||||
})
|
||||
|
||||
test('Does not report warning on undo/redo', async ({ comfyPage }) => {
|
||||
test('@perf Does not report warning on undo/redo', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'undo-redo-no-warning'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await comfyPage.setSetting('Comfy.NodeSearchBoxImpl', 'default')
|
||||
|
||||
await comfyPage.loadWorkflow('missing_nodes')
|
||||
await perfMonitor.measureOperation('load-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('missing_nodes')
|
||||
})
|
||||
|
||||
await comfyPage.closeDialog()
|
||||
|
||||
// Make a change to the graph
|
||||
await comfyPage.doubleClickCanvas()
|
||||
await comfyPage.searchBox.fillAndSelectFirstNode('KSampler')
|
||||
await perfMonitor.measureOperation('add-node-sequence', async () => {
|
||||
await comfyPage.doubleClickCanvas()
|
||||
await comfyPage.searchBox.fillAndSelectFirstNode('KSampler')
|
||||
})
|
||||
|
||||
// Undo and redo the change
|
||||
await comfyPage.ctrlZ()
|
||||
await perfMonitor.measureOperation('undo-operation', async () => {
|
||||
await comfyPage.ctrlZ()
|
||||
})
|
||||
|
||||
await expect(comfyPage.page.locator('.comfy-missing-nodes')).not.toBeVisible()
|
||||
await comfyPage.ctrlY()
|
||||
|
||||
await perfMonitor.measureOperation('redo-operation', async () => {
|
||||
await comfyPage.ctrlY()
|
||||
})
|
||||
|
||||
await expect(comfyPage.page.locator('.comfy-missing-nodes')).not.toBeVisible()
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test.describe('Execution error', () => {
|
||||
test('Should display an error message when an execution error occurs', async ({
|
||||
test('@perf Should display an error message when an execution error occurs', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.loadWorkflow('execution_error')
|
||||
await comfyPage.queueButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'execution-error-display'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('load-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('execution_error')
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('queue-execution', async () => {
|
||||
await comfyPage.queueButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
})
|
||||
|
||||
// Wait for the element with the .comfy-execution-error selector to be visible
|
||||
const executionError = comfyPage.page.locator('.comfy-error-report')
|
||||
await expect(executionError).toBeVisible()
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Can display Issue Report form', async ({ comfyPage }) => {
|
||||
await comfyPage.loadWorkflow('execution_error')
|
||||
await comfyPage.queueButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
test('@perf Can display Issue Report form', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'issue-report-form-display'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('load-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('execution_error')
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('queue-execution', async () => {
|
||||
await comfyPage.queueButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
})
|
||||
|
||||
await comfyPage.page.getByLabel('Help Fix This').click()
|
||||
const issueReportForm = comfyPage.page.getByText(
|
||||
'Submit Error Report (Optional)'
|
||||
)
|
||||
await expect(issueReportForm).toBeVisible()
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -355,18 +399,28 @@ test.describe('Error dialog', () => {
|
||||
})
|
||||
|
||||
test.describe('Signin dialog', () => {
|
||||
test('Paste content to signin dialog should not paste node on canvas', async ({
|
||||
test('@perf Paste content to signin dialog should not paste node on canvas', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const nodeNum = (await comfyPage.getNodes()).length
|
||||
await comfyPage.clickEmptyLatentNode()
|
||||
await comfyPage.ctrlC()
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'signin-dialog-paste-isolation'
|
||||
|
||||
const textBox = comfyPage.widgetTextBox
|
||||
await textBox.click()
|
||||
await textBox.fill('test_password')
|
||||
await textBox.press('Control+a')
|
||||
await textBox.press('Control+c')
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
const nodeNum = (await comfyPage.getNodes()).length
|
||||
|
||||
await perfMonitor.measureOperation('copy-node-sequence', async () => {
|
||||
await comfyPage.clickEmptyLatentNode()
|
||||
await comfyPage.ctrlC()
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('widget-text-operations', async () => {
|
||||
const textBox = comfyPage.widgetTextBox
|
||||
await textBox.click()
|
||||
await textBox.fill('test_password')
|
||||
await textBox.press('Control+a')
|
||||
await textBox.press('Control+c')
|
||||
})
|
||||
|
||||
await comfyPage.page.evaluate(() => {
|
||||
window['app'].extensionManager.dialog.showSignInDialog()
|
||||
@@ -378,5 +432,7 @@ test.describe('Signin dialog', () => {
|
||||
await expect(input).toHaveValue('test_password')
|
||||
|
||||
expect(await comfyPage.getNodes()).toHaveLength(nodeNum)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -2,6 +2,7 @@ import { expect } from '@playwright/test'
|
||||
|
||||
import { ComfyPage, comfyPageFixture as test } from '../fixtures/ComfyPage'
|
||||
import type { NodeReference } from '../fixtures/utils/litegraphUtils'
|
||||
import { PerformanceMonitor } from '../helpers/performanceMonitor'
|
||||
|
||||
test.describe('Group Node', () => {
|
||||
test.describe('Node library sidebar', () => {
|
||||
@@ -21,25 +22,47 @@ test.describe('Group Node', () => {
|
||||
expect(await libraryTab.getFolder('group nodes').count()).toBe(1)
|
||||
})
|
||||
|
||||
test('Can be added to canvas using node library sidebar', async ({
|
||||
test('@perf Can be added to canvas using node library sidebar', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'add-group-node-from-library'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
const initialNodeCount = await comfyPage.getGraphNodesCount()
|
||||
|
||||
// Add group node from node library sidebar
|
||||
await libraryTab.getFolder(groupNodeCategory).click()
|
||||
await libraryTab.getNode(groupNodeName).click()
|
||||
await perfMonitor.measureOperation('expand-category-folder', async () => {
|
||||
await libraryTab.getFolder(groupNodeCategory).click()
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('add-node-from-library', async () => {
|
||||
await libraryTab.getNode(groupNodeName).click()
|
||||
})
|
||||
|
||||
// Verify the node is added to the canvas
|
||||
expect(await comfyPage.getGraphNodesCount()).toBe(initialNodeCount + 1)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Can be bookmarked and unbookmarked', async ({ comfyPage }) => {
|
||||
await libraryTab.getFolder(groupNodeCategory).click()
|
||||
await libraryTab
|
||||
.getNode(groupNodeName)
|
||||
.locator('.bookmark-button')
|
||||
.click()
|
||||
test('@perf Can be bookmarked and unbookmarked', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'bookmark-unbookmark-group-node'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('expand-category-folder', async () => {
|
||||
await libraryTab.getFolder(groupNodeCategory).click()
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('bookmark-node', async () => {
|
||||
await libraryTab
|
||||
.getNode(groupNodeName)
|
||||
.locator('.bookmark-button')
|
||||
.click()
|
||||
})
|
||||
|
||||
// Verify the node is added to the bookmarks tab
|
||||
expect(
|
||||
@@ -49,16 +72,20 @@ test.describe('Group Node', () => {
|
||||
expect(await libraryTab.getNode(groupNodeName).count()).not.toBe(0)
|
||||
|
||||
// Unbookmark the node
|
||||
await libraryTab
|
||||
.getNode(groupNodeName)
|
||||
.locator('.bookmark-button')
|
||||
.first()
|
||||
.click()
|
||||
await perfMonitor.measureOperation('unbookmark-node', async () => {
|
||||
await libraryTab
|
||||
.getNode(groupNodeName)
|
||||
.locator('.bookmark-button')
|
||||
.first()
|
||||
.click()
|
||||
})
|
||||
|
||||
// Verify the node is removed from the bookmarks tab
|
||||
expect(
|
||||
await comfyPage.getSetting('Comfy.NodeLibrary.Bookmarks.V2')
|
||||
).toHaveLength(0)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Displays preview on bookmark hover', async ({ comfyPage }) => {
|
||||
@@ -95,18 +122,37 @@ test.describe('Group Node', () => {
|
||||
)
|
||||
})
|
||||
|
||||
test('Displays tooltip on title hover', async ({ comfyPage }) => {
|
||||
test('@perf Displays tooltip on title hover', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'group-node-tooltip-display'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await comfyPage.setSetting('Comfy.EnableTooltips', true)
|
||||
await comfyPage.convertAllNodesToGroupNode('Group Node')
|
||||
await comfyPage.page.mouse.move(47, 173)
|
||||
const tooltipTimeout = 500
|
||||
await comfyPage.page.waitForTimeout(tooltipTimeout + 16)
|
||||
|
||||
await perfMonitor.measureOperation('convert-to-group-node', async () => {
|
||||
await comfyPage.convertAllNodesToGroupNode('Group Node')
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('hover-for-tooltip', async () => {
|
||||
await comfyPage.page.mouse.move(47, 173)
|
||||
const tooltipTimeout = 500
|
||||
await comfyPage.page.waitForTimeout(tooltipTimeout + 16)
|
||||
})
|
||||
|
||||
await expect(comfyPage.page.locator('.node-tooltip')).toBeVisible()
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Manage group opens with the correct group selected', async ({
|
||||
test('@perf Manage group opens with the correct group selected', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'manage-group-node-selection'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
const makeGroup = async (name, type1, type2) => {
|
||||
const node1 = (await comfyPage.getNodeRefsByType(type1))[0]
|
||||
const node2 = (await comfyPage.getNodeRefsByType(type2))[0]
|
||||
@@ -117,21 +163,44 @@ test.describe('Group Node', () => {
|
||||
return await node2.convertToGroupNode(name)
|
||||
}
|
||||
|
||||
const group1 = await makeGroup(
|
||||
'g1',
|
||||
'CLIPTextEncode',
|
||||
'CheckpointLoaderSimple'
|
||||
)
|
||||
const group2 = await makeGroup('g2', 'EmptyLatentImage', 'KSampler')
|
||||
let group1
|
||||
await perfMonitor.measureOperation('create-first-group', async () => {
|
||||
group1 = await makeGroup('g1', 'CLIPTextEncode', 'CheckpointLoaderSimple')
|
||||
})
|
||||
|
||||
let group2
|
||||
await perfMonitor.measureOperation('create-second-group', async () => {
|
||||
group2 = await makeGroup('g2', 'EmptyLatentImage', 'KSampler')
|
||||
})
|
||||
|
||||
let manage1
|
||||
await perfMonitor.measureOperation('open-first-manage-dialog', async () => {
|
||||
manage1 = await group1.manageGroupNode()
|
||||
await comfyPage.nextFrame()
|
||||
})
|
||||
|
||||
const manage1 = await group1.manageGroupNode()
|
||||
await comfyPage.nextFrame()
|
||||
expect(await manage1.getSelectedNodeType()).toBe('g1')
|
||||
await manage1.close()
|
||||
|
||||
await perfMonitor.measureOperation(
|
||||
'close-first-manage-dialog',
|
||||
async () => {
|
||||
await manage1.close()
|
||||
}
|
||||
)
|
||||
|
||||
await expect(manage1.root).not.toBeVisible()
|
||||
|
||||
const manage2 = await group2.manageGroupNode()
|
||||
let manage2
|
||||
await perfMonitor.measureOperation(
|
||||
'open-second-manage-dialog',
|
||||
async () => {
|
||||
manage2 = await group2.manageGroupNode()
|
||||
}
|
||||
)
|
||||
|
||||
expect(await manage2.getSelectedNodeType()).toBe('g2')
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Preserves hidden input configuration when containing duplicate node types', async ({
|
||||
@@ -165,9 +234,14 @@ test.describe('Group Node', () => {
|
||||
expect(visibleInputCount).toBe(2)
|
||||
})
|
||||
|
||||
test('Reconnects inputs after configuration changed via manage dialog save', async ({
|
||||
test('@perf Reconnects inputs after configuration changed via manage dialog save', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'reconnect-inputs-after-config-change'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
const expectSingleNode = async (type: string) => {
|
||||
const nodes = await comfyPage.getNodeRefsByType(type)
|
||||
expect(nodes).toHaveLength(1)
|
||||
@@ -175,30 +249,65 @@ test.describe('Group Node', () => {
|
||||
}
|
||||
const latent = await expectSingleNode('EmptyLatentImage')
|
||||
const sampler = await expectSingleNode('KSampler')
|
||||
|
||||
// Remove existing link
|
||||
const samplerInput = await sampler.getInput(0)
|
||||
await samplerInput.removeLinks()
|
||||
await perfMonitor.measureOperation('remove-existing-links', async () => {
|
||||
await samplerInput.removeLinks()
|
||||
})
|
||||
|
||||
// Group latent + sampler
|
||||
await latent.click('title', {
|
||||
modifiers: ['Shift']
|
||||
await perfMonitor.measureOperation('select-nodes-for-group', async () => {
|
||||
await latent.click('title', {
|
||||
modifiers: ['Shift']
|
||||
})
|
||||
await sampler.click('title', {
|
||||
modifiers: ['Shift']
|
||||
})
|
||||
})
|
||||
await sampler.click('title', {
|
||||
modifiers: ['Shift']
|
||||
|
||||
let groupNode
|
||||
await perfMonitor.measureOperation('convert-to-group-node', async () => {
|
||||
groupNode = await sampler.convertToGroupNode()
|
||||
})
|
||||
const groupNode = await sampler.convertToGroupNode()
|
||||
|
||||
// Connect node to group
|
||||
const ckpt = await expectSingleNode('CheckpointLoaderSimple')
|
||||
const input = await ckpt.connectOutput(0, groupNode, 0)
|
||||
let input
|
||||
await perfMonitor.measureOperation('connect-nodes', async () => {
|
||||
input = await ckpt.connectOutput(0, groupNode, 0)
|
||||
})
|
||||
|
||||
expect(await input.getLinkCount()).toBe(1)
|
||||
|
||||
// Modify the group node via manage dialog
|
||||
const manage = await groupNode.manageGroupNode()
|
||||
await manage.selectNode('KSampler')
|
||||
await manage.changeTab('Inputs')
|
||||
await manage.setLabel('model', 'test')
|
||||
await manage.save()
|
||||
await manage.close()
|
||||
await perfMonitor.markEvent('before-manage-dialog')
|
||||
|
||||
let manage
|
||||
await perfMonitor.measureOperation('open-manage-dialog', async () => {
|
||||
manage = await groupNode.manageGroupNode()
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation(
|
||||
'configure-in-manage-dialog',
|
||||
async () => {
|
||||
await manage.selectNode('KSampler')
|
||||
await manage.changeTab('Inputs')
|
||||
await manage.setLabel('model', 'test')
|
||||
await manage.save()
|
||||
}
|
||||
)
|
||||
|
||||
await perfMonitor.measureOperation('close-manage-dialog', async () => {
|
||||
await manage.close()
|
||||
})
|
||||
|
||||
await perfMonitor.markEvent('after-manage-dialog')
|
||||
|
||||
// Ensure the link is still present
|
||||
expect(await input.getLinkCount()).toBe(1)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Loads from a workflow using the legacy path separator ("/")', async ({
|
||||
@@ -254,57 +363,131 @@ test.describe('Group Node', () => {
|
||||
await groupNode.copy()
|
||||
})
|
||||
|
||||
test('Copies and pastes group node within the same workflow', async ({
|
||||
test('@perf Copies and pastes group node within the same workflow', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.ctrlV()
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'copy-paste-group-node-same-workflow'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('paste-group-node', async () => {
|
||||
await comfyPage.ctrlV()
|
||||
})
|
||||
|
||||
await verifyNodeLoaded(comfyPage, 2)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Copies and pastes group node after clearing workflow', async ({
|
||||
test('@perf Copies and pastes group node after clearing workflow', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.menu.topbar.triggerTopbarCommand([
|
||||
'Edit',
|
||||
'Clear Workflow'
|
||||
])
|
||||
await comfyPage.ctrlV()
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'copy-paste-group-node-after-clear'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('clear-workflow', async () => {
|
||||
await comfyPage.menu.topbar.triggerTopbarCommand([
|
||||
'Edit',
|
||||
'Clear Workflow'
|
||||
])
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('paste-group-node', async () => {
|
||||
await comfyPage.ctrlV()
|
||||
})
|
||||
|
||||
await verifyNodeLoaded(comfyPage, 1)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Copies and pastes group node into a newly created blank workflow', async ({
|
||||
test('@perf Copies and pastes group node into a newly created blank workflow', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.menu.topbar.triggerTopbarCommand(['Workflow', 'New'])
|
||||
await comfyPage.ctrlV()
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'copy-paste-group-node-new-workflow'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('create-new-workflow', async () => {
|
||||
await comfyPage.menu.topbar.triggerTopbarCommand(['Workflow', 'New'])
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('paste-group-node', async () => {
|
||||
await comfyPage.ctrlV()
|
||||
})
|
||||
|
||||
await verifyNodeLoaded(comfyPage, 1)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Copies and pastes group node across different workflows', async ({
|
||||
test('@perf Copies and pastes group node across different workflows', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.loadWorkflow('default')
|
||||
await comfyPage.ctrlV()
|
||||
await verifyNodeLoaded(comfyPage, 1)
|
||||
})
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'copy-paste-group-node-different-workflow'
|
||||
|
||||
test('Serializes group node after copy and paste across workflows', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.menu.topbar.triggerTopbarCommand(['Workflow', 'New'])
|
||||
await comfyPage.ctrlV()
|
||||
const currentGraphState = await comfyPage.page.evaluate(() =>
|
||||
window['app'].graph.serialize()
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation(
|
||||
'load-different-workflow',
|
||||
async () => {
|
||||
await comfyPage.loadWorkflow('default')
|
||||
}
|
||||
)
|
||||
|
||||
await test.step('Load workflow containing a group node pasted from a different workflow', async () => {
|
||||
await comfyPage.page.evaluate(
|
||||
(workflow) => window['app'].loadGraphData(workflow),
|
||||
currentGraphState
|
||||
await perfMonitor.measureOperation('paste-group-node', async () => {
|
||||
await comfyPage.ctrlV()
|
||||
})
|
||||
|
||||
await verifyNodeLoaded(comfyPage, 1)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('@perf Serializes group node after copy and paste across workflows', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'serialize-group-node-cross-workflow'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('create-new-workflow', async () => {
|
||||
await comfyPage.menu.topbar.triggerTopbarCommand(['Workflow', 'New'])
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('paste-group-node', async () => {
|
||||
await comfyPage.ctrlV()
|
||||
})
|
||||
|
||||
let currentGraphState
|
||||
await perfMonitor.measureOperation('serialize-graph', async () => {
|
||||
currentGraphState = await comfyPage.page.evaluate(() =>
|
||||
window['app'].graph.serialize()
|
||||
)
|
||||
await comfyPage.nextFrame()
|
||||
})
|
||||
|
||||
await test.step('Load workflow containing a group node pasted from a different workflow', async () => {
|
||||
await perfMonitor.measureOperation(
|
||||
'load-serialized-workflow',
|
||||
async () => {
|
||||
await comfyPage.page.evaluate(
|
||||
(workflow) => window['app'].loadGraphData(workflow),
|
||||
currentGraphState
|
||||
)
|
||||
await comfyPage.nextFrame()
|
||||
}
|
||||
)
|
||||
|
||||
await verifyNodeLoaded(comfyPage, 1)
|
||||
})
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -315,12 +498,31 @@ test.describe('Group Node', () => {
|
||||
await comfyPage.page.waitForTimeout(300)
|
||||
expect(await comfyPage.getVisibleToastCount()).toBe(1)
|
||||
})
|
||||
test('Convert to group node, selected 1 node', async ({ comfyPage }) => {
|
||||
test('@perf Convert to group node, selected 1 node', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'convert-single-node-to-group-keybinding'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
expect(await comfyPage.getVisibleToastCount()).toBe(0)
|
||||
await comfyPage.clickTextEncodeNode1()
|
||||
await comfyPage.page.keyboard.press('Alt+g')
|
||||
await comfyPage.page.waitForTimeout(300)
|
||||
|
||||
await perfMonitor.measureOperation('select-node', async () => {
|
||||
await comfyPage.clickTextEncodeNode1()
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation(
|
||||
'trigger-group-keybinding',
|
||||
async () => {
|
||||
await comfyPage.page.keyboard.press('Alt+g')
|
||||
await comfyPage.page.waitForTimeout(300)
|
||||
}
|
||||
)
|
||||
|
||||
expect(await comfyPage.getVisibleToastCount()).toBe(1)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -2,6 +2,7 @@ import { expect } from '@playwright/test'
|
||||
|
||||
import { comfyPageFixture as test } from '../fixtures/ComfyPage'
|
||||
import { getMiddlePoint } from '../fixtures/utils/litegraphUtils'
|
||||
import { PerformanceMonitor } from '../helpers/performanceMonitor'
|
||||
|
||||
test.describe('Reroute Node', () => {
|
||||
test.beforeEach(async ({ comfyPage }) => {
|
||||
@@ -12,29 +13,56 @@ test.describe('Reroute Node', () => {
|
||||
await comfyPage.setupWorkflowsDirectory({})
|
||||
})
|
||||
|
||||
test('loads from inserted workflow', async ({ comfyPage }) => {
|
||||
test('@perf loads from inserted workflow', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'load-workflow-with-reroute'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
const workflowName = 'single_connected_reroute_node.json'
|
||||
await comfyPage.setupWorkflowsDirectory({
|
||||
[workflowName]: workflowName
|
||||
await perfMonitor.measureOperation('setup-workflow-directory', async () => {
|
||||
await comfyPage.setupWorkflowsDirectory({
|
||||
[workflowName]: workflowName
|
||||
})
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('setup-page', async () => {
|
||||
await comfyPage.setup()
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('create-new-workflow', async () => {
|
||||
await comfyPage.menu.topbar.triggerTopbarCommand(['Workflow', 'New'])
|
||||
})
|
||||
await comfyPage.setup()
|
||||
await comfyPage.menu.topbar.triggerTopbarCommand(['Workflow', 'New'])
|
||||
|
||||
// Insert the workflow
|
||||
const workflowsTab = comfyPage.menu.workflowsTab
|
||||
await workflowsTab.open()
|
||||
await workflowsTab.getPersistedItem(workflowName).click({ button: 'right' })
|
||||
const insertButton = comfyPage.page.locator('.p-contextmenu-item-link', {
|
||||
hasText: 'Insert'
|
||||
await perfMonitor.measureOperation('open-workflows-tab', async () => {
|
||||
await workflowsTab.open()
|
||||
})
|
||||
await insertButton.click()
|
||||
|
||||
// Close the sidebar tab
|
||||
await workflowsTab.tabButton.click()
|
||||
await workflowsTab.root.waitFor({ state: 'hidden' })
|
||||
await comfyPage.setFocusMode(true)
|
||||
await perfMonitor.measureOperation('insert-workflow', async () => {
|
||||
await workflowsTab
|
||||
.getPersistedItem(workflowName)
|
||||
.click({ button: 'right' })
|
||||
const insertButton = comfyPage.page.locator('.p-contextmenu-item-link', {
|
||||
hasText: 'Insert'
|
||||
})
|
||||
await insertButton.click()
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('close-sidebar', async () => {
|
||||
// Close the sidebar tab
|
||||
await workflowsTab.tabButton.click()
|
||||
await workflowsTab.root.waitFor({ state: 'hidden' })
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('set-focus-mode', async () => {
|
||||
await comfyPage.setFocusMode(true)
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('reroute_inserted.png')
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -43,53 +71,108 @@ test.describe('LiteGraph Native Reroute Node', () => {
|
||||
await comfyPage.setSetting('LiteGraph.Reroute.SplineOffset', 80)
|
||||
})
|
||||
|
||||
test('loads from workflow', async ({ comfyPage }) => {
|
||||
await comfyPage.loadWorkflow('reroute/native_reroute')
|
||||
test('@perf loads from workflow', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'load-native-reroute-workflow'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('load-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('reroute/native_reroute')
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('native_reroute.png')
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Can add reroute by alt clicking on link', async ({ comfyPage }) => {
|
||||
const loadCheckpointNode = (
|
||||
await comfyPage.getNodeRefsByTitle('Load Checkpoint')
|
||||
)[0]
|
||||
const clipEncodeNode = (
|
||||
await comfyPage.getNodeRefsByTitle('CLIP Text Encode (Prompt)')
|
||||
)[0]
|
||||
test('@perf Can add reroute by alt clicking on link', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'add-reroute-alt-click'
|
||||
|
||||
const slot1 = await loadCheckpointNode.getOutput(1)
|
||||
const slot2 = await clipEncodeNode.getInput(0)
|
||||
const middlePoint = getMiddlePoint(
|
||||
await slot1.getPosition(),
|
||||
await slot2.getPosition()
|
||||
)
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await comfyPage.page.keyboard.down('Alt')
|
||||
await comfyPage.page.mouse.click(middlePoint.x, middlePoint.y)
|
||||
await comfyPage.page.keyboard.up('Alt')
|
||||
let loadCheckpointNode: any
|
||||
let clipEncodeNode: any
|
||||
|
||||
await perfMonitor.measureOperation('get-nodes', async () => {
|
||||
loadCheckpointNode = (
|
||||
await comfyPage.getNodeRefsByTitle('Load Checkpoint')
|
||||
)[0]
|
||||
clipEncodeNode = (
|
||||
await comfyPage.getNodeRefsByTitle('CLIP Text Encode (Prompt)')
|
||||
)[0]
|
||||
})
|
||||
|
||||
let slot1: any
|
||||
let slot2: any
|
||||
let middlePoint: any
|
||||
|
||||
await perfMonitor.measureOperation('calculate-link-position', async () => {
|
||||
slot1 = await loadCheckpointNode.getOutput(1)
|
||||
slot2 = await clipEncodeNode.getInput(0)
|
||||
middlePoint = getMiddlePoint(
|
||||
await slot1.getPosition(),
|
||||
await slot2.getPosition()
|
||||
)
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('alt-click-link', async () => {
|
||||
await comfyPage.page.keyboard.down('Alt')
|
||||
await comfyPage.page.mouse.click(middlePoint.x, middlePoint.y)
|
||||
await comfyPage.page.keyboard.up('Alt')
|
||||
})
|
||||
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'native_reroute_alt_click.png'
|
||||
)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('Can add reroute by clicking middle of link context menu', async ({
|
||||
test('@perf Can add reroute by clicking middle of link context menu', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const loadCheckpointNode = (
|
||||
await comfyPage.getNodeRefsByTitle('Load Checkpoint')
|
||||
)[0]
|
||||
const clipEncodeNode = (
|
||||
await comfyPage.getNodeRefsByTitle('CLIP Text Encode (Prompt)')
|
||||
)[0]
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'add-reroute-context-menu'
|
||||
|
||||
const slot1 = await loadCheckpointNode.getOutput(1)
|
||||
const slot2 = await clipEncodeNode.getInput(0)
|
||||
const middlePoint = getMiddlePoint(
|
||||
await slot1.getPosition(),
|
||||
await slot2.getPosition()
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
let loadCheckpointNode: any
|
||||
let clipEncodeNode: any
|
||||
|
||||
await perfMonitor.measureOperation('get-nodes', async () => {
|
||||
loadCheckpointNode = (
|
||||
await comfyPage.getNodeRefsByTitle('Load Checkpoint')
|
||||
)[0]
|
||||
clipEncodeNode = (
|
||||
await comfyPage.getNodeRefsByTitle('CLIP Text Encode (Prompt)')
|
||||
)[0]
|
||||
})
|
||||
|
||||
let slot1: any
|
||||
let slot2: any
|
||||
let middlePoint: any
|
||||
|
||||
await perfMonitor.measureOperation('calculate-link-position', async () => {
|
||||
slot1 = await loadCheckpointNode.getOutput(1)
|
||||
slot2 = await clipEncodeNode.getInput(0)
|
||||
middlePoint = getMiddlePoint(
|
||||
await slot1.getPosition(),
|
||||
await slot2.getPosition()
|
||||
)
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation(
|
||||
'click-link-for-context-menu',
|
||||
async () => {
|
||||
await comfyPage.page.mouse.click(middlePoint.x, middlePoint.y)
|
||||
}
|
||||
)
|
||||
|
||||
await comfyPage.page.mouse.click(middlePoint.x, middlePoint.y)
|
||||
// Context menu interaction not monitored (floating menu - skip per guide)
|
||||
await comfyPage.page
|
||||
.locator('.litecontextmenu .litemenu-entry', { hasText: 'Add Reroute' })
|
||||
.click()
|
||||
@@ -97,5 +180,7 @@ test.describe('LiteGraph Native Reroute Node', () => {
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
'native_reroute_context_menu.png'
|
||||
)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
import { comfyPageFixture } from '../fixtures/ComfyPage'
|
||||
import { PerformanceMonitor } from '../helpers/performanceMonitor'
|
||||
|
||||
const test = comfyPageFixture
|
||||
|
||||
@@ -12,14 +13,21 @@ test.describe('Selection Toolbox', () => {
|
||||
await comfyPage.setSetting('Comfy.Canvas.SelectionToolbox', true)
|
||||
})
|
||||
|
||||
test('shows selection toolbox', async ({ comfyPage }) => {
|
||||
test('@perf shows selection toolbox', async ({ comfyPage }) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'show-selection-toolbox'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
// By default, selection toolbox should be enabled
|
||||
expect(
|
||||
await comfyPage.page.locator('.selection-overlay-container').isVisible()
|
||||
).toBe(false)
|
||||
|
||||
// Select multiple nodes
|
||||
await comfyPage.selectNodes(['KSampler', 'CLIP Text Encode (Prompt)'])
|
||||
await perfMonitor.measureOperation('select-multiple-nodes', async () => {
|
||||
await comfyPage.selectNodes(['KSampler', 'CLIP Text Encode (Prompt)'])
|
||||
})
|
||||
|
||||
// Selection toolbox should be visible with multiple nodes selected
|
||||
await expect(
|
||||
@@ -28,16 +36,37 @@ test.describe('Selection Toolbox', () => {
|
||||
await expect(
|
||||
comfyPage.page.locator('.selection-overlay-container.show-border')
|
||||
).toBeVisible()
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('shows at correct position when node is pasted', async ({
|
||||
test('@perf shows at correct position when node is pasted', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.loadWorkflow('single_ksampler')
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
await comfyPage.ctrlC()
|
||||
await comfyPage.page.mouse.move(100, 100)
|
||||
await comfyPage.ctrlV()
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'node-paste-position'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('load-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('single_ksampler')
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('select-node', async () => {
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('copy-node', async () => {
|
||||
await comfyPage.ctrlC()
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('position-mouse', async () => {
|
||||
await comfyPage.page.mouse.move(100, 100)
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('paste-node', async () => {
|
||||
await comfyPage.ctrlV()
|
||||
})
|
||||
|
||||
const overlayContainer = comfyPage.page.locator(
|
||||
'.selection-overlay-container'
|
||||
@@ -51,28 +80,59 @@ test.describe('Selection Toolbox', () => {
|
||||
expect(Math.round(boundingBox!.x)).toBeCloseTo(90, -1) // Allow ~10px tolerance
|
||||
// 30px offset of node title height
|
||||
expect(Math.round(boundingBox!.y)).toBeCloseTo(60, -1)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('hide when select and drag happen at the same time', async ({
|
||||
test('@perf hide when select and drag happen at the same time', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await comfyPage.loadWorkflow('single_ksampler')
|
||||
const node = (await comfyPage.getNodeRefsByTitle('KSampler'))[0]
|
||||
const nodePos = await node.getPosition()
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'hide-toolbox-during-drag'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
await perfMonitor.measureOperation('load-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('single_ksampler')
|
||||
})
|
||||
|
||||
let node: any
|
||||
let nodePos: any
|
||||
await perfMonitor.measureOperation('get-node-position', async () => {
|
||||
node = (await comfyPage.getNodeRefsByTitle('KSampler'))[0]
|
||||
nodePos = await node.getPosition()
|
||||
})
|
||||
|
||||
// Drag on the title of the node
|
||||
await comfyPage.page.mouse.move(nodePos.x + 100, nodePos.y - 15)
|
||||
await comfyPage.page.mouse.down()
|
||||
await comfyPage.page.mouse.move(nodePos.x + 200, nodePos.y + 200)
|
||||
await perfMonitor.measureOperation('start-drag', async () => {
|
||||
await comfyPage.page.mouse.move(nodePos.x + 100, nodePos.y - 15)
|
||||
await comfyPage.page.mouse.down()
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('drag-to-position', async () => {
|
||||
await comfyPage.page.mouse.move(nodePos.x + 200, nodePos.y + 200)
|
||||
})
|
||||
|
||||
await comfyPage.nextFrame()
|
||||
await expect(
|
||||
comfyPage.page.locator('.selection-overlay-container')
|
||||
).not.toBeVisible()
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('shows border only with multiple selections', async ({ comfyPage }) => {
|
||||
test('@perf shows border only with multiple selections', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'border-multiple-selections'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
// Select single node
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
await perfMonitor.measureOperation('select-single-node', async () => {
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
})
|
||||
|
||||
// Selection overlay should be visible but without border
|
||||
await expect(
|
||||
@@ -83,7 +143,9 @@ test.describe('Selection Toolbox', () => {
|
||||
).not.toBeVisible()
|
||||
|
||||
// Select multiple nodes
|
||||
await comfyPage.selectNodes(['KSampler', 'CLIP Text Encode (Prompt)'])
|
||||
await perfMonitor.measureOperation('select-multiple-nodes', async () => {
|
||||
await comfyPage.selectNodes(['KSampler', 'CLIP Text Encode (Prompt)'])
|
||||
})
|
||||
|
||||
// Selection overlay should show border with multiple selections
|
||||
await expect(
|
||||
@@ -91,23 +153,37 @@ test.describe('Selection Toolbox', () => {
|
||||
).toBeVisible()
|
||||
|
||||
// Deselect to single node
|
||||
await comfyPage.selectNodes(['CLIP Text Encode (Prompt)'])
|
||||
await perfMonitor.measureOperation('deselect-to-single', async () => {
|
||||
await comfyPage.selectNodes(['CLIP Text Encode (Prompt)'])
|
||||
})
|
||||
|
||||
// Border should be hidden again
|
||||
await expect(
|
||||
comfyPage.page.locator('.selection-overlay-container.show-border')
|
||||
).not.toBeVisible()
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('displays bypass button in toolbox when nodes are selected', async ({
|
||||
test('@perf displays bypass button in toolbox when nodes are selected', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'bypass-button-display'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
// A group + a KSampler node
|
||||
await comfyPage.loadWorkflow('single_group')
|
||||
await perfMonitor.measureOperation('load-workflow', async () => {
|
||||
await comfyPage.loadWorkflow('single_group')
|
||||
})
|
||||
|
||||
// Select group + node should show bypass button
|
||||
await comfyPage.page.focus('canvas')
|
||||
await comfyPage.page.keyboard.press('Control+A')
|
||||
await perfMonitor.measureOperation('select-all-nodes', async () => {
|
||||
await comfyPage.page.focus('canvas')
|
||||
await comfyPage.page.keyboard.press('Control+A')
|
||||
})
|
||||
|
||||
await expect(
|
||||
comfyPage.page.locator(
|
||||
'.selection-toolbox *[data-testid="bypass-button"]'
|
||||
@@ -115,20 +191,32 @@ test.describe('Selection Toolbox', () => {
|
||||
).toBeVisible()
|
||||
|
||||
// Deselect node (Only group is selected) should hide bypass button
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
await perfMonitor.measureOperation('select-single-node', async () => {
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
})
|
||||
|
||||
await expect(
|
||||
comfyPage.page.locator(
|
||||
'.selection-toolbox *[data-testid="bypass-button"]'
|
||||
)
|
||||
).not.toBeVisible()
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test.describe('Color Picker', () => {
|
||||
test('displays color picker button and allows color selection', async ({
|
||||
test('@perf displays color picker button and allows color selection', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'color-picker-selection'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
// Select a node
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
await perfMonitor.measureOperation('select-node', async () => {
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
})
|
||||
|
||||
// Color picker button should be visible
|
||||
const colorPickerButton = comfyPage.page.locator(
|
||||
@@ -137,7 +225,9 @@ test.describe('Selection Toolbox', () => {
|
||||
await expect(colorPickerButton).toBeVisible()
|
||||
|
||||
// Click color picker button
|
||||
await colorPickerButton.click()
|
||||
await perfMonitor.measureOperation('open-color-picker', async () => {
|
||||
await colorPickerButton.click()
|
||||
})
|
||||
|
||||
// Color picker dropdown should be visible
|
||||
const colorPickerDropdown = comfyPage.page.locator(
|
||||
@@ -146,10 +236,12 @@ test.describe('Selection Toolbox', () => {
|
||||
await expect(colorPickerDropdown).toBeVisible()
|
||||
|
||||
// Select a color (e.g., blue)
|
||||
const blueColorOption = colorPickerDropdown.locator(
|
||||
'i[data-testid="blue"]'
|
||||
)
|
||||
await blueColorOption.click()
|
||||
await perfMonitor.measureOperation('select-color', async () => {
|
||||
const blueColorOption = colorPickerDropdown.locator(
|
||||
'i[data-testid="blue"]'
|
||||
)
|
||||
await blueColorOption.click()
|
||||
})
|
||||
|
||||
// Dropdown should close after selection
|
||||
await expect(colorPickerDropdown).not.toBeVisible()
|
||||
@@ -158,13 +250,22 @@ test.describe('Selection Toolbox', () => {
|
||||
// Note: Exact verification method depends on how color is applied to nodes
|
||||
const selectedNode = (await comfyPage.getNodeRefsByTitle('KSampler'))[0]
|
||||
expect(selectedNode.getProperty('color')).not.toBeNull()
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('color picker shows current color of selected nodes', async ({
|
||||
test('@perf color picker shows current color of selected nodes', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'color-picker-current-color'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
// Select multiple nodes
|
||||
await comfyPage.selectNodes(['KSampler', 'CLIP Text Encode (Prompt)'])
|
||||
await perfMonitor.measureOperation('select-multiple-nodes', async () => {
|
||||
await comfyPage.selectNodes(['KSampler', 'CLIP Text Encode (Prompt)'])
|
||||
})
|
||||
|
||||
const colorPickerButton = comfyPage.page.locator(
|
||||
'.selection-toolbox .pi-circle-fill'
|
||||
@@ -174,84 +275,136 @@ test.describe('Selection Toolbox', () => {
|
||||
await expect(colorPickerButton).not.toHaveAttribute('color')
|
||||
|
||||
// Click color picker and select a color
|
||||
await colorPickerButton.click()
|
||||
const redColorOption = comfyPage.page.locator(
|
||||
'.color-picker-container i[data-testid="red"]'
|
||||
)
|
||||
await redColorOption.click()
|
||||
await perfMonitor.measureOperation('open-color-picker', async () => {
|
||||
await colorPickerButton.click()
|
||||
})
|
||||
|
||||
await perfMonitor.measureOperation('select-red-color', async () => {
|
||||
const redColorOption = comfyPage.page.locator(
|
||||
'.color-picker-container i[data-testid="red"]'
|
||||
)
|
||||
await redColorOption.click()
|
||||
})
|
||||
|
||||
// Button should now show the selected color
|
||||
await expect(colorPickerButton).toHaveCSS('color', RED_COLOR)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('color picker shows mixed state for differently colored selections', async ({
|
||||
test('@perf color picker shows mixed state for differently colored selections', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'color-picker-mixed-state'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
// Select first node and color it
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
await comfyPage.page.locator('.selection-toolbox .pi-circle-fill').click()
|
||||
await comfyPage.page
|
||||
.locator('.color-picker-container i[data-testid="blue"]')
|
||||
.click()
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
await perfMonitor.measureOperation('color-first-node', async () => {
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
await comfyPage.page
|
||||
.locator('.selection-toolbox .pi-circle-fill')
|
||||
.click()
|
||||
await comfyPage.page
|
||||
.locator('.color-picker-container i[data-testid="blue"]')
|
||||
.click()
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
})
|
||||
|
||||
// Select second node and color it differently
|
||||
await comfyPage.selectNodes(['CLIP Text Encode (Prompt)'])
|
||||
await comfyPage.page.locator('.selection-toolbox .pi-circle-fill').click()
|
||||
await comfyPage.page
|
||||
.locator('.color-picker-container i[data-testid="red"]')
|
||||
.click()
|
||||
await perfMonitor.measureOperation('color-second-node', async () => {
|
||||
await comfyPage.selectNodes(['CLIP Text Encode (Prompt)'])
|
||||
await comfyPage.page
|
||||
.locator('.selection-toolbox .pi-circle-fill')
|
||||
.click()
|
||||
await comfyPage.page
|
||||
.locator('.color-picker-container i[data-testid="red"]')
|
||||
.click()
|
||||
})
|
||||
|
||||
// Select both nodes
|
||||
await comfyPage.selectNodes(['KSampler', 'CLIP Text Encode (Prompt)'])
|
||||
await perfMonitor.measureOperation('select-both-nodes', async () => {
|
||||
await comfyPage.selectNodes(['KSampler', 'CLIP Text Encode (Prompt)'])
|
||||
})
|
||||
|
||||
// Color picker should show null/mixed state
|
||||
const colorPickerButton = comfyPage.page.locator(
|
||||
'.selection-toolbox .pi-circle-fill'
|
||||
)
|
||||
await expect(colorPickerButton).not.toHaveAttribute('color')
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('color picker shows correct color when selecting pre-colored node', async ({
|
||||
test('@perf color picker shows correct color when selecting pre-colored node', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'color-picker-pre-colored'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
// First color a node
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
await comfyPage.page.locator('.selection-toolbox .pi-circle-fill').click()
|
||||
await comfyPage.page
|
||||
.locator('.color-picker-container i[data-testid="blue"]')
|
||||
.click()
|
||||
await perfMonitor.measureOperation('color-node-blue', async () => {
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
await comfyPage.page
|
||||
.locator('.selection-toolbox .pi-circle-fill')
|
||||
.click()
|
||||
await comfyPage.page
|
||||
.locator('.color-picker-container i[data-testid="blue"]')
|
||||
.click()
|
||||
})
|
||||
|
||||
// Clear selection
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
await perfMonitor.measureOperation('clear-selection', async () => {
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
})
|
||||
|
||||
// Re-select the node
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
await perfMonitor.measureOperation('reselect-node', async () => {
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
})
|
||||
|
||||
// Color picker button should show the correct color
|
||||
const colorPickerButton = comfyPage.page.locator(
|
||||
'.selection-toolbox .pi-circle-fill'
|
||||
)
|
||||
await expect(colorPickerButton).toHaveCSS('color', BLUE_COLOR)
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
|
||||
test('colorization via color picker can be undone', async ({
|
||||
test('@perf colorization via color picker can be undone', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
const perfMonitor = new PerformanceMonitor(comfyPage.page)
|
||||
const testName = 'color-picker-undo'
|
||||
|
||||
await perfMonitor.startMonitoring(testName)
|
||||
|
||||
// Select a node and color it
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
await comfyPage.page.locator('.selection-toolbox .pi-circle-fill').click()
|
||||
await comfyPage.page
|
||||
.locator('.color-picker-container i[data-testid="blue"]')
|
||||
.click()
|
||||
await perfMonitor.measureOperation('color-node', async () => {
|
||||
await comfyPage.selectNodes(['KSampler'])
|
||||
await comfyPage.page
|
||||
.locator('.selection-toolbox .pi-circle-fill')
|
||||
.click()
|
||||
await comfyPage.page
|
||||
.locator('.color-picker-container i[data-testid="blue"]')
|
||||
.click()
|
||||
})
|
||||
|
||||
// Undo the colorization
|
||||
await comfyPage.page.keyboard.press('Control+Z')
|
||||
await comfyPage.nextFrame()
|
||||
await perfMonitor.measureOperation('undo-operation', async () => {
|
||||
await comfyPage.page.keyboard.press('Control+Z')
|
||||
await comfyPage.nextFrame()
|
||||
})
|
||||
|
||||
// Node should be uncolored again
|
||||
const selectedNode = (await comfyPage.getNodeRefsByTitle('KSampler'))[0]
|
||||
expect(await selectedNode.getProperty('color')).toBeUndefined()
|
||||
|
||||
await perfMonitor.finishMonitoring(testName)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user