mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 14:30:41 +00:00
fix: remove redundant and counterproductive e2e timeout overrides
- Remove ~120 redundant timeout overrides from auto-retrying assertions (toBeVisible, toBeHidden, toHaveCount, toBeEnabled, toHaveAttribute, toContainText, expect.poll) where 5000ms is already the Playwright default - Remove sub-5s timeouts (1s, 2s, 3s) from assertions that were needlessly tighter than the default, encouraging flaky failures - Raise absurdly short timeouts in customMatchers.ts (250ms toPass -> 5000ms, 256ms poll default -> removed to use 5000ms default) - Preserve timeouts on .toPass() (defaults to 0), .waitFor(), .waitForRequest(), waitForFunction(), intentionally-short assertion timeouts inside retry loops, and conditional .isVisible()/.catch() checks Amp-Thread-ID: https://ampcode.com/threads/T-019d7558-e8be-7099-b026-367fa10d97ca Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -427,24 +427,20 @@ export class AssetsSidebarTab extends SidebarTab {
|
||||
}
|
||||
// Wait for all toast elements to fully animate out and detach from DOM
|
||||
await expect(this.page.locator('.p-toast-message'))
|
||||
.toHaveCount(0, { timeout: 5000 })
|
||||
.toHaveCount(0)
|
||||
.catch(() => {})
|
||||
}
|
||||
|
||||
async switchToImported() {
|
||||
await this.dismissToasts()
|
||||
await this.importedTab.click()
|
||||
await expect(this.importedTab).toHaveAttribute('aria-selected', 'true', {
|
||||
timeout: 3000
|
||||
})
|
||||
await expect(this.importedTab).toHaveAttribute('aria-selected', 'true')
|
||||
}
|
||||
|
||||
async switchToGenerated() {
|
||||
await this.dismissToasts()
|
||||
await this.generatedTab.click()
|
||||
await expect(this.generatedTab).toHaveAttribute('aria-selected', 'true', {
|
||||
timeout: 3000
|
||||
})
|
||||
await expect(this.generatedTab).toHaveAttribute('aria-selected', 'true')
|
||||
}
|
||||
|
||||
async openSettingsMenu() {
|
||||
@@ -467,7 +463,7 @@ export class AssetsSidebarTab extends SidebarTab {
|
||||
|
||||
async waitForAssets(count?: number) {
|
||||
if (count !== undefined) {
|
||||
await expect(this.assetCards).toHaveCount(count, { timeout: 5000 })
|
||||
await expect(this.assetCards).toHaveCount(count)
|
||||
} else {
|
||||
await this.assetCards.first().waitFor({ state: 'visible', timeout: 5000 })
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ export class Topbar {
|
||||
{ timeout: 3000 }
|
||||
)
|
||||
// Wait for the dialog to close.
|
||||
await this.getSaveDialog().waitFor({ state: 'hidden', timeout: 500 })
|
||||
await this.getSaveDialog().waitFor({ state: 'hidden' })
|
||||
|
||||
// Check if a confirmation dialog appeared (e.g., "Overwrite existing file?")
|
||||
// If so, return early to let the test handle the confirmation
|
||||
|
||||
@@ -28,6 +28,6 @@ export class ToastHelper {
|
||||
}
|
||||
|
||||
// Assert all toasts are closed
|
||||
await expect(this.visibleToasts).toHaveCount(0, { timeout: 1000 })
|
||||
await expect(this.visibleToasts).toHaveCount(0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ function makeMatcher<T>(
|
||||
? expect(value, 'Node is ' + type).not
|
||||
: expect(value, 'Node is not ' + type)
|
||||
assertion.toBeTruthy()
|
||||
}).toPass({ timeout: 250, ...options })
|
||||
}).toPass({ timeout: 5000, ...options })
|
||||
return {
|
||||
pass: !this.isNot,
|
||||
message: () => 'Node is ' + (this.isNot ? 'not ' : '') + type
|
||||
@@ -30,7 +30,7 @@ export const comfyExpect = expect.extend({
|
||||
toBePinned: makeMatcher((n) => n.isPinned(), 'pinned'),
|
||||
toBeBypassed: makeMatcher((n) => n.isBypassed(), 'bypassed'),
|
||||
toBeCollapsed: makeMatcher((n) => n.isCollapsed(), 'collapsed'),
|
||||
async toHaveFocus(locator: Locator, options = { timeout: 256 }) {
|
||||
async toHaveFocus(locator: Locator, options = {}) {
|
||||
await expect
|
||||
.poll(
|
||||
() => locator.evaluate((el) => el === document.activeElement),
|
||||
|
||||
@@ -82,11 +82,9 @@ export async function builderSaveAs(
|
||||
viewType: 'App' | 'Node graph' = 'App'
|
||||
) {
|
||||
await appMode.footer.saveAsButton.click()
|
||||
await comfyExpect(appMode.saveAs.nameInput).toBeVisible({ timeout: 5000 })
|
||||
await comfyExpect(appMode.saveAs.nameInput).toBeVisible()
|
||||
await appMode.saveAs.fillAndSave(workflowName, viewType)
|
||||
await comfyExpect(appMode.saveAs.successMessage).toBeVisible({
|
||||
timeout: 5000
|
||||
})
|
||||
await comfyExpect(appMode.saveAs.successMessage).toBeVisible()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -75,9 +75,7 @@ test.describe('App mode dropdown clipping', { tag: '@ui' }, () => {
|
||||
]
|
||||
await comfyPage.appMode.enterAppModeWithInputs(inputs)
|
||||
|
||||
await expect(comfyPage.appMode.linearWidgets).toBeVisible({
|
||||
timeout: 5000
|
||||
})
|
||||
await expect(comfyPage.appMode.linearWidgets).toBeVisible()
|
||||
|
||||
// Scroll to bottom so the codec widget is at the clipping edge
|
||||
const widgetList = comfyPage.appMode.linearWidgets
|
||||
@@ -90,7 +88,7 @@ test.describe('App mode dropdown clipping', { tag: '@ui' }, () => {
|
||||
await codecSelect.click()
|
||||
|
||||
const overlay = comfyPage.page.locator('.p-select-overlay').first()
|
||||
await expect(overlay).toBeVisible({ timeout: 5000 })
|
||||
await expect(overlay).toBeVisible()
|
||||
|
||||
await expect
|
||||
.poll(() =>
|
||||
@@ -123,9 +121,7 @@ test.describe('App mode dropdown clipping', { tag: '@ui' }, () => {
|
||||
]
|
||||
await comfyPage.appMode.enterAppModeWithInputs(inputs)
|
||||
|
||||
await expect(comfyPage.appMode.linearWidgets).toBeVisible({
|
||||
timeout: 5000
|
||||
})
|
||||
await expect(comfyPage.appMode.linearWidgets).toBeVisible()
|
||||
|
||||
// Scroll to bottom so the image widget is at the clipping edge
|
||||
const widgetList = comfyPage.appMode.linearWidgets
|
||||
@@ -144,7 +140,7 @@ test.describe('App mode dropdown clipping', { tag: '@ui' }, () => {
|
||||
// The unstyled PrimeVue Popover renders with role="dialog".
|
||||
// Locate the one containing the image grid (filter buttons like "All", "Inputs").
|
||||
const popover = comfyPage.appMode.imagePickerPopover
|
||||
await expect(popover).toBeVisible({ timeout: 5000 })
|
||||
await expect(popover).toBeVisible()
|
||||
|
||||
await expect
|
||||
.poll(() =>
|
||||
|
||||
@@ -26,7 +26,7 @@ test.describe('App mode widget rename', { tag: ['@ui', '@subgraph'] }, () => {
|
||||
await appMode.steps.goToInputs()
|
||||
|
||||
const menu = appMode.select.getInputItemMenu('seed')
|
||||
await expect(menu).toBeVisible({ timeout: 5000 })
|
||||
await expect(menu).toBeVisible()
|
||||
await appMode.select.renameInputViaMenu('seed', 'Builder Input Seed')
|
||||
|
||||
// Verify in app mode after save/reload
|
||||
@@ -34,7 +34,7 @@ test.describe('App mode widget rename', { tag: ['@ui', '@subgraph'] }, () => {
|
||||
const workflowName = `${new Date().getTime()} builder-input-menu`
|
||||
await saveAndReopenInAppMode(comfyPage, workflowName)
|
||||
|
||||
await expect(appMode.linearWidgets).toBeVisible({ timeout: 5000 })
|
||||
await expect(appMode.linearWidgets).toBeVisible()
|
||||
await expect(
|
||||
appMode.linearWidgets.getByText('Builder Input Seed')
|
||||
).toBeVisible()
|
||||
@@ -54,7 +54,7 @@ test.describe('App mode widget rename', { tag: ['@ui', '@subgraph'] }, () => {
|
||||
const workflowName = `${new Date().getTime()} builder-input-dblclick`
|
||||
await saveAndReopenInAppMode(comfyPage, workflowName)
|
||||
|
||||
await expect(appMode.linearWidgets).toBeVisible({ timeout: 5000 })
|
||||
await expect(appMode.linearWidgets).toBeVisible()
|
||||
await expect(appMode.linearWidgets.getByText('Dblclick Seed')).toBeVisible()
|
||||
})
|
||||
|
||||
@@ -65,7 +65,7 @@ test.describe('App mode widget rename', { tag: ['@ui', '@subgraph'] }, () => {
|
||||
await appMode.steps.goToPreview()
|
||||
|
||||
const menu = appMode.select.getPreviewWidgetMenu('seed — New Subgraph')
|
||||
await expect(menu).toBeVisible({ timeout: 5000 })
|
||||
await expect(menu).toBeVisible()
|
||||
await appMode.select.renameWidget(menu, 'Preview Seed')
|
||||
|
||||
// Verify in app mode after save/reload
|
||||
@@ -73,7 +73,7 @@ test.describe('App mode widget rename', { tag: ['@ui', '@subgraph'] }, () => {
|
||||
const workflowName = `${new Date().getTime()} builder-preview`
|
||||
await saveAndReopenInAppMode(comfyPage, workflowName)
|
||||
|
||||
await expect(appMode.linearWidgets).toBeVisible({ timeout: 5000 })
|
||||
await expect(appMode.linearWidgets).toBeVisible()
|
||||
await expect(appMode.linearWidgets.getByText('Preview Seed')).toBeVisible()
|
||||
})
|
||||
|
||||
@@ -85,7 +85,7 @@ test.describe('App mode widget rename', { tag: ['@ui', '@subgraph'] }, () => {
|
||||
await appMode.footer.exitBuilder()
|
||||
await appMode.toggleAppMode()
|
||||
|
||||
await expect(appMode.linearWidgets).toBeVisible({ timeout: 5000 })
|
||||
await expect(appMode.linearWidgets).toBeVisible()
|
||||
|
||||
const menu = appMode.getAppModeWidgetMenu('seed')
|
||||
await appMode.select.renameWidget(menu, 'App Mode Seed')
|
||||
@@ -97,7 +97,7 @@ test.describe('App mode widget rename', { tag: ['@ui', '@subgraph'] }, () => {
|
||||
const workflowName = `${new Date().getTime()} app-mode`
|
||||
await saveAndReopenInAppMode(comfyPage, workflowName)
|
||||
|
||||
await expect(appMode.linearWidgets).toBeVisible({ timeout: 5000 })
|
||||
await expect(appMode.linearWidgets).toBeVisible()
|
||||
await expect(appMode.linearWidgets.getByText('App Mode Seed')).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -63,7 +63,7 @@ test.describe('App mode widget values in prompt', { tag: '@ui' }, () => {
|
||||
({ nodeId, widgetName }) => [nodeId, widgetName]
|
||||
)
|
||||
await appMode.enterAppModeWithInputs(inputs)
|
||||
await expect(appMode.linearWidgets).toBeVisible({ timeout: 5000 })
|
||||
await expect(appMode.linearWidgets).toBeVisible()
|
||||
|
||||
for (const { nodeId, widgetName, type, fill } of WIDGET_TEST_DATA) {
|
||||
const key = `${nodeId}:${widgetName}`
|
||||
|
||||
@@ -122,7 +122,7 @@ test.describe('Builder input reordering', { tag: '@ui' }, () => {
|
||||
const workflowName = `${Date.now()} reorder-preview`
|
||||
await saveCloseAndReopenAsApp(comfyPage, appMode, workflowName)
|
||||
|
||||
await expect(appMode.linearWidgets).toBeVisible({ timeout: 5000 })
|
||||
await expect(appMode.linearWidgets).toBeVisible()
|
||||
await expect(appMode.select.previewWidgetLabels).toHaveText([
|
||||
'steps',
|
||||
'cfg',
|
||||
@@ -147,7 +147,7 @@ test.describe('Builder input reordering', { tag: '@ui' }, () => {
|
||||
const workflowName = `${Date.now()} reorder-persist`
|
||||
await saveCloseAndReopenAsApp(comfyPage, appMode, workflowName)
|
||||
|
||||
await expect(appMode.linearWidgets).toBeVisible({ timeout: 5000 })
|
||||
await expect(appMode.linearWidgets).toBeVisible()
|
||||
await expect(appMode.select.previewWidgetLabels).toHaveText([
|
||||
'steps',
|
||||
'cfg',
|
||||
|
||||
@@ -21,7 +21,7 @@ async function reSaveAs(
|
||||
viewType: 'App' | 'Node graph'
|
||||
) {
|
||||
await appMode.footer.openSaveAsFromChevron()
|
||||
await expect(appMode.saveAs.nameInput).toBeVisible({ timeout: 5000 })
|
||||
await expect(appMode.saveAs.nameInput).toBeVisible()
|
||||
await appMode.saveAs.fillAndSave(workflowName, viewType)
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
await setupBuilder(comfyPage)
|
||||
await comfyPage.appMode.footer.saveAsButton.click()
|
||||
|
||||
await expect(saveAs.dialog).toBeVisible({ timeout: 5000 })
|
||||
await expect(saveAs.dialog).toBeVisible()
|
||||
await expect(saveAs.nameInput).toBeVisible()
|
||||
await expect(saveAs.title).toBeVisible()
|
||||
await expect(saveAs.radioGroup).toBeVisible()
|
||||
@@ -68,7 +68,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
await setupBuilder(comfyPage)
|
||||
await comfyPage.appMode.footer.saveAsButton.click()
|
||||
|
||||
await expect(saveAs.dialog).toBeVisible({ timeout: 5000 })
|
||||
await expect(saveAs.dialog).toBeVisible()
|
||||
await saveAs.nameInput.fill('')
|
||||
await expect(saveAs.saveButton).toBeDisabled()
|
||||
})
|
||||
@@ -78,7 +78,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
await setupBuilder(comfyPage)
|
||||
await comfyPage.appMode.footer.saveAsButton.click()
|
||||
|
||||
await expect(saveAs.dialog).toBeVisible({ timeout: 5000 })
|
||||
await expect(saveAs.dialog).toBeVisible()
|
||||
|
||||
const appRadio = saveAs.viewTypeRadio('App')
|
||||
await expect(appRadio).toHaveAttribute('aria-checked', 'true')
|
||||
@@ -136,12 +136,12 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
// Modify the workflow so the save button becomes enabled
|
||||
await comfyPage.appMode.steps.goToInputs()
|
||||
await comfyPage.appMode.select.deleteInput('seed')
|
||||
await expect(footer.saveButton).toBeEnabled({ timeout: 5000 })
|
||||
await expect(footer.saveButton).toBeEnabled()
|
||||
|
||||
await footer.saveButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
await expect(saveAs.dialog).not.toBeVisible({ timeout: 2000 })
|
||||
await expect(saveAs.dialog).not.toBeVisible()
|
||||
await expect(footer.saveButton).toBeDisabled()
|
||||
})
|
||||
|
||||
@@ -156,7 +156,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
|
||||
await footer.openSaveAsFromChevron()
|
||||
|
||||
await expect(saveAs.title).toBeVisible({ timeout: 5000 })
|
||||
await expect(saveAs.title).toBeVisible()
|
||||
await expect(saveAs.nameInput).toBeVisible()
|
||||
})
|
||||
|
||||
@@ -209,7 +209,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
|
||||
await expect(
|
||||
comfyPage.page.getByText('Connect an output', { exact: false })
|
||||
).toBeVisible({ timeout: 5000 })
|
||||
).toBeVisible()
|
||||
})
|
||||
|
||||
test('save as app produces correct extension and linearMode', async ({
|
||||
@@ -291,7 +291,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
|
||||
// Re-save as node graph — creates a copy
|
||||
await reSaveAs(appMode, `${Date.now()} copy`, 'Node graph')
|
||||
await expect(appMode.saveAs.successMessage).toBeVisible({ timeout: 5000 })
|
||||
await expect(appMode.saveAs.successMessage).toBeVisible()
|
||||
|
||||
await expect
|
||||
.poll(() => comfyPage.workflow.getActiveWorkflowPath())
|
||||
@@ -325,11 +325,11 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
|
||||
await reSaveAs(appMode, name, 'App')
|
||||
|
||||
await expect(appMode.saveAs.overwriteDialog).toBeVisible({ timeout: 5000 })
|
||||
await expect(appMode.saveAs.overwriteDialog).toBeVisible()
|
||||
await appMode.saveAs.overwriteButton.click()
|
||||
await expect(appMode.saveAs.overwriteDialog).not.toBeVisible()
|
||||
|
||||
await expect(appMode.saveAs.successMessage).toBeVisible({ timeout: 5000 })
|
||||
await expect(appMode.saveAs.successMessage).toBeVisible()
|
||||
|
||||
await expect
|
||||
.poll(() => comfyPage.workflow.getActiveWorkflowPath())
|
||||
@@ -351,7 +351,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
await dismissSuccessDialog(appMode.saveAs)
|
||||
|
||||
await reSaveAs(appMode, name, 'Node graph')
|
||||
await expect(appMode.saveAs.successMessage).toBeVisible({ timeout: 5000 })
|
||||
await expect(appMode.saveAs.successMessage).toBeVisible()
|
||||
|
||||
await expect
|
||||
.poll(() => comfyPage.workflow.getActiveWorkflowPath())
|
||||
|
||||
@@ -206,8 +206,8 @@ test.describe('Change Tracker', { tag: '@workflow' }, () => {
|
||||
|
||||
// Ensure undo reverts both changes
|
||||
await comfyPage.keyboard.undo()
|
||||
await expect(node).not.toBeBypassed({ timeout: 5000 })
|
||||
await expect(node).not.toBeCollapsed({ timeout: 5000 })
|
||||
await expect(node).not.toBeBypassed()
|
||||
await expect(node).not.toBeCollapsed()
|
||||
await waitForChangeTrackerSettled(comfyPage, {
|
||||
isModified: false,
|
||||
redoQueueSize: 1,
|
||||
|
||||
@@ -149,11 +149,7 @@ test.describe('Copy Paste', { tag: ['@screenshot', '@workflow'] }, () => {
|
||||
await comfyPage.canvas.click({ position: { x: 50, y: 500 } })
|
||||
await comfyPage.nextFrame()
|
||||
await comfyPage.clipboard.paste()
|
||||
await expect
|
||||
.poll(() => comfyPage.nodeOps.getGraphNodesCount(), {
|
||||
timeout: 5_000
|
||||
})
|
||||
.toBe(3)
|
||||
await expect.poll(() => comfyPage.nodeOps.getGraphNodesCount()).toBe(3)
|
||||
|
||||
// Step 2: Paste image onto selected LoadImage node
|
||||
const loadImageNodes =
|
||||
@@ -171,13 +167,10 @@ test.describe('Copy Paste', { tag: ['@screenshot', '@workflow'] }, () => {
|
||||
await uploadPromise
|
||||
|
||||
await expect
|
||||
.poll(
|
||||
async () => {
|
||||
const fileWidget = await loadImageNodes[0].getWidget(0)
|
||||
return fileWidget.getValue()
|
||||
},
|
||||
{ timeout: 5_000 }
|
||||
)
|
||||
.poll(async () => {
|
||||
const fileWidget = await loadImageNodes[0].getWidget(0)
|
||||
return fileWidget.getValue()
|
||||
})
|
||||
.toContain('image32x32')
|
||||
await expect.poll(() => comfyPage.nodeOps.getGraphNodesCount()).toBe(3)
|
||||
|
||||
@@ -194,11 +187,7 @@ test.describe('Copy Paste', { tag: ['@screenshot', '@workflow'] }, () => {
|
||||
)
|
||||
await uploadPromise2
|
||||
|
||||
await expect
|
||||
.poll(() => comfyPage.nodeOps.getGraphNodesCount(), {
|
||||
timeout: 5_000
|
||||
})
|
||||
.toBe(4)
|
||||
await expect.poll(() => comfyPage.nodeOps.getGraphNodesCount()).toBe(4)
|
||||
const allLoadImageNodes =
|
||||
await comfyPage.nodeOps.getNodeRefsByType('LoadImage')
|
||||
expect(allLoadImageNodes).toHaveLength(2)
|
||||
|
||||
@@ -250,7 +250,7 @@ test.describe('Default Keybindings', { tag: '@keyboard' }, () => {
|
||||
|
||||
// The Save As dialog should appear (p-dialog overlay)
|
||||
const dialogOverlay = comfyPage.page.locator('.p-dialog-mask')
|
||||
await expect(dialogOverlay).toBeVisible({ timeout: 3000 })
|
||||
await expect(dialogOverlay).toBeVisible()
|
||||
|
||||
// Dismiss the dialog
|
||||
await comfyPage.page.keyboard.press('Escape')
|
||||
@@ -303,9 +303,7 @@ test.describe('Default Keybindings', { tag: '@keyboard' }, () => {
|
||||
// After conversion, node count should decrease
|
||||
// (multiple nodes replaced by single subgraph node)
|
||||
await expect
|
||||
.poll(() => comfyPage.nodeOps.getGraphNodesCount(), {
|
||||
timeout: 5000
|
||||
})
|
||||
.poll(() => comfyPage.nodeOps.getGraphNodesCount())
|
||||
.toBeLessThan(initialCount)
|
||||
})
|
||||
|
||||
|
||||
@@ -112,10 +112,10 @@ test.describe('Error overlay', { tag: '@ui' }, () => {
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
await comfyPage.keyboard.undo()
|
||||
await expect(errorOverlay).not.toBeVisible({ timeout: 5000 })
|
||||
await expect(errorOverlay).not.toBeVisible()
|
||||
|
||||
await comfyPage.keyboard.redo()
|
||||
await expect(errorOverlay).not.toBeVisible({ timeout: 5000 })
|
||||
await expect(errorOverlay).not.toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -63,19 +63,13 @@ test.describe(
|
||||
|
||||
await comfyPage.command.executeCommand('Comfy.QueueSelectedOutputNodes')
|
||||
await expect
|
||||
.poll(async () => (await input.getWidget(0)).getValue(), {
|
||||
timeout: 2_000
|
||||
})
|
||||
.poll(async () => (await input.getWidget(0)).getValue())
|
||||
.toBe('foo')
|
||||
await expect
|
||||
.poll(async () => (await output1.getWidget(0)).getValue(), {
|
||||
timeout: 2_000
|
||||
})
|
||||
.poll(async () => (await output1.getWidget(0)).getValue())
|
||||
.toBe('foo')
|
||||
await expect
|
||||
.poll(async () => (await output2.getWidget(0)).getValue(), {
|
||||
timeout: 2_000
|
||||
})
|
||||
.poll(async () => (await output2.getWidget(0)).getValue())
|
||||
.toBe('')
|
||||
})
|
||||
}
|
||||
|
||||
@@ -79,9 +79,7 @@ test.describe('Keybinding Presets', { tag: '@keyboard' }, () => {
|
||||
await expect(presetTrigger).toContainText('test-preset')
|
||||
|
||||
// Wait for toast to auto-dismiss, then close settings via Escape
|
||||
await expect(comfyPage.toast.visibleToasts).toHaveCount(0, {
|
||||
timeout: 5000
|
||||
})
|
||||
await expect(comfyPage.toast.visibleToasts).toHaveCount(0)
|
||||
await page.keyboard.press('Escape')
|
||||
await comfyPage.settingDialog.waitForHidden()
|
||||
|
||||
@@ -133,9 +131,7 @@ test.describe('Keybinding Presets', { tag: '@keyboard' }, () => {
|
||||
await expect(presetTrigger).toContainText('test-preset')
|
||||
|
||||
// Wait for toast to auto-dismiss
|
||||
await expect(comfyPage.toast.visibleToasts).toHaveCount(0, {
|
||||
timeout: 5000
|
||||
})
|
||||
await expect(comfyPage.toast.visibleToasts).toHaveCount(0)
|
||||
|
||||
// Export via ellipsis menu
|
||||
await menuButton.click()
|
||||
@@ -183,9 +179,7 @@ test.describe('Keybinding Presets', { tag: '@keyboard' }, () => {
|
||||
await expect(presetTrigger).toContainText('test-preset')
|
||||
|
||||
// Wait for toast to auto-dismiss
|
||||
await expect(comfyPage.toast.visibleToasts).toHaveCount(0, {
|
||||
timeout: 5000
|
||||
})
|
||||
await expect(comfyPage.toast.visibleToasts).toHaveCount(0)
|
||||
|
||||
// Delete via ellipsis menu
|
||||
await menuButton.click()
|
||||
@@ -223,9 +217,7 @@ test.describe('Keybinding Presets', { tag: '@keyboard' }, () => {
|
||||
await expect(presetTrigger).toContainText('test-preset')
|
||||
|
||||
// Wait for toast to auto-dismiss
|
||||
await expect(comfyPage.toast.visibleToasts).toHaveCount(0, {
|
||||
timeout: 5000
|
||||
})
|
||||
await expect(comfyPage.toast.visibleToasts).toHaveCount(0)
|
||||
|
||||
// Save as new preset via ellipsis menu
|
||||
await menuButton.click()
|
||||
@@ -237,9 +229,7 @@ test.describe('Keybinding Presets', { tag: '@keyboard' }, () => {
|
||||
await promptInput.press('Enter')
|
||||
|
||||
// Wait for toast to auto-dismiss
|
||||
await expect(comfyPage.toast.visibleToasts).toHaveCount(0, {
|
||||
timeout: 5000
|
||||
})
|
||||
await expect(comfyPage.toast.visibleToasts).toHaveCount(0)
|
||||
|
||||
// Verify preset trigger shows my-custom-preset
|
||||
await expect(presetTrigger).toContainText('my-custom-preset')
|
||||
|
||||
@@ -16,7 +16,7 @@ test.describe('Linear Mode', { tag: '@ui' }, () => {
|
||||
|
||||
await expect(
|
||||
comfyPage.page.locator('[data-testid="linear-widgets"]')
|
||||
).toBeVisible({ timeout: 5000 })
|
||||
).toBeVisible()
|
||||
})
|
||||
|
||||
test('Run button visible in linear mode', async ({ comfyPage }) => {
|
||||
@@ -24,7 +24,7 @@ test.describe('Linear Mode', { tag: '@ui' }, () => {
|
||||
|
||||
await expect(
|
||||
comfyPage.page.locator('[data-testid="linear-run-button"]')
|
||||
).toBeVisible({ timeout: 5000 })
|
||||
).toBeVisible()
|
||||
})
|
||||
|
||||
test('Workflow info section visible', async ({ comfyPage }) => {
|
||||
@@ -32,7 +32,7 @@ test.describe('Linear Mode', { tag: '@ui' }, () => {
|
||||
|
||||
await expect(
|
||||
comfyPage.page.locator('[data-testid="linear-workflow-info"]')
|
||||
).toBeVisible({ timeout: 5000 })
|
||||
).toBeVisible()
|
||||
})
|
||||
|
||||
test('Returns to graph mode', async ({ comfyPage }) => {
|
||||
@@ -40,11 +40,11 @@ test.describe('Linear Mode', { tag: '@ui' }, () => {
|
||||
|
||||
await expect(
|
||||
comfyPage.page.locator('[data-testid="linear-widgets"]')
|
||||
).toBeVisible({ timeout: 5000 })
|
||||
).toBeVisible()
|
||||
|
||||
await comfyPage.appMode.toggleAppMode()
|
||||
|
||||
await expect(comfyPage.canvas).toBeVisible({ timeout: 5000 })
|
||||
await expect(comfyPage.canvas).toBeVisible()
|
||||
await expect(
|
||||
comfyPage.page.locator('[data-testid="linear-widgets"]')
|
||||
).not.toBeVisible()
|
||||
@@ -55,7 +55,7 @@ test.describe('Linear Mode', { tag: '@ui' }, () => {
|
||||
|
||||
await expect(
|
||||
comfyPage.page.locator('[data-testid="linear-widgets"]')
|
||||
).toBeVisible({ timeout: 5000 })
|
||||
).toBeVisible()
|
||||
await expect(comfyPage.canvas).not.toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -25,6 +25,6 @@ export class Load3DViewerHelper {
|
||||
}
|
||||
|
||||
async waitForClosed(): Promise<void> {
|
||||
await expect(this.dialog).toBeHidden({ timeout: 5000 })
|
||||
await expect(this.dialog).toBeHidden()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,16 +66,14 @@ test.describe('Load3D', () => {
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
await expect
|
||||
.poll(
|
||||
() =>
|
||||
comfyPage.page.evaluate(() => {
|
||||
const n = window.app!.graph.getNodeById(1)
|
||||
const config = n?.properties?.['Scene Config'] as
|
||||
| Record<string, string>
|
||||
| undefined
|
||||
return config?.backgroundColor
|
||||
}),
|
||||
{ timeout: 3000 }
|
||||
.poll(() =>
|
||||
comfyPage.page.evaluate(() => {
|
||||
const n = window.app!.graph.getNodeById(1)
|
||||
const config = n?.properties?.['Scene Config'] as
|
||||
| Record<string, string>
|
||||
| undefined
|
||||
return config?.backgroundColor
|
||||
})
|
||||
)
|
||||
.toBe('#cc3333')
|
||||
|
||||
@@ -111,9 +109,7 @@ test.describe('Load3D', () => {
|
||||
|
||||
const node = await comfyPage.nodeOps.getNodeRefById(1)
|
||||
const modelFileWidget = await node.getWidget(0)
|
||||
await expect
|
||||
.poll(() => modelFileWidget.getValue(), { timeout: 5000 })
|
||||
.toContain('cube.obj')
|
||||
await expect.poll(() => modelFileWidget.getValue()).toContain('cube.obj')
|
||||
|
||||
await load3d.waitForModelLoaded()
|
||||
await comfyPage.nextFrame()
|
||||
@@ -143,9 +139,7 @@ test.describe('Load3D', () => {
|
||||
|
||||
const node = await comfyPage.nodeOps.getNodeRefById(1)
|
||||
const modelFileWidget = await node.getWidget(0)
|
||||
await expect
|
||||
.poll(() => modelFileWidget.getValue(), { timeout: 5000 })
|
||||
.toContain('cube.obj')
|
||||
await expect.poll(() => modelFileWidget.getValue()).toContain('cube.obj')
|
||||
|
||||
await load3d.waitForModelLoaded()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -18,9 +18,7 @@ test.describe('Load3D Viewer', () => {
|
||||
|
||||
const nodeRef = await comfyPage.nodeOps.getNodeRefById(1)
|
||||
const modelFileWidget = await nodeRef.getWidget(0)
|
||||
await expect
|
||||
.poll(() => modelFileWidget.getValue(), { timeout: 5000 })
|
||||
.toContain('cube.obj')
|
||||
await expect.poll(() => modelFileWidget.getValue()).toContain('cube.obj')
|
||||
|
||||
await load3d.waitForModelLoaded()
|
||||
})
|
||||
|
||||
@@ -37,19 +37,17 @@ test.describe(
|
||||
await ksamplerNodes[0].click('title')
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
await expect(comfyPage.page.locator('.selection-toolbox')).toBeVisible({
|
||||
timeout: 5000
|
||||
})
|
||||
await expect(comfyPage.page.locator('.selection-toolbox')).toBeVisible()
|
||||
|
||||
const moreOptionsBtn = comfyPage.page.locator(
|
||||
'[data-testid="more-options-button"]'
|
||||
)
|
||||
await expect(moreOptionsBtn).toBeVisible({ timeout: 3000 })
|
||||
await expect(moreOptionsBtn).toBeVisible()
|
||||
await moreOptionsBtn.click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
const menu = comfyPage.page.locator('.p-contextmenu')
|
||||
await expect(menu).toBeVisible({ timeout: 3000 })
|
||||
await expect(menu).toBeVisible()
|
||||
|
||||
// Wait for constrainMenuHeight (runs via requestAnimationFrame in onMenuShow)
|
||||
await comfyPage.nextFrame()
|
||||
@@ -68,8 +66,7 @@ test.describe(
|
||||
() => rootList.evaluate((el) => el.scrollHeight > el.clientHeight),
|
||||
{
|
||||
message:
|
||||
'Menu should overflow vertically so this test exercises the viewport clamp',
|
||||
timeout: 3000
|
||||
'Menu should overflow vertically so this test exercises the viewport clamp'
|
||||
}
|
||||
)
|
||||
.toBe(true)
|
||||
@@ -97,9 +94,7 @@ test.describe(
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
// The node should be removed from the graph
|
||||
await expect
|
||||
.poll(() => comfyPage.nodeOps.getGraphNodesCount(), { timeout: 3000 })
|
||||
.toBe(0)
|
||||
await expect.poll(() => comfyPage.nodeOps.getGraphNodesCount()).toBe(0)
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
@@ -25,10 +25,7 @@ test.describe('Record Audio Node', { tag: '@screenshot' }, () => {
|
||||
await expect
|
||||
.poll(
|
||||
async () =>
|
||||
(await comfyPage.nodeOps.getNodeRefsByType('RecordAudio')).length,
|
||||
{
|
||||
timeout: 5000
|
||||
}
|
||||
(await comfyPage.nodeOps.getNodeRefsByType('RecordAudio')).length
|
||||
)
|
||||
.toBe(1)
|
||||
|
||||
|
||||
@@ -45,14 +45,12 @@ test.describe(
|
||||
await ksamplerNodes[0].click('title')
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
await expect(comfyPage.page.locator('.selection-toolbox')).toBeVisible({
|
||||
timeout: 5000
|
||||
})
|
||||
await expect(comfyPage.page.locator('.selection-toolbox')).toBeVisible()
|
||||
|
||||
const moreOptionsBtn = comfyPage.page.locator(
|
||||
'[data-testid="more-options-button"]'
|
||||
)
|
||||
await expect(moreOptionsBtn).toBeVisible({ timeout: 3000 })
|
||||
await expect(moreOptionsBtn).toBeVisible()
|
||||
|
||||
await comfyPage.page.click('[data-testid="more-options-button"]')
|
||||
|
||||
@@ -99,9 +97,7 @@ test.describe(
|
||||
await comfyPage.page.getByText('Shape', { exact: true }).hover()
|
||||
await expect(
|
||||
comfyPage.page.getByText('Box', { exact: true })
|
||||
).toBeVisible({
|
||||
timeout: 5000
|
||||
})
|
||||
).toBeVisible()
|
||||
await comfyPage.page.getByText('Box', { exact: true }).click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -118,7 +114,7 @@ test.describe(
|
||||
await openMoreOptions(comfyPage)
|
||||
await comfyPage.page.getByText('Color', { exact: true }).click()
|
||||
const blueSwatch = comfyPage.page.locator('[title="Blue"]')
|
||||
await expect(blueSwatch.first()).toBeVisible({ timeout: 5000 })
|
||||
await expect(blueSwatch.first()).toBeVisible()
|
||||
await blueSwatch.first().click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -152,7 +148,7 @@ test.describe(
|
||||
}) => {
|
||||
await openMoreOptions(comfyPage)
|
||||
const renameItem = comfyPage.page.getByText('Rename', { exact: true })
|
||||
await expect(renameItem).toBeVisible({ timeout: 5000 })
|
||||
await expect(renameItem).toBeVisible()
|
||||
|
||||
// Wait for multiple frames to allow PrimeVue's outside click handler to initialize
|
||||
for (let i = 0; i < 30; i++) {
|
||||
@@ -175,7 +171,7 @@ test.describe(
|
||||
await openMoreOptions(comfyPage)
|
||||
await expect(
|
||||
comfyPage.page.getByText('Rename', { exact: true })
|
||||
).toBeVisible({ timeout: 5000 })
|
||||
).toBeVisible()
|
||||
|
||||
await comfyPage.page.evaluate(() => {
|
||||
const btn = document.querySelector(
|
||||
|
||||
@@ -187,7 +187,7 @@ test.describe('Assets sidebar - grid view display', () => {
|
||||
await tab.switchToImported()
|
||||
|
||||
// Wait for imported assets to render
|
||||
await expect(tab.assetCards.first()).toBeVisible({ timeout: 5000 })
|
||||
await expect(tab.assetCards.first()).toBeVisible()
|
||||
|
||||
// Imported tab should show the mocked files
|
||||
await expect.poll(() => tab.assetCards.count()).toBeGreaterThanOrEqual(1)
|
||||
@@ -242,7 +242,7 @@ test.describe('Assets sidebar - view mode toggle', () => {
|
||||
await tab.listViewOption.click()
|
||||
|
||||
// List view items should now be visible
|
||||
await expect(tab.listViewItems.first()).toBeVisible({ timeout: 5000 })
|
||||
await expect(tab.listViewItems.first()).toBeVisible()
|
||||
})
|
||||
|
||||
test('Can switch back to grid view', async ({ comfyPage }) => {
|
||||
@@ -253,14 +253,14 @@ test.describe('Assets sidebar - view mode toggle', () => {
|
||||
// Switch to list view
|
||||
await tab.openSettingsMenu()
|
||||
await tab.listViewOption.click()
|
||||
await expect(tab.listViewItems.first()).toBeVisible({ timeout: 5000 })
|
||||
await expect(tab.listViewItems.first()).toBeVisible()
|
||||
|
||||
// Switch back to grid view (settings popover is still open)
|
||||
await tab.gridViewOption.click()
|
||||
await tab.waitForAssets()
|
||||
|
||||
// Grid cards (with data-selected attribute) should be visible again
|
||||
await expect(tab.assetCards.first()).toBeVisible({ timeout: 5000 })
|
||||
await expect(tab.assetCards.first()).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -299,9 +299,7 @@ test.describe('Assets sidebar - search', () => {
|
||||
await tab.searchInput.fill('landscape')
|
||||
|
||||
// Wait for filter to reduce the count
|
||||
await expect
|
||||
.poll(() => tab.assetCards.count(), { timeout: 5000 })
|
||||
.toBeLessThan(initialCount)
|
||||
await expect.poll(() => tab.assetCards.count()).toBeLessThan(initialCount)
|
||||
})
|
||||
|
||||
test('Clearing search restores all assets', async ({ comfyPage }) => {
|
||||
@@ -316,7 +314,7 @@ test.describe('Assets sidebar - search', () => {
|
||||
await expect.poll(() => tab.assetCards.count()).toBeLessThan(initialCount)
|
||||
|
||||
await tab.searchInput.fill('')
|
||||
await expect(tab.assetCards).toHaveCount(initialCount, { timeout: 5000 })
|
||||
await expect(tab.assetCards).toHaveCount(initialCount)
|
||||
})
|
||||
|
||||
test('Search with no matches shows empty state', async ({ comfyPage }) => {
|
||||
@@ -325,7 +323,7 @@ test.describe('Assets sidebar - search', () => {
|
||||
await tab.waitForAssets()
|
||||
|
||||
await tab.searchInput.fill('nonexistent_file_xyz')
|
||||
await expect(tab.assetCards).toHaveCount(0, { timeout: 5000 })
|
||||
await expect(tab.assetCards).toHaveCount(0)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -384,7 +382,7 @@ test.describe('Assets sidebar - selection', () => {
|
||||
await tab.assetCards.first().click()
|
||||
|
||||
// Footer should show selection count
|
||||
await expect(tab.selectionCountButton).toBeVisible({ timeout: 3000 })
|
||||
await expect(tab.selectionCountButton).toBeVisible()
|
||||
})
|
||||
|
||||
test('Deselect all clears selection', async ({ comfyPage }) => {
|
||||
@@ -398,7 +396,7 @@ test.describe('Assets sidebar - selection', () => {
|
||||
|
||||
// Hover over the selection count button to reveal "Deselect all"
|
||||
await tab.selectionCountButton.hover()
|
||||
await expect(tab.deselectAllButton).toBeVisible({ timeout: 3000 })
|
||||
await expect(tab.deselectAllButton).toBeVisible()
|
||||
|
||||
// Click "Deselect all"
|
||||
await tab.deselectAllButton.click()
|
||||
@@ -449,7 +447,7 @@ test.describe('Assets sidebar - context menu', () => {
|
||||
|
||||
// Context menu should appear with standard items
|
||||
const contextMenu = comfyPage.page.locator('.p-contextmenu')
|
||||
await expect(contextMenu).toBeVisible({ timeout: 3000 })
|
||||
await expect(contextMenu).toBeVisible()
|
||||
})
|
||||
|
||||
test('Context menu contains Download action for output asset', async ({
|
||||
@@ -522,7 +520,7 @@ test.describe('Assets sidebar - context menu', () => {
|
||||
await tab.assetCards.first().click({ button: 'right' })
|
||||
|
||||
const contextMenu = comfyPage.page.locator('.p-contextmenu')
|
||||
await expect(contextMenu).toBeVisible({ timeout: 3000 })
|
||||
await expect(contextMenu).toBeVisible()
|
||||
|
||||
await expect(
|
||||
tab.contextMenuItem('Open as workflow in new tab')
|
||||
@@ -552,8 +550,8 @@ test.describe('Assets sidebar - context menu', () => {
|
||||
await comfyPage.page.keyboard.up('Control')
|
||||
|
||||
// Verify multi-selection took effect and footer is stable before right-clicking
|
||||
await expect(tab.selectedCards).toHaveCount(2, { timeout: 3000 })
|
||||
await expect(tab.selectionFooter).toBeVisible({ timeout: 3000 })
|
||||
await expect(tab.selectedCards).toHaveCount(2)
|
||||
await expect(tab.selectionFooter).toBeVisible()
|
||||
|
||||
// Use dispatchEvent instead of click({ button: 'right' }) to avoid any
|
||||
// overlay intercepting the event, and assert directly without toPass.
|
||||
@@ -595,7 +593,7 @@ test.describe('Assets sidebar - bulk actions', () => {
|
||||
await tab.assetCards.first().click()
|
||||
|
||||
// Download button in footer should be visible
|
||||
await expect(tab.downloadSelectedButton).toBeVisible({ timeout: 3000 })
|
||||
await expect(tab.downloadSelectedButton).toBeVisible()
|
||||
})
|
||||
|
||||
test('Footer shows delete button when output assets selected', async ({
|
||||
@@ -608,7 +606,7 @@ test.describe('Assets sidebar - bulk actions', () => {
|
||||
await tab.assetCards.first().click()
|
||||
|
||||
// Delete button in footer should be visible
|
||||
await expect(tab.deleteSelectedButton).toBeVisible({ timeout: 3000 })
|
||||
await expect(tab.deleteSelectedButton).toBeVisible()
|
||||
})
|
||||
|
||||
test('Selection count displays correct number', async ({ comfyPage }) => {
|
||||
@@ -629,7 +627,7 @@ test.describe('Assets sidebar - bulk actions', () => {
|
||||
await comfyPage.page.keyboard.up('Control')
|
||||
|
||||
// Selection count should show the count
|
||||
await expect(tab.selectionCountButton).toBeVisible({ timeout: 3000 })
|
||||
await expect(tab.selectionCountButton).toBeVisible()
|
||||
await expect(tab.selectionCountButton).toHaveText(/Assets Selected:\s*2\b/)
|
||||
})
|
||||
})
|
||||
@@ -748,12 +746,10 @@ test.describe('Assets sidebar - delete confirmation', () => {
|
||||
await comfyPage.confirmDialog.delete.click()
|
||||
|
||||
await expect(dialog).not.toBeVisible()
|
||||
await expect(tab.assetCards).toHaveCount(initialCount - 1, {
|
||||
timeout: 5000
|
||||
})
|
||||
await expect(tab.assetCards).toHaveCount(initialCount - 1)
|
||||
|
||||
const successToast = comfyPage.page.locator('.p-toast-message-success')
|
||||
await expect(successToast).toBeVisible({ timeout: 5000 })
|
||||
await expect(successToast).toBeVisible()
|
||||
})
|
||||
|
||||
test('Cancelling delete preserves asset', async ({ comfyPage }) => {
|
||||
|
||||
@@ -76,9 +76,7 @@ test.describe('Model library sidebar - folders', () => {
|
||||
await tab.getFolderByLabel('checkpoints').click()
|
||||
|
||||
// Models should appear as leaf nodes
|
||||
await expect(tab.getLeafByLabel('sd_xl_base_1.0')).toBeVisible({
|
||||
timeout: 5000
|
||||
})
|
||||
await expect(tab.getLeafByLabel('sd_xl_base_1.0')).toBeVisible()
|
||||
await expect(tab.getLeafByLabel('dreamshaper_8')).toBeVisible()
|
||||
await expect(tab.getLeafByLabel('realisticVision_v51')).toBeVisible()
|
||||
})
|
||||
@@ -91,9 +89,7 @@ test.describe('Model library sidebar - folders', () => {
|
||||
|
||||
await tab.getFolderByLabel('loras').click()
|
||||
|
||||
await expect(tab.getLeafByLabel('detail_tweaker_xl')).toBeVisible({
|
||||
timeout: 5000
|
||||
})
|
||||
await expect(tab.getLeafByLabel('detail_tweaker_xl')).toBeVisible()
|
||||
await expect(tab.getLeafByLabel('add_brightness')).toBeVisible()
|
||||
})
|
||||
})
|
||||
@@ -119,9 +115,7 @@ test.describe('Model library sidebar - search', () => {
|
||||
await tab.searchInput.fill('dreamshaper')
|
||||
|
||||
// Wait for debounce (300ms) + load + render
|
||||
await expect(tab.getLeafByLabel('dreamshaper_8')).toBeVisible({
|
||||
timeout: 5000
|
||||
})
|
||||
await expect(tab.getLeafByLabel('dreamshaper_8')).toBeVisible()
|
||||
|
||||
// Other models should not be visible
|
||||
await expect(tab.getLeafByLabel('sd_xl_base_1.0')).not.toBeVisible()
|
||||
@@ -132,17 +126,13 @@ test.describe('Model library sidebar - search', () => {
|
||||
await tab.open()
|
||||
|
||||
await tab.searchInput.fill('dreamshaper')
|
||||
await expect(tab.getLeafByLabel('dreamshaper_8')).toBeVisible({
|
||||
timeout: 5000
|
||||
})
|
||||
await expect(tab.getLeafByLabel('dreamshaper_8')).toBeVisible()
|
||||
|
||||
// Clear the search
|
||||
await tab.searchInput.fill('')
|
||||
|
||||
// Folders should be visible again (collapsed)
|
||||
await expect(tab.getFolderByLabel('checkpoints')).toBeVisible({
|
||||
timeout: 5000
|
||||
})
|
||||
await expect(tab.getFolderByLabel('checkpoints')).toBeVisible()
|
||||
await expect(tab.getFolderByLabel('loras')).toBeVisible()
|
||||
})
|
||||
|
||||
@@ -152,7 +142,7 @@ test.describe('Model library sidebar - search', () => {
|
||||
|
||||
// Expand a folder and verify models are present before searching
|
||||
await tab.getFolderByLabel('checkpoints').click()
|
||||
await expect(tab.leafNodes).not.toHaveCount(0, { timeout: 5000 })
|
||||
await expect(tab.leafNodes).not.toHaveCount(0)
|
||||
|
||||
await tab.searchInput.fill('nonexistent_model_xyz')
|
||||
|
||||
@@ -196,7 +186,7 @@ test.describe('Model library sidebar - refresh', () => {
|
||||
await tab.refreshButton.click()
|
||||
await refreshRequest
|
||||
|
||||
await expect(tab.getFolderByLabel('loras')).toBeVisible({ timeout: 5000 })
|
||||
await expect(tab.getFolderByLabel('loras')).toBeVisible()
|
||||
})
|
||||
|
||||
test('Load all folders button triggers loading all model data', async ({
|
||||
|
||||
@@ -45,9 +45,7 @@ test.describe('Node library sidebar V2', () => {
|
||||
await expect(tab.getNode('KSampler (Advanced)')).not.toBeVisible()
|
||||
|
||||
await tab.searchInput.fill('KSampler')
|
||||
await expect(tab.getNode('KSampler (Advanced)')).toBeVisible({
|
||||
timeout: 5000
|
||||
})
|
||||
await expect(tab.getNode('KSampler (Advanced)')).toBeVisible()
|
||||
await expect(tab.getNode('CLIPLoader')).not.toBeVisible()
|
||||
})
|
||||
|
||||
@@ -96,7 +94,7 @@ test.describe('Node library sidebar V2', () => {
|
||||
const contextMenu = comfyPage.page.getByRole('menuitem', {
|
||||
name: /Bookmark Node/
|
||||
})
|
||||
await expect(contextMenu).toBeVisible({ timeout: 3000 })
|
||||
await expect(contextMenu).toBeVisible()
|
||||
})
|
||||
|
||||
test('Search clear restores folder view', async ({ comfyPage }) => {
|
||||
@@ -105,14 +103,12 @@ test.describe('Node library sidebar V2', () => {
|
||||
await expect(tab.getFolder('sampling')).toBeVisible()
|
||||
|
||||
await tab.searchInput.fill('KSampler')
|
||||
await expect(tab.getNode('KSampler (Advanced)')).toBeVisible({
|
||||
timeout: 5000
|
||||
})
|
||||
await expect(tab.getNode('KSampler (Advanced)')).toBeVisible()
|
||||
|
||||
await tab.searchInput.clear()
|
||||
await tab.searchInput.press('Enter')
|
||||
|
||||
await expect(tab.getFolder('sampling')).toBeVisible({ timeout: 5000 })
|
||||
await expect(tab.getFolder('sampling')).toBeVisible()
|
||||
})
|
||||
|
||||
test('Sort dropdown shows sorting options', async ({ comfyPage }) => {
|
||||
@@ -122,7 +118,7 @@ test.describe('Node library sidebar V2', () => {
|
||||
|
||||
// Reka UI DropdownMenuRadioItem renders with role="menuitemradio"
|
||||
const options = comfyPage.page.getByRole('menuitemradio')
|
||||
await expect(options.first()).toBeVisible({ timeout: 3000 })
|
||||
await expect(options.first()).toBeVisible()
|
||||
await expect.poll(() => options.count()).toBeGreaterThanOrEqual(2)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -289,9 +289,7 @@ test.describe('Workflows sidebar', () => {
|
||||
)
|
||||
await closeButton.click()
|
||||
await expect
|
||||
.poll(() => comfyPage.menu.workflowsTab.getOpenedWorkflowNames(), {
|
||||
timeout: 5000
|
||||
})
|
||||
.poll(() => comfyPage.menu.workflowsTab.getOpenedWorkflowNames())
|
||||
.toEqual(['*Unsaved Workflow'])
|
||||
})
|
||||
|
||||
@@ -370,7 +368,7 @@ test.describe('Workflows sidebar', () => {
|
||||
// Wait for workflow to appear in Browse section after sync
|
||||
const workflowItem =
|
||||
comfyPage.menu.workflowsTab.getPersistedItem('workflow1')
|
||||
await expect(workflowItem).toBeVisible({ timeout: 3000 })
|
||||
await expect(workflowItem).toBeVisible()
|
||||
|
||||
const nodeCount = await comfyPage.nodeOps.getGraphNodesCount()
|
||||
|
||||
|
||||
@@ -219,9 +219,7 @@ test.describe('Subgraph Navigation', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
await subgraphNode.navigateIntoSubgraph()
|
||||
|
||||
await expect
|
||||
.poll(() => comfyPage.page.evaluate(hasVisibleNodeInViewport), {
|
||||
timeout: 5_000
|
||||
})
|
||||
.poll(() => comfyPage.page.evaluate(hasVisibleNodeInViewport))
|
||||
.toBe(true)
|
||||
})
|
||||
|
||||
@@ -237,9 +235,7 @@ test.describe('Subgraph Navigation', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
await comfyPage.vueNodes.enterSubgraph('11')
|
||||
|
||||
await expect
|
||||
.poll(() => comfyPage.page.evaluate(hasVisibleNodeInViewport), {
|
||||
timeout: 5_000
|
||||
})
|
||||
.poll(() => comfyPage.page.evaluate(hasVisibleNodeInViewport))
|
||||
.toBe(true)
|
||||
})
|
||||
|
||||
@@ -263,13 +259,11 @@ test.describe('Subgraph Navigation', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
await comfyPage.subgraph.exitViaBreadcrumb()
|
||||
|
||||
await expect
|
||||
.poll(
|
||||
() =>
|
||||
comfyPage.page.evaluate(() => {
|
||||
const ds = window.app!.canvas.ds
|
||||
return { scale: ds.scale, offset: [...ds.offset] }
|
||||
}),
|
||||
{ timeout: 5_000 }
|
||||
.poll(() =>
|
||||
comfyPage.page.evaluate(() => {
|
||||
const ds = window.app!.canvas.ds
|
||||
return { scale: ds.scale, offset: [...ds.offset] }
|
||||
})
|
||||
)
|
||||
.toEqual({
|
||||
scale: expect.closeTo(rootViewport.scale, 2),
|
||||
@@ -314,12 +308,10 @@ test.describe('Subgraph Navigation', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
await expect
|
||||
.poll(
|
||||
() =>
|
||||
comfyPage.page.evaluate((nodeId) => {
|
||||
return window.app!.canvas.graph!.getNodeById(nodeId)!.progress
|
||||
}, subgraphNodeId),
|
||||
{ timeout: 2_000 }
|
||||
.poll(() =>
|
||||
comfyPage.page.evaluate((nodeId) => {
|
||||
return window.app!.canvas.graph!.getNodeById(nodeId)!.progress
|
||||
}, subgraphNodeId)
|
||||
)
|
||||
.toBeUndefined()
|
||||
})
|
||||
@@ -350,20 +342,18 @@ test.describe('Subgraph Navigation', { tag: ['@slow', '@subgraph'] }, () => {
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
await expect
|
||||
.poll(
|
||||
() =>
|
||||
comfyPage.page.evaluate(() => {
|
||||
const graph = window.app!.canvas.graph!
|
||||
const subgraphNode = graph.nodes.find(
|
||||
(node) =>
|
||||
typeof node.isSubgraphNode === 'function' &&
|
||||
node.isSubgraphNode()
|
||||
)
|
||||
if (!subgraphNode) return { exists: false, progress: null }
|
||||
.poll(() =>
|
||||
comfyPage.page.evaluate(() => {
|
||||
const graph = window.app!.canvas.graph!
|
||||
const subgraphNode = graph.nodes.find(
|
||||
(node) =>
|
||||
typeof node.isSubgraphNode === 'function' &&
|
||||
node.isSubgraphNode()
|
||||
)
|
||||
if (!subgraphNode) return { exists: false, progress: null }
|
||||
|
||||
return { exists: true, progress: subgraphNode.progress }
|
||||
}),
|
||||
{ timeout: 5_000 }
|
||||
return { exists: true, progress: subgraphNode.progress }
|
||||
})
|
||||
)
|
||||
.toEqual({ exists: true, progress: undefined })
|
||||
})
|
||||
|
||||
@@ -15,9 +15,7 @@ async function expectPromotedWidgetNamesToContain(
|
||||
widgetName: string
|
||||
) {
|
||||
await expect
|
||||
.poll(() => getPromotedWidgetNames(comfyPage, nodeId), {
|
||||
timeout: 5000
|
||||
})
|
||||
.poll(() => getPromotedWidgetNames(comfyPage, nodeId))
|
||||
.toContain(widgetName)
|
||||
}
|
||||
|
||||
@@ -27,9 +25,7 @@ async function expectPromotedWidgetCountToBeGreaterThan(
|
||||
count: number
|
||||
) {
|
||||
await expect
|
||||
.poll(() => getPromotedWidgetCount(comfyPage, nodeId), {
|
||||
timeout: 5000
|
||||
})
|
||||
.poll(() => getPromotedWidgetCount(comfyPage, nodeId))
|
||||
.toBeGreaterThan(count)
|
||||
}
|
||||
|
||||
@@ -288,9 +284,7 @@ test.describe(
|
||||
await comfyPage.subgraph.exitViaBreadcrumb()
|
||||
|
||||
await expect
|
||||
.poll(() => getPromotedWidgetCount(comfyPage, '2'), {
|
||||
timeout: 5000
|
||||
})
|
||||
.poll(() => getPromotedWidgetCount(comfyPage, '2'))
|
||||
.toBeLessThan(initialWidgetCount)
|
||||
})
|
||||
})
|
||||
@@ -332,7 +326,7 @@ test.describe(
|
||||
.locator('.p-contextmenu')
|
||||
.locator('text=Promote Widget')
|
||||
|
||||
await expect(promoteEntry.first()).toBeVisible({ timeout: 5000 })
|
||||
await expect(promoteEntry.first()).toBeVisible()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -536,9 +530,7 @@ test.describe(
|
||||
expectedNames.splice(removedIndex, 1)
|
||||
|
||||
await expect
|
||||
.poll(() => getPromotedWidgetNames(comfyPage, '5'), {
|
||||
timeout: 5000
|
||||
})
|
||||
.poll(() => getPromotedWidgetNames(comfyPage, '5'))
|
||||
.toEqual(expectedNames)
|
||||
})
|
||||
|
||||
@@ -553,9 +545,7 @@ test.describe(
|
||||
|
||||
let initialWidgetCount = 0
|
||||
await expect
|
||||
.poll(() => getPromotedWidgetCount(comfyPage, '11'), {
|
||||
timeout: 5000
|
||||
})
|
||||
.poll(() => getPromotedWidgetCount(comfyPage, '11'))
|
||||
.toBeGreaterThan(0)
|
||||
initialWidgetCount = await getPromotedWidgetCount(comfyPage, '11')
|
||||
|
||||
@@ -571,9 +561,7 @@ test.describe(
|
||||
|
||||
// Widget count should be reduced
|
||||
await expect
|
||||
.poll(() => getPromotedWidgetCount(comfyPage, '11'), {
|
||||
timeout: 5000
|
||||
})
|
||||
.poll(() => getPromotedWidgetCount(comfyPage, '11'))
|
||||
.toBeLessThan(initialWidgetCount)
|
||||
})
|
||||
})
|
||||
|
||||
@@ -22,13 +22,11 @@ async function openSubgraphById(comfyPage: ComfyPage, nodeId: string) {
|
||||
}, nodeId)
|
||||
|
||||
await expect
|
||||
.poll(
|
||||
() =>
|
||||
comfyPage.page.evaluate(() => {
|
||||
const graph = window.app!.canvas.graph
|
||||
return !!graph && 'inputNode' in graph
|
||||
}),
|
||||
{ timeout: 5_000 }
|
||||
.poll(() =>
|
||||
comfyPage.page.evaluate(() => {
|
||||
const graph = window.app!.canvas.graph
|
||||
return !!graph && 'inputNode' in graph
|
||||
})
|
||||
)
|
||||
.toBe(true)
|
||||
}
|
||||
@@ -149,7 +147,7 @@ test.describe('Subgraph Promotion DOM', { tag: ['@subgraph'] }, () => {
|
||||
)
|
||||
|
||||
const visibleWidgets = comfyPage.page.locator(VISIBLE_DOM_WIDGET_SELECTOR)
|
||||
await expect(visibleWidgets).toHaveCount(2, { timeout: 5_000 })
|
||||
await expect(visibleWidgets).toHaveCount(2)
|
||||
const parentCount = await visibleWidgets.count()
|
||||
|
||||
const subgraphNode = await comfyPage.nodeOps.getNodeRefById('11')
|
||||
|
||||
@@ -23,7 +23,7 @@ async function exitSubgraphAndPublish(
|
||||
name: blueprintName
|
||||
})
|
||||
|
||||
await expect(comfyPage.visibleToasts).toHaveCount(1, { timeout: 5_000 })
|
||||
await expect(comfyPage.visibleToasts).toHaveCount(1)
|
||||
await comfyPage.toast.closeToasts(1)
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ test.describe('Templates', { tag: ['@slow', '@workflow'] }, () => {
|
||||
await comfyPage.setup({ clearStorage: true })
|
||||
|
||||
// Expect the templates dialog to be shown
|
||||
await expect(comfyPage.templates.content).toBeVisible({ timeout: 5000 })
|
||||
await expect(comfyPage.templates.content).toBeVisible()
|
||||
})
|
||||
|
||||
test('Uses proper locale files for templates', async ({ comfyPage }) => {
|
||||
@@ -305,7 +305,7 @@ test.describe('Templates', { tag: ['@slow', '@workflow'] }, () => {
|
||||
comfyPage.page.locator(
|
||||
'[data-testid="template-workflow-short-description"]'
|
||||
)
|
||||
).toBeVisible({ timeout: 5000 })
|
||||
).toBeVisible()
|
||||
|
||||
// Verify all three cards with different descriptions are visible
|
||||
const shortDescCard = comfyPage.page.locator(
|
||||
@@ -399,7 +399,7 @@ test.describe('Templates', { tag: ['@slow', '@workflow'] }, () => {
|
||||
const taggedCard = comfyPage.page.getByTestId(
|
||||
TestIds.templates.workflowCard('tagged-template')
|
||||
)
|
||||
await expect(taggedCard).toBeVisible({ timeout: 5000 })
|
||||
await expect(taggedCard).toBeVisible()
|
||||
await expect(taggedCard.getByText('Relight')).toBeVisible()
|
||||
await expect(taggedCard.getByText('Image Edit')).toBeVisible()
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ test.describe('Workflow tabs', () => {
|
||||
const contextMenu = comfyPage.page.locator(
|
||||
'[role="menu"][data-state="open"]'
|
||||
)
|
||||
await expect(contextMenu).toBeVisible({ timeout: 5000 })
|
||||
await expect(contextMenu).toBeVisible()
|
||||
|
||||
await expect(
|
||||
contextMenu.getByRole('menuitem', { name: /Close Tab/i }).first()
|
||||
@@ -89,7 +89,7 @@ test.describe('Workflow tabs', () => {
|
||||
const contextMenu = comfyPage.page.locator(
|
||||
'[role="menu"][data-state="open"]'
|
||||
)
|
||||
await expect(contextMenu).toBeVisible({ timeout: 5000 })
|
||||
await expect(contextMenu).toBeVisible()
|
||||
|
||||
await contextMenu
|
||||
.getByRole('menuitem', { name: /Close Tab/i })
|
||||
@@ -123,7 +123,7 @@ test.describe('Workflow tabs', () => {
|
||||
|
||||
// WorkflowTab renders "•" when the workflow has unsaved changes
|
||||
const activeTab = topbar.getActiveTab()
|
||||
await expect(activeTab.locator('text=•')).toBeVisible({ timeout: 5000 })
|
||||
await expect(activeTab.locator('text=•')).toBeVisible()
|
||||
})
|
||||
|
||||
test('Multiple tabs can be created, switched, and closed', async ({
|
||||
|
||||
@@ -217,14 +217,12 @@ test.describe('Vue Node Context Menu', () => {
|
||||
if (!loadImageNode) throw new Error('Load Image node not found')
|
||||
|
||||
await expect
|
||||
.poll(
|
||||
() =>
|
||||
comfyPage.page.evaluate(
|
||||
(nodeId) =>
|
||||
window.app!.graph.getNodeById(nodeId)?.imgs?.length ?? 0,
|
||||
loadImageNode.id
|
||||
),
|
||||
{ timeout: 5_000 }
|
||||
.poll(() =>
|
||||
comfyPage.page.evaluate(
|
||||
(nodeId) =>
|
||||
window.app!.graph.getNodeById(nodeId)?.imgs?.length ?? 0,
|
||||
loadImageNode.id
|
||||
)
|
||||
)
|
||||
.toBeGreaterThan(0)
|
||||
})
|
||||
|
||||
@@ -102,7 +102,7 @@ test.describe('Vue Nodes - Delete Key Interaction', () => {
|
||||
|
||||
// Node count should remain the same
|
||||
await expect
|
||||
.poll(() => comfyPage.nodeOps.getGraphNodesCount(), { timeout: 1000 })
|
||||
.poll(() => comfyPage.nodeOps.getGraphNodesCount())
|
||||
.toBe(initialNodeCount)
|
||||
})
|
||||
|
||||
|
||||
@@ -132,9 +132,7 @@ test.describe('Slider widget', { tag: ['@screenshot', '@widget'] }, () => {
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('slider_widget_dragged.png')
|
||||
|
||||
await expect
|
||||
.poll(() => comfyPage.page.evaluate(() => window.widgetValue), {
|
||||
timeout: 2_000
|
||||
})
|
||||
.poll(() => comfyPage.page.evaluate(() => window.widgetValue))
|
||||
.toBeDefined()
|
||||
})
|
||||
})
|
||||
@@ -156,9 +154,7 @@ test.describe('Number widget', { tag: ['@screenshot', '@widget'] }, () => {
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('seed_widget_dragged.png')
|
||||
|
||||
await expect
|
||||
.poll(() => comfyPage.page.evaluate(() => window.widgetValue), {
|
||||
timeout: 2_000
|
||||
})
|
||||
.poll(() => comfyPage.page.evaluate(() => window.widgetValue))
|
||||
.toBeDefined()
|
||||
})
|
||||
})
|
||||
|
||||
@@ -134,11 +134,7 @@ test.describe('Workflow Persistence', () => {
|
||||
await tab.switchToWorkflow('outputs-test')
|
||||
await comfyPage.workflow.waitForWorkflowIdle()
|
||||
|
||||
await expect
|
||||
.poll(() => getNodeOutputImageCount(comfyPage, nodeId), {
|
||||
timeout: 5_000
|
||||
})
|
||||
.toBe(1)
|
||||
await expect.poll(() => getNodeOutputImageCount(comfyPage, nodeId)).toBe(1)
|
||||
})
|
||||
|
||||
test('Loading a new workflow cleanly replaces the previous graph', async ({
|
||||
@@ -191,9 +187,7 @@ test.describe('Workflow Persistence', () => {
|
||||
await comfyPage.workflow.waitForWorkflowIdle()
|
||||
|
||||
await expect
|
||||
.poll(() => getWidgetValueSnapshot(comfyPage), {
|
||||
timeout: 5_000
|
||||
})
|
||||
.poll(() => getWidgetValueSnapshot(comfyPage))
|
||||
.toEqual(widgetValuesBefore)
|
||||
})
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ test.describe('Workflow Tab Thumbnails', { tag: '@workflow' }, () => {
|
||||
|
||||
const popover = comfyPage.page.locator('.workflow-popover-fade')
|
||||
await expect(popover).toHaveCount(1)
|
||||
await expect(popover).toBeVisible({ timeout: 500 })
|
||||
await expect(popover).toBeVisible()
|
||||
if (name) {
|
||||
await expect(popover).toContainText(name)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user