mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-17 21:21:06 +00:00
Compare commits
3 Commits
test/minim
...
test/add-v
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1034b5030f | ||
|
|
d5622eef75 | ||
|
|
fb95fddf0d |
@@ -11,6 +11,7 @@ exist to make flaky-test triage faster and more repeatable.
|
||||
Before merging a flaky-test fix, confirm all of these are true:
|
||||
|
||||
- the latest CI artifact was inspected directly
|
||||
- every `.click()` is preceded by `await expect(locator).toBeVisible()`
|
||||
- the root cause is stated as a race or readiness mismatch
|
||||
- the fix waits on the real readiness boundary
|
||||
- the assertion primitive matches the job
|
||||
@@ -26,7 +27,25 @@ Before merging a flaky-test fix, confirm all of these are true:
|
||||
- Pull the newest run after each push instead of assuming the flaky set is
|
||||
unchanged.
|
||||
|
||||
## 2. Wait For The Real Readiness Boundary
|
||||
## 2. Assert Visibility Before Every Click
|
||||
|
||||
- Every `await locator.click()` must be preceded by
|
||||
`await expect(locator).toBeVisible()`.
|
||||
- This gives an immediate, descriptive failure ("expected element to be visible")
|
||||
instead of a generic actionability timeout.
|
||||
- Exceptions (do NOT add the assertion):
|
||||
- `click({ force: true })` — intentionally bypasses actionability checks.
|
||||
- Canvas / mouse coordinate clicks (`comfyPage.canvas.click(...)`,
|
||||
`page.mouse.click(x, y)`).
|
||||
- Custom click methods with string args (`node.click('title')`,
|
||||
`confirmDialog.click('save')`).
|
||||
- Clicks inside `.catch()` chains (fire-and-forget cleanup).
|
||||
- Clicks inside `expect(async () => { ... }).toPass()` retry blocks.
|
||||
- `NodeWidgetReference.click()` (canvas coordinate-based).
|
||||
- If a visibility check already exists within the preceding 3 lines
|
||||
(`toBeVisible()`, `waitFor({ state: 'visible' })`), do not duplicate it.
|
||||
|
||||
## 3. Wait For The Real Readiness Boundary
|
||||
|
||||
- Visible is not always ready.
|
||||
- If the behavior depends on internal state, wait on that state.
|
||||
@@ -42,7 +61,7 @@ Common readiness boundaries:
|
||||
- locale-triggered workflow reload finished before selecting nodes
|
||||
- real builder UI ready, not transient helper metadata
|
||||
|
||||
## 3. Choose The Smallest Correct Assertion
|
||||
## 4. Choose The Smallest Correct Assertion
|
||||
|
||||
- Use built-in retrying locator assertions when locator state is the behavior.
|
||||
- Use `expect.poll()` for a single async value.
|
||||
@@ -58,7 +77,7 @@ await expect
|
||||
.toEqual([])
|
||||
```
|
||||
|
||||
## 4. Prefer Behavioral Assertions
|
||||
## 5. Prefer Behavioral Assertions
|
||||
|
||||
- Use screenshots only when appearance is the behavior under test.
|
||||
- If a screenshot only indirectly proves behavior, replace it with a direct
|
||||
@@ -66,7 +85,7 @@ await expect
|
||||
- Prefer assertions on link counts, positions, visible menu items, persisted
|
||||
settings, and node state.
|
||||
|
||||
## 5. Keep Helper Changes Narrow
|
||||
## 6. Keep Helper Changes Narrow
|
||||
|
||||
- Shared helpers should drive setup to a stable boundary.
|
||||
- Do not encode one-spec timing assumptions into generic helpers.
|
||||
@@ -74,7 +93,7 @@ await expect
|
||||
- If a helper fails before the real test begins, remove or relax the brittle
|
||||
precondition and let downstream UI interaction prove readiness.
|
||||
|
||||
## 6. Verify Narrowly
|
||||
## 7. Verify Narrowly
|
||||
|
||||
- Prefer targeted reruns through `pnpm test:browser:local`.
|
||||
- On Windows, prefer `file:line` or whole-spec arguments over `--grep` when the
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { APIRequestContext, Locator, Page } from '@playwright/test'
|
||||
import { test as base } from '@playwright/test'
|
||||
import { expect, test as base } from '@playwright/test'
|
||||
import { config as dotenvConfig } from 'dotenv'
|
||||
|
||||
import { NodeBadgeMode } from '@/types/nodeSource'
|
||||
@@ -116,6 +116,7 @@ class ComfyMenu {
|
||||
|
||||
async toggleTheme() {
|
||||
const currentTheme = await this.getThemeId()
|
||||
await expect(this.modeToggleButton).toBeVisible()
|
||||
await this.modeToggleButton.click()
|
||||
await this.page.waitForFunction(
|
||||
(prevTheme) => {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* Vue Node Test Helpers
|
||||
*/
|
||||
import type { Locator, Page } from '@playwright/test'
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
import { TestIds } from '@e2e/fixtures/selectors'
|
||||
import { VueNodeFixture } from '@e2e/fixtures/utils/vueNodeFixtures'
|
||||
@@ -210,6 +211,7 @@ export class VueNodeHelpers {
|
||||
'subgraph-enter-button has no bounding box: element may be hidden or not in DOM'
|
||||
)
|
||||
}
|
||||
await expect(editButton).toBeVisible()
|
||||
await editButton.click({
|
||||
position: { x: box.width / 2, y: box.height * 0.75 }
|
||||
})
|
||||
|
||||
@@ -23,6 +23,9 @@ export class ComfyNodeSearchFilterSelectionPanel {
|
||||
}
|
||||
|
||||
async selectFilterValue(filterValue: string) {
|
||||
await expect(
|
||||
this.page.locator('.filter-value-select .p-select-dropdown')
|
||||
).toBeVisible()
|
||||
await this.page.locator('.filter-value-select .p-select-dropdown').click()
|
||||
await this.page
|
||||
.locator(
|
||||
@@ -34,6 +37,9 @@ export class ComfyNodeSearchFilterSelectionPanel {
|
||||
async addFilter(filterValue: string, filterType: string) {
|
||||
await this.selectFilterType(filterType)
|
||||
await this.selectFilterValue(filterValue)
|
||||
await expect(
|
||||
this.page.getByRole('button', { name: 'Add', exact: true })
|
||||
).toBeVisible()
|
||||
await this.page.getByRole('button', { name: 'Add', exact: true }).click()
|
||||
}
|
||||
}
|
||||
@@ -74,6 +80,7 @@ export class ComfyNodeSearchBox {
|
||||
}
|
||||
|
||||
async addFilter(filterValue: string, filterType: string) {
|
||||
await expect(this.filterButton).toBeVisible()
|
||||
await this.filterButton.click()
|
||||
await this.filterSelectionPanel.addFilter(filterValue, filterType)
|
||||
}
|
||||
@@ -85,6 +92,9 @@ export class ComfyNodeSearchBox {
|
||||
}
|
||||
|
||||
async removeFilter(index: number) {
|
||||
await expect(
|
||||
this.filterChips.nth(index).locator('.p-chip-remove-icon')
|
||||
).toBeVisible()
|
||||
await this.filterChips.nth(index).locator('.p-chip-remove-icon').click()
|
||||
}
|
||||
|
||||
|
||||
@@ -17,14 +17,21 @@ export class ContextMenu {
|
||||
}
|
||||
|
||||
async clickMenuItem(name: string): Promise<void> {
|
||||
await expect(this.page.getByRole('menuitem', { name })).toBeVisible()
|
||||
await this.page.getByRole('menuitem', { name }).click()
|
||||
}
|
||||
|
||||
async clickMenuItemExact(name: string): Promise<void> {
|
||||
await expect(
|
||||
this.page.getByRole('menuitem', { name, exact: true })
|
||||
).toBeVisible()
|
||||
await this.page.getByRole('menuitem', { name, exact: true }).click()
|
||||
}
|
||||
|
||||
async clickLitegraphMenuItem(name: string): Promise<void> {
|
||||
await expect(
|
||||
this.page.locator(`.litemenu-entry:has-text("${name}")`)
|
||||
).toBeVisible()
|
||||
await this.page.locator(`.litemenu-entry:has-text("${name}")`).click()
|
||||
}
|
||||
|
||||
@@ -47,6 +54,7 @@ export class ContextMenu {
|
||||
}
|
||||
|
||||
async openFor(locator: Locator): Promise<this> {
|
||||
await expect(locator).toBeVisible()
|
||||
await locator.click({ button: 'right' })
|
||||
await expect.poll(() => this.isVisible()).toBe(true)
|
||||
return this
|
||||
@@ -58,6 +66,7 @@ export class ContextMenu {
|
||||
* right-click so the correct per-node menu items appear.
|
||||
*/
|
||||
async openForVueNode(header: Locator): Promise<this> {
|
||||
await expect(header).toBeVisible()
|
||||
await header.click()
|
||||
await header.click({ button: 'right' })
|
||||
await this.primeVueMenu.waitFor({ state: 'visible' })
|
||||
|
||||
@@ -13,6 +13,7 @@ export class QueuePanel {
|
||||
}
|
||||
|
||||
async openClearHistoryDialog() {
|
||||
await expect(this.moreOptionsButton).toBeVisible()
|
||||
await this.moreOptionsButton.click()
|
||||
|
||||
const clearHistoryAction = this.page.getByTestId(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Page } from '@playwright/test'
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
import type { ComfyPage } from '@e2e/fixtures/ComfyPage'
|
||||
import { TestIds } from '@e2e/fixtures/selectors'
|
||||
@@ -33,6 +34,7 @@ export class SettingDialog extends BaseDialog {
|
||||
*/
|
||||
async toggleBooleanSetting(id: string) {
|
||||
const settingInputDiv = this.root.locator(`div[id="${id}"]`)
|
||||
await expect(settingInputDiv.locator('input')).toBeVisible()
|
||||
await settingInputDiv.locator('input').click()
|
||||
}
|
||||
|
||||
@@ -56,6 +58,7 @@ export class SettingDialog extends BaseDialog {
|
||||
const aboutButton = this.root.locator('nav').getByRole('button', {
|
||||
name: 'About'
|
||||
})
|
||||
await expect(aboutButton).toBeVisible()
|
||||
await aboutButton.click()
|
||||
await this.page.waitForSelector('.about-container')
|
||||
}
|
||||
|
||||
@@ -24,12 +24,14 @@ class SidebarTab {
|
||||
if (await this.selectedTabButton.isVisible()) {
|
||||
return
|
||||
}
|
||||
await expect(this.tabButton).toBeVisible()
|
||||
await this.tabButton.click()
|
||||
}
|
||||
async close() {
|
||||
if (!this.tabButton.isVisible()) {
|
||||
return
|
||||
}
|
||||
await expect(this.tabButton).toBeVisible()
|
||||
await this.tabButton.click()
|
||||
}
|
||||
}
|
||||
@@ -69,6 +71,7 @@ export class NodeLibrarySidebarTab extends SidebarTab {
|
||||
return
|
||||
}
|
||||
|
||||
await expect(this.tabButton).toBeVisible()
|
||||
await this.tabButton.click()
|
||||
await this.nodeLibraryTree.waitFor({ state: 'hidden' })
|
||||
}
|
||||
@@ -143,6 +146,7 @@ export class NodeLibrarySidebarTabV2 extends SidebarTab {
|
||||
const folder = this.getFolder(folderName)
|
||||
const isExpanded = await folder.getAttribute('aria-expanded')
|
||||
if (isExpanded !== 'true') {
|
||||
await expect(folder).toBeVisible()
|
||||
await folder.click()
|
||||
}
|
||||
}
|
||||
@@ -182,6 +186,7 @@ export class WorkflowsSidebarTab extends SidebarTab {
|
||||
|
||||
async switchToWorkflow(workflowName: string) {
|
||||
const workflowLocator = this.getOpenedItem(workflowName)
|
||||
await expect(workflowLocator).toBeVisible()
|
||||
await workflowLocator.click()
|
||||
}
|
||||
|
||||
@@ -198,6 +203,7 @@ export class WorkflowsSidebarTab extends SidebarTab {
|
||||
}
|
||||
|
||||
async renameWorkflow(locator: Locator, newName: string) {
|
||||
await expect(locator).toBeVisible()
|
||||
await locator.click({ button: 'right' })
|
||||
await this.page
|
||||
.locator('.p-contextmenu-item-content', { hasText: 'Rename' })
|
||||
@@ -216,6 +222,7 @@ export class WorkflowsSidebarTab extends SidebarTab {
|
||||
}
|
||||
|
||||
async insertWorkflow(locator: Locator) {
|
||||
await expect(locator).toBeVisible()
|
||||
await locator.click({ button: 'right' })
|
||||
await this.page
|
||||
.locator('.p-contextmenu-item-content', { hasText: 'Insert' })
|
||||
@@ -429,6 +436,7 @@ export class AssetsSidebarTab extends SidebarTab {
|
||||
|
||||
async switchToImported() {
|
||||
await this.dismissToasts()
|
||||
await expect(this.importedTab).toBeVisible()
|
||||
await this.importedTab.click()
|
||||
await expect(this.importedTab).toHaveAttribute('aria-selected', 'true', {
|
||||
timeout: 3000
|
||||
@@ -437,6 +445,7 @@ export class AssetsSidebarTab extends SidebarTab {
|
||||
|
||||
async switchToGenerated() {
|
||||
await this.dismissToasts()
|
||||
await expect(this.generatedTab).toBeVisible()
|
||||
await this.generatedTab.click()
|
||||
await expect(this.generatedTab).toHaveAttribute('aria-selected', 'true', {
|
||||
timeout: 3000
|
||||
@@ -445,6 +454,7 @@ export class AssetsSidebarTab extends SidebarTab {
|
||||
|
||||
async openSettingsMenu() {
|
||||
await this.dismissToasts()
|
||||
await expect(this.settingsButton).toBeVisible()
|
||||
await this.settingsButton.click()
|
||||
// Wait for popover content to render
|
||||
await this.listViewOption
|
||||
@@ -455,6 +465,7 @@ export class AssetsSidebarTab extends SidebarTab {
|
||||
|
||||
async rightClickAsset(name: string) {
|
||||
const card = this.getAssetCardByName(name)
|
||||
await expect(card).toBeVisible()
|
||||
await card.click({ button: 'right' })
|
||||
await this.page
|
||||
.locator('.p-contextmenu')
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Locator, Page } from '@playwright/test'
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
import type { WorkspaceStore } from '@e2e/types/globals'
|
||||
|
||||
@@ -128,6 +129,7 @@ export class Topbar {
|
||||
await this.menuLocator.waitFor({ state: 'hidden', timeout: 1000 })
|
||||
}
|
||||
|
||||
await expect(this.menuTrigger).toBeVisible()
|
||||
await this.menuTrigger.click()
|
||||
await this.menuLocator.waitFor({ state: 'visible' })
|
||||
return this.menuLocator
|
||||
@@ -171,6 +173,7 @@ export class Topbar {
|
||||
const { darkTheme, lightTheme } = await this.getThemeMenuItems()
|
||||
const themeItem = theme === 'dark' ? darkTheme : lightTheme
|
||||
const themeLabel = themeItem.locator('.p-menubar-item-label')
|
||||
await expect(themeLabel).toBeVisible()
|
||||
await themeLabel.click()
|
||||
}
|
||||
|
||||
@@ -189,6 +192,7 @@ export class Topbar {
|
||||
|
||||
// Handle top-level commands (like "New")
|
||||
if (path.length === 1) {
|
||||
await expect(topLevelMenuItem).toBeVisible()
|
||||
await topLevelMenuItem.click()
|
||||
return
|
||||
}
|
||||
@@ -203,6 +207,7 @@ export class Topbar {
|
||||
// Click outside to reset, then reopen menu
|
||||
await this.page.locator('body').click({ position: { x: 500, y: 300 } })
|
||||
await this.menuLocator.waitFor({ state: 'hidden', timeout: 1000 })
|
||||
await expect(this.menuTrigger).toBeVisible()
|
||||
await this.menuTrigger.click()
|
||||
await this.menuLocator.waitFor({ state: 'visible' })
|
||||
// Re-hover on top-level menu to trigger submenu
|
||||
@@ -228,6 +233,7 @@ export class Topbar {
|
||||
await menuItem.hover()
|
||||
currentMenu = menuItem
|
||||
}
|
||||
await expect(currentMenu).toBeVisible()
|
||||
await currentMenu.click()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Locator, Page } from '@playwright/test'
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
import type { ComfyPage } from '@e2e/fixtures/ComfyPage'
|
||||
import { TestIds } from '@e2e/fixtures/selectors'
|
||||
@@ -45,6 +46,9 @@ export class AppModeHelper {
|
||||
.getByRole('button', { name: 'Workflow actions' })
|
||||
.first()
|
||||
.click()
|
||||
await expect(
|
||||
this.page.getByRole('menuitem', { name: /Build app|Edit app/ })
|
||||
).toBeVisible()
|
||||
await this.page
|
||||
.getByRole('menuitem', { name: /Build app|Edit app/ })
|
||||
.click()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Locator, Page } from '@playwright/test'
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
import type { ComfyPage } from '@e2e/fixtures/ComfyPage'
|
||||
|
||||
@@ -52,6 +53,7 @@ export class AppModeWidgetHelper {
|
||||
/** Select an option from a combo/select widget. */
|
||||
async selectOption(key: string, optionName: string) {
|
||||
const widget = this.getWidgetItem(key)
|
||||
await expect(widget.getByRole('combobox')).toBeVisible()
|
||||
await widget.getByRole('combobox').click()
|
||||
await this.page
|
||||
.getByRole('option', { name: optionName, exact: true })
|
||||
@@ -84,6 +86,7 @@ export class AppModeWidgetHelper {
|
||||
)
|
||||
|
||||
const responsePromise = this.page.waitForResponse('**/api/prompt')
|
||||
await expect(this.comfyPage.appMode.runButton).toBeVisible()
|
||||
await this.comfyPage.appMode.runButton.click()
|
||||
await responsePromise
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Locator, Page } from '@playwright/test'
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
import type { ComfyPage } from '@e2e/fixtures/ComfyPage'
|
||||
import { TestIds } from '@e2e/fixtures/selectors'
|
||||
@@ -51,22 +52,29 @@ export class BuilderFooterHelper {
|
||||
}
|
||||
|
||||
async next() {
|
||||
await expect(this.nextButton).toBeVisible()
|
||||
await this.nextButton.click()
|
||||
await this.comfyPage.nextFrame()
|
||||
}
|
||||
|
||||
async back() {
|
||||
await expect(this.backButton).toBeVisible()
|
||||
await this.backButton.click()
|
||||
await this.comfyPage.nextFrame()
|
||||
}
|
||||
|
||||
async exitBuilder() {
|
||||
await expect(this.exitButton).toBeVisible()
|
||||
await this.exitButton.click()
|
||||
await this.comfyPage.nextFrame()
|
||||
}
|
||||
|
||||
async openSaveAsFromChevron() {
|
||||
await expect(this.saveAsChevron).toBeVisible()
|
||||
await this.saveAsChevron.click()
|
||||
await expect(
|
||||
this.page.getByRole('menuitem', { name: 'Save as' })
|
||||
).toBeVisible()
|
||||
await this.page.getByRole('menuitem', { name: 'Save as' }).click()
|
||||
await this.comfyPage.nextFrame()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Locator, Page } from '@playwright/test'
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
import type { ComfyPage } from '@e2e/fixtures/ComfyPage'
|
||||
|
||||
@@ -72,7 +73,9 @@ export class BuilderSaveAsHelper {
|
||||
|
||||
async fillAndSave(workflowName: string, viewType: 'App' | 'Node graph') {
|
||||
await this.nameInput.fill(workflowName)
|
||||
await expect(this.viewTypeRadio(viewType)).toBeVisible()
|
||||
await this.viewTypeRadio(viewType).click()
|
||||
await expect(this.saveButton).toBeVisible()
|
||||
await this.saveButton.click()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Locator, Page } from '@playwright/test'
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
import type { ComfyPage } from '@e2e/fixtures/ComfyPage'
|
||||
import { TestIds } from '@e2e/fixtures/selectors'
|
||||
@@ -66,7 +67,9 @@ export class BuilderSelectHelper {
|
||||
/** Delete a builder input via its actions menu. */
|
||||
async deleteInput(title: string) {
|
||||
const menu = this.getInputItemMenu(title)
|
||||
await expect(menu).toBeVisible()
|
||||
await menu.click()
|
||||
await expect(this.page.getByText('Delete', { exact: true })).toBeVisible()
|
||||
await this.page.getByText('Delete', { exact: true }).click()
|
||||
await this.comfyPage.nextFrame()
|
||||
}
|
||||
@@ -78,7 +81,9 @@ export class BuilderSelectHelper {
|
||||
*/
|
||||
async renameInputViaMenu(title: string, newName: string) {
|
||||
const menu = this.getInputItemMenu(title)
|
||||
await expect(menu).toBeVisible()
|
||||
await menu.click()
|
||||
await expect(this.page.getByText('Rename', { exact: true })).toBeVisible()
|
||||
await this.page.getByText('Rename', { exact: true }).click()
|
||||
|
||||
const input = this.page
|
||||
@@ -114,7 +119,9 @@ export class BuilderSelectHelper {
|
||||
* @param newName The new name to assign.
|
||||
*/
|
||||
async renameWidget(popoverTrigger: Locator, newName: string) {
|
||||
await expect(popoverTrigger).toBeVisible()
|
||||
await popoverTrigger.click()
|
||||
await expect(this.page.getByText('Rename', { exact: true })).toBeVisible()
|
||||
await this.page.getByText('Rename', { exact: true }).click()
|
||||
|
||||
const dialogInput = this.page.locator(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Locator, Page } from '@playwright/test'
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
import type { ComfyPage } from '@e2e/fixtures/ComfyPage'
|
||||
|
||||
@@ -14,16 +15,25 @@ export class BuilderStepsHelper {
|
||||
}
|
||||
|
||||
async goToInputs() {
|
||||
await expect(
|
||||
this.toolbar.getByRole('button', { name: 'Inputs' })
|
||||
).toBeVisible()
|
||||
await this.toolbar.getByRole('button', { name: 'Inputs' }).click()
|
||||
await this.comfyPage.nextFrame()
|
||||
}
|
||||
|
||||
async goToOutputs() {
|
||||
await expect(
|
||||
this.toolbar.getByRole('button', { name: 'Outputs' })
|
||||
).toBeVisible()
|
||||
await this.toolbar.getByRole('button', { name: 'Outputs' }).click()
|
||||
await this.comfyPage.nextFrame()
|
||||
}
|
||||
|
||||
async goToPreview() {
|
||||
await expect(
|
||||
this.toolbar.getByRole('button', { name: 'Preview' })
|
||||
).toBeVisible()
|
||||
await this.toolbar.getByRole('button', { name: 'Preview' }).click()
|
||||
await this.comfyPage.nextFrame()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Locator, Page } from '@playwright/test'
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
import { DefaultGraphPositions } from '@e2e/fixtures/constants/defaultGraphPositions'
|
||||
import type { Position } from '@e2e/fixtures/types'
|
||||
@@ -18,6 +19,7 @@ export class CanvasHelper {
|
||||
|
||||
async resetView(): Promise<void> {
|
||||
if (await this.resetViewButton.isVisible()) {
|
||||
await expect(this.resetViewButton).toBeVisible()
|
||||
await this.resetViewButton.click()
|
||||
}
|
||||
await this.page.mouse.move(10, 10)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Locator } from '@playwright/test'
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
import type { LGraph, LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import type { NodeId } from '@/platform/workflow/validation/schemas/workflowSchema'
|
||||
@@ -182,6 +183,7 @@ export class NodeOperationsHelper {
|
||||
position: DefaultGraphPositions.emptyLatentWidgetClick
|
||||
})
|
||||
const dialogInput = this.page.locator('.graphdialog input[type="text"]')
|
||||
await expect(dialogInput).toBeVisible()
|
||||
await dialogInput.click()
|
||||
await dialogInput.fill('128')
|
||||
await dialogInput.press('Enter')
|
||||
|
||||
@@ -337,6 +337,7 @@ export class SubgraphHelper {
|
||||
const breadcrumb = this.page.getByTestId(TestIds.breadcrumb.subgraph)
|
||||
const parentLink = breadcrumb.getByRole('link').first()
|
||||
if (await parentLink.isVisible()) {
|
||||
await expect(parentLink).toBeVisible()
|
||||
await parentLink.click()
|
||||
} else {
|
||||
await this.page.evaluate(() => {
|
||||
|
||||
@@ -30,6 +30,7 @@ export class ToastHelper {
|
||||
.locator('.p-toast-close-button')
|
||||
.all()
|
||||
for (const button of toastCloseButtons) {
|
||||
await expect(button).toBeVisible()
|
||||
await button.click()
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { expect } from '@playwright/test'
|
||||
import { readFileSync } from 'fs'
|
||||
|
||||
import type { AppMode } from '@/composables/useAppMode'
|
||||
@@ -90,9 +91,11 @@ export class WorkflowHelper {
|
||||
}
|
||||
|
||||
// Delete workflow
|
||||
await expect(workflowsTab.getPersistedItem(workflowName)).toBeVisible()
|
||||
await workflowsTab.getPersistedItem(workflowName).click({ button: 'right' })
|
||||
await this.comfyPage.contextMenu.clickMenuItem('Delete')
|
||||
await this.comfyPage.nextFrame()
|
||||
await expect(this.comfyPage.confirmDialog.delete).toBeVisible()
|
||||
await this.comfyPage.confirmDialog.delete.click()
|
||||
|
||||
// Clear toast & close tab
|
||||
|
||||
@@ -431,6 +431,7 @@ export class NodeReference {
|
||||
async clickContextMenuOption(optionText: string) {
|
||||
await this.click('title', { button: 'right' })
|
||||
const ctx = this.comfyPage.page.locator('.litecontextmenu')
|
||||
await expect(ctx.getByText(optionText)).toBeVisible()
|
||||
await ctx.getByText(optionText).click()
|
||||
}
|
||||
async convertToGroupNode(groupNodeName: string = 'GroupNode') {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Locator } from '@playwright/test'
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
import { TestIds } from '@e2e/fixtures/selectors'
|
||||
|
||||
@@ -58,6 +59,7 @@ export class VueNodeFixture {
|
||||
}
|
||||
|
||||
async toggleCollapse(): Promise<void> {
|
||||
await expect(this.collapseButton).toBeVisible()
|
||||
await this.collapseButton.click()
|
||||
}
|
||||
|
||||
|
||||
@@ -87,6 +87,7 @@ test.describe('App mode dropdown clipping', { tag: '@ui' }, () => {
|
||||
|
||||
// Click the codec select (combobox role with aria-label from WidgetSelectDefault)
|
||||
const codecSelect = widgetList.getByRole('combobox', { name: 'codec' })
|
||||
await expect(codecSelect).toBeVisible()
|
||||
await codecSelect.click()
|
||||
|
||||
const overlay = comfyPage.page.locator('.p-select-overlay').first()
|
||||
@@ -135,6 +136,7 @@ test.describe('App mode dropdown clipping', { tag: '@ui' }, () => {
|
||||
'div:has(> div > span:text-is("image"))'
|
||||
)
|
||||
const dropdownButton = imageRow.locator('button:has(> span)').first()
|
||||
await expect(dropdownButton).toBeVisible()
|
||||
await dropdownButton.click()
|
||||
|
||||
// The unstyled PrimeVue Popover renders with role="dialog".
|
||||
|
||||
@@ -25,6 +25,7 @@ test.describe('Background Image Upload', () => {
|
||||
|
||||
// Navigate to Appearance category
|
||||
const appearanceOption = comfyPage.page.locator('text=Appearance')
|
||||
await expect(appearanceOption).toBeVisible()
|
||||
await appearanceOption.click()
|
||||
|
||||
// Find the background image setting
|
||||
@@ -58,6 +59,7 @@ test.describe('Background Image Upload', () => {
|
||||
|
||||
// Navigate to Appearance category
|
||||
const appearanceOption = comfyPage.page.locator('text=Appearance')
|
||||
await expect(appearanceOption).toBeVisible()
|
||||
await appearanceOption.click()
|
||||
|
||||
// Find the background image setting
|
||||
@@ -71,6 +73,7 @@ test.describe('Background Image Upload', () => {
|
||||
|
||||
// Set up file upload handler
|
||||
const fileChooserPromise = comfyPage.page.waitForEvent('filechooser')
|
||||
await expect(uploadButton).toBeVisible()
|
||||
await uploadButton.click()
|
||||
const fileChooser = await fileChooserPromise
|
||||
|
||||
@@ -104,6 +107,7 @@ test.describe('Background Image Upload', () => {
|
||||
|
||||
// Navigate to Appearance category
|
||||
const appearanceOption = comfyPage.page.locator('text=Appearance')
|
||||
await expect(appearanceOption).toBeVisible()
|
||||
await appearanceOption.click()
|
||||
|
||||
// Find the background image setting
|
||||
@@ -146,6 +150,7 @@ test.describe('Background Image Upload', () => {
|
||||
|
||||
// Navigate to Appearance category
|
||||
const appearanceOption = comfyPage.page.locator('text=Appearance')
|
||||
await expect(appearanceOption).toBeVisible()
|
||||
await appearanceOption.click()
|
||||
|
||||
// Find the background image setting
|
||||
@@ -163,6 +168,7 @@ test.describe('Background Image Upload', () => {
|
||||
await expect(clearButton).toBeEnabled()
|
||||
|
||||
// Click the clear button
|
||||
await expect(clearButton).toBeVisible()
|
||||
await clearButton.click()
|
||||
|
||||
// Verify the input is now empty
|
||||
@@ -186,6 +192,7 @@ test.describe('Background Image Upload', () => {
|
||||
|
||||
// Navigate to Appearance category
|
||||
const appearanceOption = comfyPage.page.locator('text=Appearance')
|
||||
await expect(appearanceOption).toBeVisible()
|
||||
await appearanceOption.click()
|
||||
|
||||
// Find the background image setting
|
||||
@@ -227,6 +234,7 @@ test.describe('Background Image Upload', () => {
|
||||
|
||||
// Navigate to Appearance category
|
||||
const appearanceOption = comfyPage.page.locator('text=Appearance')
|
||||
await expect(appearanceOption).toBeVisible()
|
||||
await appearanceOption.click()
|
||||
|
||||
// Find the background image setting
|
||||
@@ -254,6 +262,7 @@ test.describe('Background Image Upload', () => {
|
||||
await expect(clearButton).toBeEnabled()
|
||||
|
||||
// Use clear button - should clear input and disable itself
|
||||
await expect(clearButton).toBeVisible()
|
||||
await clearButton.click()
|
||||
await expect(urlInput).toHaveValue('')
|
||||
await expect(clearButton).toBeDisabled()
|
||||
|
||||
@@ -12,6 +12,7 @@ test.describe('Bottom Panel Logs', { tag: '@ui' }, () => {
|
||||
const { bottomPanel } = comfyPage
|
||||
|
||||
await expect(bottomPanel.root).not.toBeVisible()
|
||||
await expect(bottomPanel.toggleButton).toBeVisible()
|
||||
await bottomPanel.toggleButton.click()
|
||||
await expect(bottomPanel.root).toBeVisible()
|
||||
})
|
||||
@@ -21,6 +22,7 @@ test.describe('Bottom Panel Logs', { tag: '@ui' }, () => {
|
||||
}) => {
|
||||
const { bottomPanel } = comfyPage
|
||||
|
||||
await expect(bottomPanel.toggleButton).toBeVisible()
|
||||
await bottomPanel.toggleButton.click()
|
||||
await expect(bottomPanel.root).toBeVisible()
|
||||
|
||||
@@ -31,6 +33,7 @@ test.describe('Bottom Panel Logs', { tag: '@ui' }, () => {
|
||||
test('should close bottom panel via toggle button', async ({ comfyPage }) => {
|
||||
const { bottomPanel } = comfyPage
|
||||
|
||||
await expect(bottomPanel.toggleButton).toBeVisible()
|
||||
await bottomPanel.toggleButton.click()
|
||||
await expect(bottomPanel.root).toBeVisible()
|
||||
|
||||
@@ -43,12 +46,14 @@ test.describe('Bottom Panel Logs', { tag: '@ui' }, () => {
|
||||
}) => {
|
||||
const { bottomPanel } = comfyPage
|
||||
|
||||
await expect(bottomPanel.keyboardShortcutsButton).toBeVisible()
|
||||
await bottomPanel.keyboardShortcutsButton.click()
|
||||
await expect(bottomPanel.root).toBeVisible()
|
||||
await expect(
|
||||
comfyPage.page.locator('[id*="tab_shortcuts-essentials"]')
|
||||
).toBeVisible()
|
||||
|
||||
await expect(bottomPanel.toggleButton).toBeVisible()
|
||||
await bottomPanel.toggleButton.click()
|
||||
|
||||
const logsTab = comfyPage.page.getByRole('tab', { name: /Logs/i })
|
||||
@@ -63,6 +68,7 @@ test.describe('Bottom Panel Logs', { tag: '@ui' }, () => {
|
||||
}) => {
|
||||
const { bottomPanel } = comfyPage
|
||||
|
||||
await expect(bottomPanel.toggleButton).toBeVisible()
|
||||
await bottomPanel.toggleButton.click()
|
||||
await expect(bottomPanel.root).toBeVisible()
|
||||
|
||||
@@ -84,6 +90,7 @@ test.describe('Bottom Panel Logs', { tag: '@ui' }, () => {
|
||||
}) => {
|
||||
const { bottomPanel } = comfyPage
|
||||
|
||||
await expect(bottomPanel.toggleButton).toBeVisible()
|
||||
await bottomPanel.toggleButton.click()
|
||||
await expect(bottomPanel.root).toBeVisible()
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ test.describe('Bottom Panel Shortcuts', { tag: '@ui' }, () => {
|
||||
const { bottomPanel } = comfyPage
|
||||
|
||||
await expect(bottomPanel.root).not.toBeVisible()
|
||||
await expect(bottomPanel.keyboardShortcutsButton).toBeVisible()
|
||||
await bottomPanel.keyboardShortcutsButton.click()
|
||||
await expect(bottomPanel.root).toBeVisible()
|
||||
await bottomPanel.keyboardShortcutsButton.click()
|
||||
@@ -20,6 +21,7 @@ test.describe('Bottom Panel Shortcuts', { tag: '@ui' }, () => {
|
||||
test('should display essentials shortcuts tab', async ({ comfyPage }) => {
|
||||
const { bottomPanel } = comfyPage
|
||||
|
||||
await expect(bottomPanel.keyboardShortcutsButton).toBeVisible()
|
||||
await bottomPanel.keyboardShortcutsButton.click()
|
||||
|
||||
await expect(bottomPanel.shortcuts.essentialsTab).toBeVisible()
|
||||
@@ -45,7 +47,9 @@ test.describe('Bottom Panel Shortcuts', { tag: '@ui' }, () => {
|
||||
test('should display view controls shortcuts tab', async ({ comfyPage }) => {
|
||||
const { bottomPanel } = comfyPage
|
||||
|
||||
await expect(bottomPanel.keyboardShortcutsButton).toBeVisible()
|
||||
await bottomPanel.keyboardShortcutsButton.click()
|
||||
await expect(bottomPanel.shortcuts.viewControlsTab).toBeVisible()
|
||||
await bottomPanel.shortcuts.viewControlsTab.click()
|
||||
|
||||
await expect(bottomPanel.shortcuts.viewControlsTab).toHaveAttribute(
|
||||
@@ -66,6 +70,7 @@ test.describe('Bottom Panel Shortcuts', { tag: '@ui' }, () => {
|
||||
test('should switch between shortcuts tabs', async ({ comfyPage }) => {
|
||||
const { bottomPanel } = comfyPage
|
||||
|
||||
await expect(bottomPanel.keyboardShortcutsButton).toBeVisible()
|
||||
await bottomPanel.keyboardShortcutsButton.click()
|
||||
|
||||
await expect(bottomPanel.shortcuts.essentialsTab).toHaveAttribute(
|
||||
@@ -73,6 +78,7 @@ test.describe('Bottom Panel Shortcuts', { tag: '@ui' }, () => {
|
||||
'true'
|
||||
)
|
||||
|
||||
await expect(bottomPanel.shortcuts.viewControlsTab).toBeVisible()
|
||||
await bottomPanel.shortcuts.viewControlsTab.click()
|
||||
|
||||
await expect(bottomPanel.shortcuts.viewControlsTab).toHaveAttribute(
|
||||
@@ -84,6 +90,7 @@ test.describe('Bottom Panel Shortcuts', { tag: '@ui' }, () => {
|
||||
'true'
|
||||
)
|
||||
|
||||
await expect(bottomPanel.shortcuts.essentialsTab).toBeVisible()
|
||||
await bottomPanel.shortcuts.essentialsTab.click()
|
||||
|
||||
await expect(bottomPanel.shortcuts.essentialsTab).toHaveAttribute(
|
||||
@@ -99,6 +106,7 @@ test.describe('Bottom Panel Shortcuts', { tag: '@ui' }, () => {
|
||||
test('should display formatted keyboard shortcuts', async ({ comfyPage }) => {
|
||||
const { bottomPanel } = comfyPage
|
||||
|
||||
await expect(bottomPanel.keyboardShortcutsButton).toBeVisible()
|
||||
await bottomPanel.keyboardShortcutsButton.click()
|
||||
|
||||
const keyBadges = bottomPanel.shortcuts.keyBadges
|
||||
@@ -119,6 +127,7 @@ test.describe('Bottom Panel Shortcuts', { tag: '@ui' }, () => {
|
||||
const { bottomPanel } = comfyPage
|
||||
|
||||
// Open shortcuts panel first
|
||||
await expect(bottomPanel.keyboardShortcutsButton).toBeVisible()
|
||||
await bottomPanel.keyboardShortcutsButton.click()
|
||||
await expect(bottomPanel.root).toBeVisible()
|
||||
await expect(
|
||||
@@ -127,6 +136,7 @@ test.describe('Bottom Panel Shortcuts', { tag: '@ui' }, () => {
|
||||
|
||||
// Try to open terminal panel - may show terminal OR close shortcuts
|
||||
// depending on whether terminal tabs have loaded (async loading)
|
||||
await expect(bottomPanel.toggleButton).toBeVisible()
|
||||
await bottomPanel.toggleButton.click()
|
||||
|
||||
// Check if terminal tabs loaded (Logs tab visible) or fell back to shortcuts toggle
|
||||
@@ -138,6 +148,7 @@ test.describe('Bottom Panel Shortcuts', { tag: '@ui' }, () => {
|
||||
await expect(bottomPanel.root).toBeVisible()
|
||||
|
||||
// Switch back to shortcuts
|
||||
await expect(bottomPanel.keyboardShortcutsButton).toBeVisible()
|
||||
await bottomPanel.keyboardShortcutsButton.click()
|
||||
|
||||
// Should show shortcuts content again
|
||||
@@ -146,6 +157,7 @@ test.describe('Bottom Panel Shortcuts', { tag: '@ui' }, () => {
|
||||
).toBeVisible()
|
||||
} else {
|
||||
// Terminal tabs not loaded - button toggled shortcuts off, reopen for verification
|
||||
await expect(bottomPanel.keyboardShortcutsButton).toBeVisible()
|
||||
await bottomPanel.keyboardShortcutsButton.click()
|
||||
await expect(bottomPanel.root).toBeVisible()
|
||||
await expect(
|
||||
@@ -157,6 +169,7 @@ test.describe('Bottom Panel Shortcuts', { tag: '@ui' }, () => {
|
||||
test('should handle keyboard navigation', async ({ comfyPage }) => {
|
||||
const { bottomPanel } = comfyPage
|
||||
|
||||
await expect(bottomPanel.keyboardShortcutsButton).toBeVisible()
|
||||
await bottomPanel.keyboardShortcutsButton.click()
|
||||
await bottomPanel.shortcuts.essentialsTab.focus()
|
||||
|
||||
@@ -177,6 +190,7 @@ test.describe('Bottom Panel Shortcuts', { tag: '@ui' }, () => {
|
||||
}) => {
|
||||
const { bottomPanel } = comfyPage
|
||||
|
||||
await expect(bottomPanel.keyboardShortcutsButton).toBeVisible()
|
||||
await bottomPanel.keyboardShortcutsButton.click()
|
||||
await expect(bottomPanel.root).toBeVisible()
|
||||
|
||||
@@ -189,6 +203,7 @@ test.describe('Bottom Panel Shortcuts', { tag: '@ui' }, () => {
|
||||
}) => {
|
||||
const { bottomPanel } = comfyPage
|
||||
|
||||
await expect(bottomPanel.keyboardShortcutsButton).toBeVisible()
|
||||
await bottomPanel.keyboardShortcutsButton.click()
|
||||
|
||||
await expect(
|
||||
@@ -221,6 +236,7 @@ test.describe('Bottom Panel Shortcuts', { tag: '@ui' }, () => {
|
||||
}) => {
|
||||
const { bottomPanel } = comfyPage
|
||||
|
||||
await expect(bottomPanel.keyboardShortcutsButton).toBeVisible()
|
||||
await bottomPanel.keyboardShortcutsButton.click()
|
||||
|
||||
await expect(bottomPanel.shortcuts.manageButton).toBeVisible()
|
||||
|
||||
@@ -20,6 +20,7 @@ async function saveCloseAndReopenAsApp(
|
||||
) {
|
||||
await appMode.steps.goToPreview()
|
||||
await builderSaveAs(appMode, workflowName)
|
||||
await expect(appMode.saveAs.closeButton).toBeVisible()
|
||||
await appMode.saveAs.closeButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
test('Save as dialog appears for unsaved workflow', async ({ comfyPage }) => {
|
||||
const { saveAs } = comfyPage.appMode
|
||||
await setupBuilder(comfyPage)
|
||||
await expect(comfyPage.appMode.footer.saveAsButton).toBeVisible()
|
||||
await comfyPage.appMode.footer.saveAsButton.click()
|
||||
|
||||
await expect(saveAs.dialog).toBeVisible({ timeout: 5000 })
|
||||
@@ -56,6 +57,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
}) => {
|
||||
const { saveAs } = comfyPage.appMode
|
||||
await setupBuilder(comfyPage)
|
||||
await expect(comfyPage.appMode.footer.saveAsButton).toBeVisible()
|
||||
await comfyPage.appMode.footer.saveAsButton.click()
|
||||
|
||||
await expect(saveAs.dialog).toBeVisible({ timeout: 5000 })
|
||||
@@ -66,6 +68,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
test('View type can be toggled in save-as dialog', async ({ comfyPage }) => {
|
||||
const { saveAs } = comfyPage.appMode
|
||||
await setupBuilder(comfyPage)
|
||||
await expect(comfyPage.appMode.footer.saveAsButton).toBeVisible()
|
||||
await comfyPage.appMode.footer.saveAsButton.click()
|
||||
|
||||
await expect(saveAs.dialog).toBeVisible({ timeout: 5000 })
|
||||
@@ -74,6 +77,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
await expect(appRadio).toHaveAttribute('aria-checked', 'true')
|
||||
|
||||
const graphRadio = saveAs.viewTypeRadio('Node graph')
|
||||
await expect(graphRadio).toBeVisible()
|
||||
await graphRadio.click()
|
||||
await expect(graphRadio).toHaveAttribute('aria-checked', 'true')
|
||||
await expect(appRadio).toHaveAttribute('aria-checked', 'false')
|
||||
@@ -121,6 +125,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
await setupBuilder(comfyPage)
|
||||
|
||||
await builderSaveAs(comfyPage.appMode, `${Date.now()} direct-save`, 'App')
|
||||
await expect(saveAs.closeButton).toBeVisible()
|
||||
await saveAs.closeButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -129,6 +134,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
await comfyPage.appMode.select.deleteInput('seed')
|
||||
await expect(footer.saveButton).toBeEnabled({ timeout: 5000 })
|
||||
|
||||
await expect(footer.saveButton).toBeVisible()
|
||||
await footer.saveButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -143,6 +149,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
await setupBuilder(comfyPage)
|
||||
|
||||
await builderSaveAs(comfyPage.appMode, `${Date.now()} split-btn`, 'App')
|
||||
await expect(saveAs.closeButton).toBeVisible()
|
||||
await saveAs.closeButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -177,6 +184,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
|
||||
// Save the workflow to transition to the Save + chevron state
|
||||
await builderSaveAs(appMode, `${Date.now()} width-test`, 'App')
|
||||
await expect(appMode.saveAs.closeButton).toBeVisible()
|
||||
await appMode.saveAs.closeButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -193,6 +201,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
await fitToViewInstant(comfyPage)
|
||||
await comfyPage.appMode.enterBuilder()
|
||||
|
||||
await expect(comfyPage.appMode.footer.saveAsButton).toBeVisible()
|
||||
await comfyPage.appMode.footer.saveAsButton.click()
|
||||
|
||||
await expect(
|
||||
@@ -235,6 +244,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
await setupBuilder(comfyPage)
|
||||
await builderSaveAs(comfyPage.appMode, `${Date.now()} app-view`, 'App')
|
||||
|
||||
await expect(comfyPage.appMode.saveAs.viewAppButton).toBeVisible()
|
||||
await comfyPage.appMode.saveAs.viewAppButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -253,6 +263,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
'Node graph'
|
||||
)
|
||||
|
||||
await expect(comfyPage.appMode.saveAs.exitBuilderButton).toBeVisible()
|
||||
await comfyPage.appMode.saveAs.exitBuilderButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -269,6 +280,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
await builderSaveAs(appMode, originalName, 'App')
|
||||
const originalPath = await comfyPage.workflow.getActiveWorkflowPath()
|
||||
expect(originalPath).toContain('.app.json')
|
||||
await expect(appMode.saveAs.closeButton).toBeVisible()
|
||||
await appMode.saveAs.closeButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -281,6 +293,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
expect(newPath).not.toContain('.app.json')
|
||||
|
||||
// Dismiss success dialog, exit app mode, reopen the original
|
||||
await expect(appMode.saveAs.dismissButton).toBeVisible()
|
||||
await appMode.saveAs.dismissButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
await appMode.toggleAppMode()
|
||||
@@ -298,6 +311,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
await setupBuilder(comfyPage)
|
||||
|
||||
await builderSaveAs(appMode, name, 'App')
|
||||
await expect(appMode.saveAs.closeButton).toBeVisible()
|
||||
await appMode.saveAs.closeButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -306,6 +320,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
await reSaveAs(appMode, name, 'App')
|
||||
|
||||
await expect(appMode.saveAs.overwriteDialog).toBeVisible({ timeout: 5000 })
|
||||
await expect(appMode.saveAs.overwriteButton).toBeVisible()
|
||||
await appMode.saveAs.overwriteButton.click()
|
||||
|
||||
await expect(appMode.saveAs.successMessage).toBeVisible({ timeout: 5000 })
|
||||
@@ -324,6 +339,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
await builderSaveAs(appMode, name, 'App')
|
||||
const pathAfterFirst = await comfyPage.workflow.getActiveWorkflowPath()
|
||||
expect(pathAfterFirst).toContain('.app.json')
|
||||
await expect(appMode.saveAs.closeButton).toBeVisible()
|
||||
await appMode.saveAs.closeButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -340,6 +356,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
const name = `${Date.now()} reload-app`
|
||||
await setupBuilder(comfyPage)
|
||||
await builderSaveAs(comfyPage.appMode, name, 'App')
|
||||
await expect(comfyPage.appMode.saveAs.dismissButton).toBeVisible()
|
||||
await comfyPage.appMode.saveAs.dismissButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
await comfyPage.appMode.footer.exitBuilder()
|
||||
@@ -356,6 +373,7 @@ test.describe('Builder save flow', { tag: ['@ui'] }, () => {
|
||||
const name = `${Date.now()} reload-graph`
|
||||
await setupBuilder(comfyPage)
|
||||
await builderSaveAs(comfyPage.appMode, name, 'Node graph')
|
||||
await expect(comfyPage.appMode.saveAs.dismissButton).toBeVisible()
|
||||
await comfyPage.appMode.saveAs.dismissButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
await comfyPage.appMode.toggleAppMode()
|
||||
|
||||
@@ -47,17 +47,20 @@ test.describe(
|
||||
|
||||
// Switch back to tab 0 (workflow-a).
|
||||
const tab0 = comfyPage.menu.topbar.getWorkflowTab('workflow-a')
|
||||
await expect(tab0).toBeVisible()
|
||||
await tab0.click()
|
||||
await comfyPage.nextFrame()
|
||||
expect(await comfyPage.nodeOps.getGraphNodesCount()).toBe(7)
|
||||
|
||||
// switch to blank tab and back to verify no corruption
|
||||
const tab1 = comfyPage.menu.topbar.getWorkflowTab('Unsaved Workflow')
|
||||
await expect(tab1).toBeVisible()
|
||||
await tab1.click()
|
||||
await comfyPage.nextFrame()
|
||||
expect(await comfyPage.nodeOps.getGraphNodesCount()).toBe(0)
|
||||
|
||||
// switch again and verify no corruption
|
||||
await expect(tab0).toBeVisible()
|
||||
await tab0.click()
|
||||
await comfyPage.nextFrame()
|
||||
expect(await comfyPage.nodeOps.getGraphNodesCount()).toBe(7)
|
||||
|
||||
@@ -32,6 +32,7 @@ test.describe('Copy Paste', { tag: ['@screenshot', '@workflow'] }, () => {
|
||||
|
||||
test('Can copy and paste text', async ({ comfyPage }) => {
|
||||
const textBox = comfyPage.widgetTextBox
|
||||
await expect(textBox).toBeVisible()
|
||||
await textBox.click()
|
||||
const originalString = await textBox.inputValue()
|
||||
await textBox.selectText()
|
||||
@@ -78,6 +79,7 @@ test.describe('Copy Paste', { tag: ['@screenshot', '@workflow'] }, () => {
|
||||
await comfyPage.nextFrame()
|
||||
await comfyPage.clipboard.copy(null)
|
||||
const textBox = comfyPage.widgetTextBox
|
||||
await expect(textBox).toBeVisible()
|
||||
await textBox.click()
|
||||
await textBox.inputValue()
|
||||
await textBox.selectText()
|
||||
@@ -91,6 +93,7 @@ test.describe('Copy Paste', { tag: ['@screenshot', '@workflow'] }, () => {
|
||||
|
||||
test('Copy text area does not copy node', async ({ comfyPage }) => {
|
||||
const textBox = comfyPage.widgetTextBox
|
||||
await expect(textBox).toBeVisible()
|
||||
await textBox.click()
|
||||
await textBox.inputValue()
|
||||
await textBox.selectText()
|
||||
|
||||
@@ -65,12 +65,14 @@ test.describe('Settings', () => {
|
||||
const newBlankWorkflowRow = comfyPage.page.locator('tr', {
|
||||
has: comfyPage.page.getByRole('cell', { name: 'New Blank Workflow' })
|
||||
})
|
||||
await expect(newBlankWorkflowRow).toBeVisible()
|
||||
await newBlankWorkflowRow.click()
|
||||
|
||||
// Click add keybinding button (New Blank Workflow has no default keybinding)
|
||||
const addKeybindingButton = newBlankWorkflowRow.locator(
|
||||
'.icon-\\[lucide--plus\\]'
|
||||
)
|
||||
await expect(addKeybindingButton).toBeVisible()
|
||||
await addKeybindingButton.click()
|
||||
|
||||
// Set new keybinding
|
||||
@@ -88,6 +90,7 @@ test.describe('Settings', () => {
|
||||
const saveButton = comfyPage.page
|
||||
.getByLabel('Modify keybinding')
|
||||
.getByText('Save')
|
||||
await expect(saveButton).toBeVisible()
|
||||
await saveButton.click()
|
||||
|
||||
const request = await requestPromise
|
||||
@@ -142,6 +145,7 @@ test.describe('Signin dialog', () => {
|
||||
await comfyPage.clipboard.copy()
|
||||
|
||||
const textBox = comfyPage.widgetTextBox
|
||||
await expect(textBox).toBeVisible()
|
||||
await textBox.click()
|
||||
await textBox.fill('test_password')
|
||||
await textBox.press('Control+a')
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
test.describe('Queue Clear History Dialog', { tag: '@ui' }, () => {
|
||||
test.beforeEach(async ({ comfyPage }) => {
|
||||
await comfyPage.setup()
|
||||
await expect(comfyPage.queuePanel.overlayToggle).toBeVisible()
|
||||
await comfyPage.queuePanel.overlayToggle.click()
|
||||
})
|
||||
|
||||
@@ -59,6 +60,7 @@ test.describe('Queue Clear History Dialog', { tag: '@ui' }, () => {
|
||||
return route.continue()
|
||||
})
|
||||
|
||||
await expect(dialog.getByRole('button', { name: 'Cancel' })).toBeVisible()
|
||||
await dialog.getByRole('button', { name: 'Cancel' }).click()
|
||||
await expect(dialog).not.toBeVisible()
|
||||
expect(clearCalled).toBe(false)
|
||||
@@ -82,6 +84,7 @@ test.describe('Queue Clear History Dialog', { tag: '@ui' }, () => {
|
||||
return route.continue()
|
||||
})
|
||||
|
||||
await expect(dialog.getByLabel('Close')).toBeVisible()
|
||||
await dialog.getByLabel('Close').click()
|
||||
await expect(dialog).not.toBeVisible()
|
||||
expect(clearCalled).toBe(false)
|
||||
@@ -101,6 +104,7 @@ test.describe('Queue Clear History Dialog', { tag: '@ui' }, () => {
|
||||
(req) => req.url().includes('/api/history') && req.method() === 'POST'
|
||||
)
|
||||
|
||||
await expect(dialog.getByRole('button', { name: 'Clear' })).toBeVisible()
|
||||
await dialog.getByRole('button', { name: 'Clear' }).click()
|
||||
|
||||
const request = await clearPromise
|
||||
@@ -113,6 +117,7 @@ test.describe('Queue Clear History Dialog', { tag: '@ui' }, () => {
|
||||
await comfyPage.queuePanel.openClearHistoryDialog()
|
||||
const dialog = comfyPage.confirmDialog.root
|
||||
await expect(dialog).toBeVisible()
|
||||
await expect(dialog.getByRole('button', { name: 'Cancel' })).toBeVisible()
|
||||
await dialog.getByRole('button', { name: 'Cancel' }).click()
|
||||
await expect(dialog).not.toBeVisible()
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ test.describe('Sign In dialog', { tag: '@ui' }, () => {
|
||||
})
|
||||
|
||||
test('Should toggle from sign-in to sign-up form', async () => {
|
||||
await expect(dialog.signUpLink).toBeVisible()
|
||||
await dialog.signUpLink.click()
|
||||
|
||||
await expect(
|
||||
@@ -34,11 +35,13 @@ test.describe('Sign In dialog', { tag: '@ui' }, () => {
|
||||
})
|
||||
|
||||
test('Should toggle back from sign-up to sign-in form', async () => {
|
||||
await expect(dialog.signUpLink).toBeVisible()
|
||||
await dialog.signUpLink.click()
|
||||
await expect(
|
||||
dialog.root.getByRole('heading', { name: 'Create an account' })
|
||||
).toBeVisible()
|
||||
|
||||
await expect(dialog.signInLink).toBeVisible()
|
||||
await dialog.signInLink.click()
|
||||
await expect(
|
||||
dialog.root.getByRole('heading', { name: 'Log in to your account' })
|
||||
@@ -48,11 +51,13 @@ test.describe('Sign In dialog', { tag: '@ui' }, () => {
|
||||
})
|
||||
|
||||
test('Should navigate to the API Key form and back', async () => {
|
||||
await expect(dialog.apiKeyButton).toBeVisible()
|
||||
await dialog.apiKeyButton.click()
|
||||
|
||||
await expect(dialog.apiKeyHeading).toBeVisible()
|
||||
await expect(dialog.apiKeyInput).toBeVisible()
|
||||
|
||||
await expect(dialog.backButton).toBeVisible()
|
||||
await dialog.backButton.click()
|
||||
await expect(
|
||||
dialog.root.getByRole('heading', { name: 'Log in to your account' })
|
||||
@@ -83,6 +88,7 @@ test.describe('Sign In dialog', { tag: '@ui' }, () => {
|
||||
})
|
||||
|
||||
test('Should close dialog via close button', async () => {
|
||||
await expect(dialog.closeButton).toBeVisible()
|
||||
await dialog.closeButton.click()
|
||||
await expect(dialog.root).toBeHidden()
|
||||
})
|
||||
|
||||
@@ -76,6 +76,9 @@ test.describe('Error dialog', () => {
|
||||
await expect(errorDialog).toBeVisible()
|
||||
await expect(errorDialog.locator('pre')).not.toBeVisible()
|
||||
|
||||
await expect(
|
||||
errorDialog.getByTestId(TestIds.dialogs.errorDialogShowReport)
|
||||
).toBeVisible()
|
||||
await errorDialog.getByTestId(TestIds.dialogs.errorDialogShowReport).click()
|
||||
|
||||
const reportPre = errorDialog.locator('pre')
|
||||
@@ -92,11 +95,17 @@ test.describe('Error dialog', () => {
|
||||
const errorDialog = await triggerConfigureError(comfyPage)
|
||||
await expect(errorDialog).toBeVisible()
|
||||
|
||||
await expect(
|
||||
errorDialog.getByTestId(TestIds.dialogs.errorDialogShowReport)
|
||||
).toBeVisible()
|
||||
await errorDialog.getByTestId(TestIds.dialogs.errorDialogShowReport).click()
|
||||
await expect(errorDialog.locator('pre')).toBeVisible()
|
||||
|
||||
await interceptClipboardWrite(comfyPage.page)
|
||||
|
||||
await expect(
|
||||
errorDialog.getByTestId(TestIds.dialogs.errorDialogCopyReport)
|
||||
).toBeVisible()
|
||||
await errorDialog.getByTestId(TestIds.dialogs.errorDialogCopyReport).click()
|
||||
|
||||
const reportText = await errorDialog.locator('pre').textContent()
|
||||
|
||||
@@ -149,6 +149,9 @@ test.describe('Error overlay', { tag: '@ui' }, () => {
|
||||
const overlay = getOverlay(comfyPage.page)
|
||||
await expect(overlay).toBeVisible()
|
||||
|
||||
await expect(
|
||||
overlay.getByTestId(TestIds.dialogs.errorOverlaySeeErrors)
|
||||
).toBeVisible()
|
||||
await overlay.getByTestId(TestIds.dialogs.errorOverlaySeeErrors).click()
|
||||
|
||||
await expect(comfyPage.page.getByTestId('properties-panel')).toBeVisible()
|
||||
@@ -160,6 +163,9 @@ test.describe('Error overlay', { tag: '@ui' }, () => {
|
||||
const overlay = getOverlay(comfyPage.page)
|
||||
await expect(overlay).toBeVisible()
|
||||
|
||||
await expect(
|
||||
overlay.getByTestId(TestIds.dialogs.errorOverlaySeeErrors)
|
||||
).toBeVisible()
|
||||
await overlay.getByTestId(TestIds.dialogs.errorOverlaySeeErrors).click()
|
||||
|
||||
await expect(overlay).not.toBeVisible()
|
||||
@@ -173,6 +179,9 @@ test.describe('Error overlay', { tag: '@ui' }, () => {
|
||||
const overlay = getOverlay(comfyPage.page)
|
||||
await expect(overlay).toBeVisible()
|
||||
|
||||
await expect(
|
||||
overlay.getByTestId(TestIds.dialogs.errorOverlayDismiss)
|
||||
).toBeVisible()
|
||||
await overlay.getByTestId(TestIds.dialogs.errorOverlayDismiss).click()
|
||||
|
||||
await expect(overlay).not.toBeVisible()
|
||||
@@ -187,6 +196,9 @@ test.describe('Error overlay', { tag: '@ui' }, () => {
|
||||
const overlay = getOverlay(comfyPage.page)
|
||||
await expect(overlay).toBeVisible()
|
||||
|
||||
await expect(
|
||||
overlay.getByRole('button', { name: /close/i })
|
||||
).toBeVisible()
|
||||
await overlay.getByRole('button', { name: /close/i }).click()
|
||||
|
||||
await expect(overlay).not.toBeVisible()
|
||||
|
||||
@@ -361,6 +361,7 @@ test.describe('Topbar commands', () => {
|
||||
const toolboxButton = comfyPage.page.locator(
|
||||
'.selection-toolbox button:has(.pi-star)'
|
||||
)
|
||||
await expect(toolboxButton).toBeVisible()
|
||||
await toolboxButton.click()
|
||||
|
||||
expect(
|
||||
|
||||
@@ -23,6 +23,7 @@ test.describe('Graph Canvas Menu', { tag: ['@screenshot', '@canvas'] }, () => {
|
||||
const button = comfyPage.page.getByTestId(
|
||||
TestIds.canvas.toggleLinkVisibilityButton
|
||||
)
|
||||
await expect(button).toBeVisible()
|
||||
await button.click()
|
||||
await comfyPage.nextFrame()
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
@@ -35,6 +36,7 @@ test.describe('Graph Canvas Menu', { tag: ['@screenshot', '@canvas'] }, () => {
|
||||
hiddenLinkRenderMode
|
||||
)
|
||||
|
||||
await expect(button).toBeVisible()
|
||||
await button.click()
|
||||
await comfyPage.nextFrame()
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
@@ -91,6 +93,7 @@ test.describe('Graph Canvas Menu', { tag: ['@screenshot', '@canvas'] }, () => {
|
||||
|
||||
// Click backdrop to close
|
||||
const backdrop = comfyPage.page.locator('.fixed.inset-0').first()
|
||||
await expect(backdrop).toBeVisible()
|
||||
await backdrop.click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
|
||||
@@ -41,7 +41,9 @@ test.describe('Group Node', { tag: '@node' }, () => {
|
||||
const initialNodeCount = await comfyPage.nodeOps.getGraphNodesCount()
|
||||
|
||||
// Add group node from node library sidebar
|
||||
await expect(libraryTab.getFolder(groupNodeCategory)).toBeVisible()
|
||||
await libraryTab.getFolder(groupNodeCategory).click()
|
||||
await expect(libraryTab.getNode(groupNodeName)).toBeVisible()
|
||||
await libraryTab.getNode(groupNodeName).click()
|
||||
|
||||
// Verify the node is added to the canvas
|
||||
@@ -51,6 +53,7 @@ test.describe('Group Node', { tag: '@node' }, () => {
|
||||
})
|
||||
|
||||
test('Can be bookmarked and unbookmarked', async ({ comfyPage }) => {
|
||||
await expect(libraryTab.getFolder(groupNodeCategory)).toBeVisible()
|
||||
await libraryTab.getFolder(groupNodeCategory).click()
|
||||
await libraryTab
|
||||
.getNode(groupNodeName)
|
||||
@@ -78,6 +81,7 @@ test.describe('Group Node', { tag: '@node' }, () => {
|
||||
})
|
||||
|
||||
test('Displays preview on bookmark hover', async ({ comfyPage }) => {
|
||||
await expect(libraryTab.getFolder(groupNodeCategory)).toBeVisible()
|
||||
await libraryTab.getFolder(groupNodeCategory).click()
|
||||
await libraryTab
|
||||
.getNode(groupNodeName)
|
||||
|
||||
@@ -43,6 +43,7 @@ test.describe('Item Interaction', { tag: ['@screenshot', '@node'] }, () => {
|
||||
test.describe('Node Interaction', () => {
|
||||
test('Can enter prompt', async ({ comfyPage }) => {
|
||||
const textBox = comfyPage.widgetTextBox
|
||||
await expect(textBox).toBeVisible()
|
||||
await textBox.click()
|
||||
await textBox.fill('Hello World')
|
||||
await expect(textBox).toHaveValue('Hello World')
|
||||
@@ -684,6 +685,7 @@ test.describe('Canvas Interaction', { tag: '@screenshot' }, () => {
|
||||
test.describe('Widget Interaction', () => {
|
||||
test('Undo text input', async ({ comfyPage }) => {
|
||||
const textBox = comfyPage.widgetTextBox
|
||||
await expect(textBox).toBeVisible()
|
||||
await textBox.click()
|
||||
await textBox.fill('')
|
||||
await expect(textBox).toHaveValue('')
|
||||
@@ -696,6 +698,7 @@ test.describe('Widget Interaction', () => {
|
||||
test('Undo attention edit', async ({ comfyPage }) => {
|
||||
await comfyPage.settings.setSetting('Comfy.EditAttention.Delta', 0.05)
|
||||
const textBox = comfyPage.widgetTextBox
|
||||
await expect(textBox).toBeVisible()
|
||||
await textBox.click()
|
||||
await textBox.fill('1girl')
|
||||
await expect(textBox).toHaveValue('1girl')
|
||||
@@ -964,6 +967,7 @@ test.describe('Viewport settings', () => {
|
||||
comfyMouse
|
||||
}) => {
|
||||
const changeTab = async (tab: Locator) => {
|
||||
await expect(tab).toBeVisible()
|
||||
await tab.click()
|
||||
await comfyPage.nextFrame()
|
||||
await comfyMouse.move(DefaultGraphPositions.emptySpace)
|
||||
@@ -980,6 +984,7 @@ test.describe('Viewport settings', () => {
|
||||
const toggleButton = comfyPage.page.getByTestId(
|
||||
TestIds.canvas.toggleMinimapButton
|
||||
)
|
||||
await expect(toggleButton).toBeVisible()
|
||||
await toggleButton.click()
|
||||
await comfyPage.settings.setSetting('Comfy.Graph.CanvasMenu', false)
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@ test.describe('Job History Actions', { tag: '@ui' }, () => {
|
||||
await comfyPage.setup()
|
||||
|
||||
// Expand the queue overlay so the JobHistoryActionsMenu is visible
|
||||
await expect(
|
||||
comfyPage.page.getByTestId('queue-overlay-toggle')
|
||||
).toBeVisible()
|
||||
await comfyPage.page.getByTestId('queue-overlay-toggle').click()
|
||||
})
|
||||
|
||||
@@ -18,6 +21,7 @@ test.describe('Job History Actions', { tag: '@ui' }, () => {
|
||||
page: { getByLabel(label: string | RegExp): Locator }
|
||||
}) {
|
||||
const moreButton = comfyPage.page.getByLabel(/More options/i).first()
|
||||
await expect(moreButton).toBeVisible()
|
||||
await moreButton.click()
|
||||
}
|
||||
|
||||
@@ -81,6 +85,7 @@ test.describe('Job History Actions', { tag: '@ui' }, () => {
|
||||
const action = comfyPage.page.locator(
|
||||
'[data-testid="show-run-progress-bar-action"]'
|
||||
)
|
||||
await expect(action).toBeVisible()
|
||||
await action.click()
|
||||
|
||||
const settingAfter = await comfyPage.settings.getSetting<boolean>(
|
||||
|
||||
@@ -27,9 +27,13 @@ const TEST_PRESET = {
|
||||
|
||||
async function importPreset(page: Page, preset: typeof TEST_PRESET) {
|
||||
const menuButton = page.getByTestId('keybinding-preset-menu')
|
||||
await expect(menuButton).toBeVisible()
|
||||
await menuButton.click()
|
||||
|
||||
const fileChooserPromise = page.waitForEvent('filechooser')
|
||||
await expect(
|
||||
page.getByRole('menuitem', { name: /Import preset/i })
|
||||
).toBeVisible()
|
||||
await page.getByRole('menuitem', { name: /Import preset/i }).click()
|
||||
const fileChooser = await fileChooserPromise
|
||||
|
||||
@@ -68,6 +72,7 @@ test.describe('Keybinding Presets', { tag: '@keyboard' }, () => {
|
||||
|
||||
// Open keybinding settings panel
|
||||
await comfyPage.settingDialog.open()
|
||||
await expect(comfyPage.settingDialog.category('Keybinding')).toBeVisible()
|
||||
await comfyPage.settingDialog.category('Keybinding').click()
|
||||
|
||||
await importPreset(page, TEST_PRESET)
|
||||
@@ -96,9 +101,14 @@ test.describe('Keybinding Presets', { tag: '@keyboard' }, () => {
|
||||
|
||||
// Switch back to default preset
|
||||
await comfyPage.settingDialog.open()
|
||||
await expect(comfyPage.settingDialog.category('Keybinding')).toBeVisible()
|
||||
await comfyPage.settingDialog.category('Keybinding').click()
|
||||
|
||||
await expect(presetTrigger).toBeVisible()
|
||||
await presetTrigger.click()
|
||||
await expect(
|
||||
page.getByRole('option', { name: /Default Preset/i })
|
||||
).toBeVisible()
|
||||
await page.getByRole('option', { name: /Default Preset/i }).click()
|
||||
|
||||
// Handle unsaved changes dialog if the preset was marked as modified
|
||||
@@ -106,6 +116,7 @@ test.describe('Keybinding Presets', { tag: '@keyboard' }, () => {
|
||||
name: /Discard and Switch/i
|
||||
})
|
||||
if (await discardButton.isVisible({ timeout: 2000 }).catch(() => false)) {
|
||||
await expect(discardButton).toBeVisible()
|
||||
await discardButton.click()
|
||||
}
|
||||
|
||||
@@ -122,6 +133,7 @@ test.describe('Keybinding Presets', { tag: '@keyboard' }, () => {
|
||||
|
||||
// Open keybinding settings panel
|
||||
await comfyPage.settingDialog.open()
|
||||
await expect(comfyPage.settingDialog.category('Keybinding')).toBeVisible()
|
||||
await comfyPage.settingDialog.category('Keybinding').click()
|
||||
|
||||
await importPreset(page, TEST_PRESET)
|
||||
@@ -138,8 +150,12 @@ test.describe('Keybinding Presets', { tag: '@keyboard' }, () => {
|
||||
})
|
||||
|
||||
// Export via ellipsis menu
|
||||
await expect(menuButton).toBeVisible()
|
||||
await menuButton.click()
|
||||
const downloadPromise = page.waitForEvent('download')
|
||||
await expect(
|
||||
page.getByRole('menuitem', { name: /Export preset/i })
|
||||
).toBeVisible()
|
||||
await page.getByRole('menuitem', { name: /Export preset/i }).click()
|
||||
const download = await downloadPromise
|
||||
|
||||
@@ -172,6 +188,7 @@ test.describe('Keybinding Presets', { tag: '@keyboard' }, () => {
|
||||
|
||||
// Open keybinding settings panel
|
||||
await comfyPage.settingDialog.open()
|
||||
await expect(comfyPage.settingDialog.category('Keybinding')).toBeVisible()
|
||||
await comfyPage.settingDialog.category('Keybinding').click()
|
||||
|
||||
await importPreset(page, TEST_PRESET)
|
||||
@@ -188,13 +205,20 @@ test.describe('Keybinding Presets', { tag: '@keyboard' }, () => {
|
||||
})
|
||||
|
||||
// Delete via ellipsis menu
|
||||
await expect(menuButton).toBeVisible()
|
||||
await menuButton.click()
|
||||
await expect(
|
||||
page.getByRole('menuitem', { name: /Delete preset/i })
|
||||
).toBeVisible()
|
||||
await page.getByRole('menuitem', { name: /Delete preset/i }).click()
|
||||
|
||||
// Confirm deletion in the dialog
|
||||
const confirmDialog = page.getByRole('dialog', {
|
||||
name: /Delete the current preset/i
|
||||
})
|
||||
await expect(
|
||||
confirmDialog.getByRole('button', { name: /Delete/i })
|
||||
).toBeVisible()
|
||||
await confirmDialog.getByRole('button', { name: /Delete/i }).click()
|
||||
|
||||
// Verify preset trigger now shows Default Preset
|
||||
@@ -212,6 +236,7 @@ test.describe('Keybinding Presets', { tag: '@keyboard' }, () => {
|
||||
|
||||
// Open keybinding settings panel
|
||||
await comfyPage.settingDialog.open()
|
||||
await expect(comfyPage.settingDialog.category('Keybinding')).toBeVisible()
|
||||
await comfyPage.settingDialog.category('Keybinding').click()
|
||||
|
||||
await importPreset(page, TEST_PRESET)
|
||||
@@ -228,7 +253,11 @@ test.describe('Keybinding Presets', { tag: '@keyboard' }, () => {
|
||||
})
|
||||
|
||||
// Save as new preset via ellipsis menu
|
||||
await expect(menuButton).toBeVisible()
|
||||
await menuButton.click()
|
||||
await expect(
|
||||
page.getByRole('menuitem', { name: /Save as new preset/i })
|
||||
).toBeVisible()
|
||||
await page.getByRole('menuitem', { name: /Save as new preset/i }).click()
|
||||
|
||||
// Fill in the preset name in the prompt dialog
|
||||
|
||||
@@ -15,6 +15,7 @@ test.describe('Keybindings', { tag: '@keyboard' }, () => {
|
||||
})
|
||||
|
||||
const textBox = comfyPage.widgetTextBox
|
||||
await expect(textBox).toBeVisible()
|
||||
await textBox.click()
|
||||
await textBox.fill('k')
|
||||
await expect(textBox).toHaveValue('k')
|
||||
@@ -31,6 +32,7 @@ test.describe('Keybindings', { tag: '@keyboard' }, () => {
|
||||
})
|
||||
|
||||
const textBox = comfyPage.widgetTextBox
|
||||
await expect(textBox).toBeVisible()
|
||||
await textBox.click()
|
||||
await textBox.fill('q')
|
||||
await textBox.press('Control+k')
|
||||
@@ -46,6 +48,7 @@ test.describe('Keybindings', { tag: '@keyboard' }, () => {
|
||||
})
|
||||
|
||||
const textBox = comfyPage.widgetTextBox
|
||||
await expect(textBox).toBeVisible()
|
||||
await textBox.click()
|
||||
await textBox.press('Control+v')
|
||||
await expect(textBox).toBeFocused()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import type { Locator } from '@playwright/test'
|
||||
import { expect } from '@playwright/test'
|
||||
|
||||
export class Load3DHelper {
|
||||
constructor(readonly node: Locator) {}
|
||||
@@ -28,6 +29,7 @@ export class Load3DHelper {
|
||||
}
|
||||
|
||||
async openMenu(): Promise<void> {
|
||||
await expect(this.menuButton).toBeVisible()
|
||||
await this.menuButton.click()
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,9 @@ test.describe('Mask Editor', () => {
|
||||
|
||||
// Hover over the image panel to reveal action buttons
|
||||
await imagePreview.getByRole('region').hover()
|
||||
await expect(
|
||||
comfyPage.page.getByLabel('Edit or mask image')
|
||||
).toBeVisible()
|
||||
await comfyPage.page.getByLabel('Edit or mask image').click()
|
||||
|
||||
const dialog = comfyPage.page.locator('.mask-editor-dialog')
|
||||
@@ -70,12 +73,14 @@ test.describe('Mask Editor', () => {
|
||||
const nodeHeader = comfyPage.vueNodes
|
||||
.getNodeLocator(nodeId)
|
||||
.locator('.lg-node-header')
|
||||
await expect(nodeHeader).toBeVisible()
|
||||
await nodeHeader.click()
|
||||
await nodeHeader.click({ button: 'right' })
|
||||
|
||||
const contextMenu = comfyPage.page.locator('.p-contextmenu')
|
||||
await expect(contextMenu).toBeVisible()
|
||||
|
||||
await expect(contextMenu.getByText('Open in Mask Editor')).toBeVisible()
|
||||
await contextMenu.getByText('Open in Mask Editor').click()
|
||||
|
||||
const dialog = comfyPage.page.locator('.mask-editor-dialog')
|
||||
|
||||
@@ -119,6 +119,7 @@ test.describe('Menu', { tag: '@ui' }, () => {
|
||||
await expect(checkmark).not.toHaveClass(/invisible/)
|
||||
|
||||
// Click Bottom Panel again to toggle it off
|
||||
await expect(bottomPanelItem).toBeVisible()
|
||||
await bottomPanelItem.click()
|
||||
|
||||
// Verify menu is still visible after second click
|
||||
|
||||
@@ -52,6 +52,7 @@ test.describe('Minimap', { tag: '@canvas' }, () => {
|
||||
|
||||
await expect(minimapContainer).toBeVisible()
|
||||
|
||||
await expect(toggleButton).toBeVisible()
|
||||
await toggleButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -83,6 +84,9 @@ test.describe('Minimap', { tag: '@canvas' }, () => {
|
||||
const minimap = comfyPage.page.locator('.litegraph-minimap')
|
||||
await expect(minimap).toBeVisible()
|
||||
|
||||
await expect(
|
||||
comfyPage.page.getByTestId(TestIds.canvas.closeMinimapButton)
|
||||
).toBeVisible()
|
||||
await comfyPage.page.getByTestId(TestIds.canvas.closeMinimapButton).click()
|
||||
await expect(minimap).not.toBeVisible()
|
||||
|
||||
|
||||
@@ -174,6 +174,7 @@ test.describe('Node Help', { tag: ['@slow', '@ui'] }, () => {
|
||||
const helpButton = ksamplerNode.getByRole('button', {
|
||||
name: /learn more/i
|
||||
})
|
||||
await expect(helpButton).toBeVisible()
|
||||
await helpButton.click()
|
||||
|
||||
// Verify help page is shown
|
||||
@@ -182,6 +183,7 @@ test.describe('Node Help', { tag: ['@slow', '@ui'] }, () => {
|
||||
|
||||
// Click the back button - use a more specific selector
|
||||
const backButton = helpPage.getByRole('button', { name: /back/i })
|
||||
await expect(backButton).toBeVisible()
|
||||
await backButton.click()
|
||||
|
||||
// Verify that we're back to the node library view
|
||||
|
||||
@@ -37,6 +37,7 @@ test.describe('Node Library Essentials Tab', { tag: '@ui' }, () => {
|
||||
|
||||
test('Node library opens via sidebar', async ({ comfyPage }) => {
|
||||
const tabButton = comfyPage.page.locator('.node-library-tab-button')
|
||||
await expect(tabButton).toBeVisible()
|
||||
await tabButton.click()
|
||||
|
||||
const sidebarContent = comfyPage.page.locator(
|
||||
@@ -47,6 +48,7 @@ test.describe('Node Library Essentials Tab', { tag: '@ui' }, () => {
|
||||
|
||||
test('Essentials tab is visible in node library', async ({ comfyPage }) => {
|
||||
const tabButton = comfyPage.page.locator('.node-library-tab-button')
|
||||
await expect(tabButton).toBeVisible()
|
||||
await tabButton.click()
|
||||
|
||||
const essentialsTab = comfyPage.page.getByRole('tab', {
|
||||
@@ -59,11 +61,13 @@ test.describe('Node Library Essentials Tab', { tag: '@ui' }, () => {
|
||||
comfyPage
|
||||
}) => {
|
||||
const tabButton = comfyPage.page.locator('.node-library-tab-button')
|
||||
await expect(tabButton).toBeVisible()
|
||||
await tabButton.click()
|
||||
|
||||
const essentialsTab = comfyPage.page.getByRole('tab', {
|
||||
name: /essentials/i
|
||||
})
|
||||
await expect(essentialsTab).toBeVisible()
|
||||
await essentialsTab.click()
|
||||
|
||||
const essentialCards = comfyPage.page.locator('[data-node-name]')
|
||||
@@ -72,11 +76,13 @@ test.describe('Node Library Essentials Tab', { tag: '@ui' }, () => {
|
||||
|
||||
test('Essential node cards have node names', async ({ comfyPage }) => {
|
||||
const tabButton = comfyPage.page.locator('.node-library-tab-button')
|
||||
await expect(tabButton).toBeVisible()
|
||||
await tabButton.click()
|
||||
|
||||
const essentialsTab = comfyPage.page.getByRole('tab', {
|
||||
name: /essentials/i
|
||||
})
|
||||
await expect(essentialsTab).toBeVisible()
|
||||
await essentialsTab.click()
|
||||
|
||||
const firstCard = comfyPage.page.locator('[data-node-name]').first()
|
||||
@@ -91,6 +97,7 @@ test.describe('Node Library Essentials Tab', { tag: '@ui' }, () => {
|
||||
comfyPage
|
||||
}) => {
|
||||
const tabButton = comfyPage.page.locator('.node-library-tab-button')
|
||||
await expect(tabButton).toBeVisible()
|
||||
await tabButton.click()
|
||||
|
||||
const essentialsTab = comfyPage.page.getByRole('tab', {
|
||||
@@ -98,11 +105,13 @@ test.describe('Node Library Essentials Tab', { tag: '@ui' }, () => {
|
||||
})
|
||||
const allNodesTab = comfyPage.page.getByRole('tab', { name: /^all$/i })
|
||||
|
||||
await expect(essentialsTab).toBeVisible()
|
||||
await essentialsTab.click()
|
||||
await expect(essentialsTab).toHaveAttribute('aria-selected', 'true')
|
||||
const essentialCards = comfyPage.page.locator('[data-node-name]')
|
||||
await expect(essentialCards.first()).toBeVisible()
|
||||
|
||||
await expect(allNodesTab).toBeVisible()
|
||||
await allNodesTab.click()
|
||||
await expect(allNodesTab).toHaveAttribute('aria-selected', 'true')
|
||||
await expect(essentialsTab).toHaveAttribute('aria-selected', 'false')
|
||||
|
||||
@@ -127,6 +127,7 @@ test.describe('Node search box', { tag: '@node' }, () => {
|
||||
const initialNodeCount = await comfyPage.nodeOps.getGraphNodesCount()
|
||||
await comfyPage.canvasOps.disconnectEdge()
|
||||
await expect(comfyPage.searchBox.input).toHaveCount(1)
|
||||
await expect(comfyPage.page.locator('.p-chip-remove-icon')).toBeVisible()
|
||||
await comfyPage.page.locator('.p-chip-remove-icon').click()
|
||||
await comfyPage.searchBox.fillAndSelectFirstNode('KSampler', {
|
||||
exact: true
|
||||
@@ -197,6 +198,7 @@ test.describe('Node search box', { tag: '@node' }, () => {
|
||||
test('Outer click dismisses filter panel but keeps search box visible', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await expect(comfyPage.searchBox.filterButton).toBeVisible()
|
||||
await comfyPage.searchBox.filterButton.click()
|
||||
const panel = comfyPage.searchBox.filterSelectionPanel
|
||||
await panel.header.waitFor({ state: 'visible' })
|
||||
|
||||
@@ -64,6 +64,7 @@ test.describe('Node search box V2', { tag: '@node' }, () => {
|
||||
await comfyPage.canvasOps.doubleClick()
|
||||
await expect(searchBoxV2.input).toBeVisible()
|
||||
|
||||
await expect(searchBoxV2.categoryButton('favorites')).toBeVisible()
|
||||
await searchBoxV2.categoryButton('favorites').click()
|
||||
|
||||
await expect(searchBoxV2.results).toHaveCount(1)
|
||||
@@ -78,6 +79,7 @@ test.describe('Node search box V2', { tag: '@node' }, () => {
|
||||
await comfyPage.canvasOps.doubleClick()
|
||||
await expect(searchBoxV2.input).toBeVisible()
|
||||
|
||||
await expect(searchBoxV2.categoryButton('sampling')).toBeVisible()
|
||||
await searchBoxV2.categoryButton('sampling').click()
|
||||
|
||||
await expect(searchBoxV2.results.first()).toBeVisible()
|
||||
@@ -94,6 +96,7 @@ test.describe('Node search box V2', { tag: '@node' }, () => {
|
||||
await expect(searchBoxV2.input).toBeVisible()
|
||||
|
||||
// Click "Input" filter chip in the filter bar
|
||||
await expect(searchBoxV2.filterBarButton('Input')).toBeVisible()
|
||||
await searchBoxV2.filterBarButton('Input').click()
|
||||
|
||||
// Filter options should appear
|
||||
|
||||
@@ -69,10 +69,12 @@ test.describe('Node search box V2 extended', { tag: '@node' }, () => {
|
||||
await comfyPage.canvasOps.doubleClick()
|
||||
await expect(searchBoxV2.input).toBeVisible()
|
||||
|
||||
await expect(searchBoxV2.categoryButton('sampling')).toBeVisible()
|
||||
await searchBoxV2.categoryButton('sampling').click()
|
||||
await expect(searchBoxV2.results.first()).toBeVisible()
|
||||
const samplingResults = await searchBoxV2.results.allTextContents()
|
||||
|
||||
await expect(searchBoxV2.categoryButton('loaders')).toBeVisible()
|
||||
await searchBoxV2.categoryButton('loaders').click()
|
||||
await expect(searchBoxV2.results.first()).toBeVisible()
|
||||
const loaderResults = await searchBoxV2.results.allTextContents()
|
||||
@@ -93,6 +95,7 @@ test.describe('Node search box V2 extended', { tag: '@node' }, () => {
|
||||
const unfilteredResults = await searchBoxV2.results.allTextContents()
|
||||
|
||||
// Apply Input filter with MODEL type
|
||||
await expect(searchBoxV2.filterBarButton('Input')).toBeVisible()
|
||||
await searchBoxV2.filterBarButton('Input').click()
|
||||
await expect(searchBoxV2.filterOptions.first()).toBeVisible()
|
||||
await searchBoxV2.input.fill('MODEL')
|
||||
@@ -111,6 +114,7 @@ test.describe('Node search box V2 extended', { tag: '@node' }, () => {
|
||||
expect(filteredResults).not.toEqual(unfilteredResults)
|
||||
|
||||
// Remove filter by clicking the chip delete button
|
||||
await expect(filterChip.getByTestId('chip-delete')).toBeVisible()
|
||||
await filterChip.getByTestId('chip-delete').click()
|
||||
|
||||
// Filter chip should be removed
|
||||
|
||||
@@ -19,6 +19,7 @@ test.describe('Paste Image context menu option', { tag: ['@node'] }, () => {
|
||||
const nodeEl = comfyPage.page.locator(
|
||||
`[data-node-id="${loadImageNode.id}"]`
|
||||
)
|
||||
await expect(nodeEl).toBeVisible()
|
||||
await nodeEl.click({ button: 'right' })
|
||||
const menu = comfyPage.page.locator('.p-contextmenu')
|
||||
await menu.waitFor({ state: 'visible' })
|
||||
@@ -41,6 +42,7 @@ test.describe('Paste Image context menu option', { tag: ['@node'] }, () => {
|
||||
const nodeEl = comfyPage.page.locator(
|
||||
`[data-node-id="${saveImageNode.id}"]`
|
||||
)
|
||||
await expect(nodeEl).toBeVisible()
|
||||
await nodeEl.click({ button: 'right' })
|
||||
const menu = comfyPage.page.locator('.p-contextmenu')
|
||||
await menu.waitFor({ state: 'visible' })
|
||||
|
||||
@@ -12,6 +12,9 @@ export async function openErrorsTabViaSeeErrors(
|
||||
const errorOverlay = comfyPage.page.getByTestId(TestIds.dialogs.errorOverlay)
|
||||
await expect(errorOverlay).toBeVisible()
|
||||
|
||||
await expect(
|
||||
errorOverlay.getByTestId(TestIds.dialogs.errorOverlaySeeErrors)
|
||||
).toBeVisible()
|
||||
await errorOverlay.getByTestId(TestIds.dialogs.errorOverlaySeeErrors).click()
|
||||
await expect(errorOverlay).not.toBeVisible()
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ export class PropertiesPanelHelper {
|
||||
|
||||
async open(actionbar: Locator): Promise<void> {
|
||||
if (!(await this.root.isVisible())) {
|
||||
await expect(actionbar).toBeVisible()
|
||||
await actionbar.click()
|
||||
await expect(this.root).toBeVisible()
|
||||
}
|
||||
@@ -75,16 +76,19 @@ export class PropertiesPanelHelper {
|
||||
|
||||
async close(): Promise<void> {
|
||||
if (await this.root.isVisible()) {
|
||||
await expect(this.closeButton).toBeVisible()
|
||||
await this.closeButton.click()
|
||||
await expect(this.root).not.toBeVisible()
|
||||
}
|
||||
}
|
||||
|
||||
async switchToTab(label: string): Promise<void> {
|
||||
await expect(this.getTab(label)).toBeVisible()
|
||||
await this.getTab(label).click()
|
||||
}
|
||||
|
||||
async editTitle(newTitle: string): Promise<void> {
|
||||
await expect(this.titleEditIcon).toBeVisible()
|
||||
await this.titleEditIcon.click()
|
||||
await this.titleInput.fill(newTitle)
|
||||
await this.titleInput.press('Enter')
|
||||
|
||||
@@ -16,6 +16,7 @@ test.describe('Errors tab - common', { tag: '@ui' }, () => {
|
||||
test.describe('Tab visibility', () => {
|
||||
test('Should show Errors tab when errors exist', async ({ comfyPage }) => {
|
||||
await comfyPage.workflow.loadWorkflow('missing/missing_nodes')
|
||||
await expect(comfyPage.actionbar.propertiesButton).toBeVisible()
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -31,6 +32,7 @@ test.describe('Errors tab - common', { tag: '@ui' }, () => {
|
||||
'Comfy.RightSidePanel.ShowErrorsTab',
|
||||
false
|
||||
)
|
||||
await expect(comfyPage.actionbar.propertiesButton).toBeVisible()
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ async function confirmPendingSelection(comfyPage: ComfyPage) {
|
||||
TestIds.dialogs.missingMediaConfirmButton
|
||||
)
|
||||
await expect(confirmButton).toBeEnabled()
|
||||
await expect(confirmButton).toBeVisible()
|
||||
await confirmButton.click()
|
||||
}
|
||||
|
||||
@@ -100,6 +101,7 @@ test.describe('Errors tab - Missing media', { tag: '@ui' }, () => {
|
||||
const librarySelect = comfyPage.page.getByTestId(
|
||||
TestIds.dialogs.missingMediaLibrarySelect
|
||||
)
|
||||
await expect(librarySelect.getByRole('combobox')).toBeVisible()
|
||||
await librarySelect.getByRole('combobox').click()
|
||||
|
||||
const optionCount = await comfyPage.page.getByRole('option').count()
|
||||
@@ -108,6 +110,7 @@ test.describe('Errors tab - Missing media', { tag: '@ui' }, () => {
|
||||
return
|
||||
}
|
||||
|
||||
await expect(comfyPage.page.getByRole('option').first()).toBeVisible()
|
||||
await comfyPage.page.getByRole('option').first().click()
|
||||
|
||||
await expect(getStatusCard(comfyPage)).toBeVisible()
|
||||
|
||||
@@ -60,6 +60,7 @@ test.describe('Errors tab - Missing models', { tag: '@ui' }, () => {
|
||||
TestIds.dialogs.missingModelExpand
|
||||
)
|
||||
await expect(expandButton.first()).toBeVisible()
|
||||
await expect(expandButton.first()).toBeVisible()
|
||||
await expandButton.first().click()
|
||||
|
||||
await expect(locateButton.first()).toBeVisible()
|
||||
@@ -73,6 +74,7 @@ test.describe('Errors tab - Missing models', { tag: '@ui' }, () => {
|
||||
TestIds.dialogs.missingModelCopyName
|
||||
)
|
||||
await expect(copyButton.first()).toBeVisible()
|
||||
await expect(copyButton.first()).toBeVisible()
|
||||
await copyButton.first().click()
|
||||
|
||||
const copiedText = await getClipboardText(comfyPage.page)
|
||||
|
||||
@@ -8,6 +8,7 @@ test.describe('Properties panel - Info tab', () => {
|
||||
|
||||
test.beforeEach(async ({ comfyPage }) => {
|
||||
panel = new PropertiesPanelHelper(comfyPage.page)
|
||||
await expect(comfyPage.actionbar.propertiesButton).toBeVisible()
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
await comfyPage.nodeOps.selectNodes(['KSampler'])
|
||||
await panel.switchToTab('Info')
|
||||
|
||||
@@ -8,6 +8,7 @@ test.describe('Properties panel - Node selection', () => {
|
||||
|
||||
test.beforeEach(async ({ comfyPage }) => {
|
||||
panel = new PropertiesPanelHelper(comfyPage.page)
|
||||
await expect(comfyPage.actionbar.propertiesButton).toBeVisible()
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
})
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ test.describe('Properties panel - Node settings', () => {
|
||||
panel = new PropertiesPanelHelper(comfyPage.page)
|
||||
await comfyPage.settings.setSetting('Comfy.VueNodes.Enabled', true)
|
||||
await comfyPage.vueNodes.waitForNodes()
|
||||
await expect(comfyPage.actionbar.propertiesButton).toBeVisible()
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
await comfyPage.nodeOps.selectNodes(['KSampler'])
|
||||
await panel.switchToTab('Settings')
|
||||
@@ -23,6 +24,7 @@ test.describe('Properties panel - Node settings', () => {
|
||||
})
|
||||
|
||||
test('should set node to Bypass mode', async ({ comfyPage }) => {
|
||||
await expect(panel.getNodeStateButton('Bypass')).toBeVisible()
|
||||
await panel.getNodeStateButton('Bypass').click()
|
||||
|
||||
const nodeLocator = comfyPage.vueNodes.getNodeByTitle('KSampler')
|
||||
@@ -30,6 +32,7 @@ test.describe('Properties panel - Node settings', () => {
|
||||
})
|
||||
|
||||
test('should set node to Mute mode', async ({ comfyPage }) => {
|
||||
await expect(panel.getNodeStateButton('Mute')).toBeVisible()
|
||||
await panel.getNodeStateButton('Mute').click()
|
||||
|
||||
const nodeLocator = comfyPage.vueNodes.getNodeByTitle('KSampler')
|
||||
@@ -37,10 +40,12 @@ test.describe('Properties panel - Node settings', () => {
|
||||
})
|
||||
|
||||
test('should restore node to Normal mode', async ({ comfyPage }) => {
|
||||
await expect(panel.getNodeStateButton('Bypass')).toBeVisible()
|
||||
await panel.getNodeStateButton('Bypass').click()
|
||||
const nodeLocator = comfyPage.vueNodes.getNodeByTitle('KSampler')
|
||||
await expect(nodeLocator.getByText('Bypassed')).toBeVisible()
|
||||
|
||||
await expect(panel.getNodeStateButton('Normal')).toBeVisible()
|
||||
await panel.getNodeStateButton('Normal').click()
|
||||
await expect(nodeLocator.getByText('Bypassed')).not.toBeVisible()
|
||||
await expect(nodeLocator.getByText('Muted')).not.toBeVisible()
|
||||
@@ -55,6 +60,7 @@ test.describe('Properties panel - Node settings', () => {
|
||||
})
|
||||
|
||||
test('should apply color to node', async ({ comfyPage }) => {
|
||||
await expect(panel.getColorSwatch('red')).toBeVisible()
|
||||
await panel.getColorSwatch('red').click()
|
||||
|
||||
await expect
|
||||
@@ -69,6 +75,7 @@ test.describe('Properties panel - Node settings', () => {
|
||||
})
|
||||
|
||||
test('should remove color with noColor swatch', async ({ comfyPage }) => {
|
||||
await expect(panel.getColorSwatch('red')).toBeVisible()
|
||||
await panel.getColorSwatch('red').click()
|
||||
|
||||
await expect
|
||||
@@ -81,6 +88,7 @@ test.describe('Properties panel - Node settings', () => {
|
||||
)
|
||||
.toBe(true)
|
||||
|
||||
await expect(panel.getColorSwatch('noColor')).toBeVisible()
|
||||
await panel.getColorSwatch('noColor').click()
|
||||
|
||||
await expect
|
||||
@@ -110,6 +118,7 @@ test.describe('Properties panel - Node settings', () => {
|
||||
test('should unpin previously pinned node', async ({ comfyPage }) => {
|
||||
const nodeLocator = comfyPage.vueNodes.getNodeByTitle('KSampler')
|
||||
|
||||
await expect(panel.pinnedSwitch).toBeVisible()
|
||||
await panel.pinnedSwitch.click()
|
||||
await expect(nodeLocator.getByTestId('node-pin-indicator')).toBeVisible()
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ test.describe('Properties panel - Open and close', () => {
|
||||
|
||||
test('should open via actionbar toggle button', async ({ comfyPage }) => {
|
||||
await expect(panel.root).not.toBeVisible()
|
||||
await expect(comfyPage.actionbar.propertiesButton).toBeVisible()
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
await expect(panel.root).toBeVisible()
|
||||
})
|
||||
@@ -19,11 +20,13 @@ test.describe('Properties panel - Open and close', () => {
|
||||
test('should close via panel close button', async ({ comfyPage }) => {
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
await expect(panel.root).toBeVisible()
|
||||
await expect(panel.closeButton).toBeVisible()
|
||||
await panel.closeButton.click()
|
||||
await expect(panel.root).not.toBeVisible()
|
||||
})
|
||||
|
||||
test('should close via close button after opening', async ({ comfyPage }) => {
|
||||
await expect(comfyPage.actionbar.propertiesButton).toBeVisible()
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
await expect(panel.root).toBeVisible()
|
||||
await panel.close()
|
||||
|
||||
@@ -8,6 +8,7 @@ test.describe('Properties panel position', () => {
|
||||
await comfyPage.settings.setSetting('Comfy.NodeLibrary.NewDesign', false)
|
||||
// Open a sidebar tab to ensure sidebar is visible
|
||||
await comfyPage.menu.nodeLibraryTab.open()
|
||||
await expect(comfyPage.actionbar.propertiesButton).toBeVisible()
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
})
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ test.describe('Properties panel - Search filtering', () => {
|
||||
|
||||
test.beforeEach(async ({ comfyPage }) => {
|
||||
panel = new PropertiesPanelHelper(comfyPage.page)
|
||||
await expect(comfyPage.actionbar.propertiesButton).toBeVisible()
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
await comfyPage.nodeOps.selectNodes([
|
||||
'KSampler',
|
||||
|
||||
@@ -8,6 +8,7 @@ test.describe('Properties panel - Title editing', () => {
|
||||
|
||||
test.beforeEach(async ({ comfyPage }) => {
|
||||
panel = new PropertiesPanelHelper(comfyPage.page)
|
||||
await expect(comfyPage.actionbar.propertiesButton).toBeVisible()
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
await comfyPage.nodeOps.selectNodes(['KSampler'])
|
||||
})
|
||||
|
||||
@@ -8,6 +8,7 @@ test.describe('Properties panel - Workflow Overview', () => {
|
||||
|
||||
test.beforeEach(async ({ comfyPage }) => {
|
||||
panel = new PropertiesPanelHelper(comfyPage.page)
|
||||
await expect(comfyPage.actionbar.propertiesButton).toBeVisible()
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
await expect(panel.root).toBeVisible()
|
||||
})
|
||||
|
||||
@@ -47,6 +47,7 @@ test.describe('Queue overlay', () => {
|
||||
|
||||
test('Toggle button opens expanded queue overlay', async ({ comfyPage }) => {
|
||||
const toggle = comfyPage.page.getByTestId(TestIds.queue.overlayToggle)
|
||||
await expect(toggle).toBeVisible()
|
||||
await toggle.click()
|
||||
|
||||
// Expanded overlay should show job items
|
||||
@@ -55,6 +56,7 @@ test.describe('Queue overlay', () => {
|
||||
|
||||
test('Overlay shows filter tabs (All, Completed)', async ({ comfyPage }) => {
|
||||
const toggle = comfyPage.page.getByTestId(TestIds.queue.overlayToggle)
|
||||
await expect(toggle).toBeVisible()
|
||||
await toggle.click()
|
||||
|
||||
await expect(
|
||||
@@ -69,6 +71,7 @@ test.describe('Queue overlay', () => {
|
||||
comfyPage
|
||||
}) => {
|
||||
const toggle = comfyPage.page.getByTestId(TestIds.queue.overlayToggle)
|
||||
await expect(toggle).toBeVisible()
|
||||
await toggle.click()
|
||||
|
||||
await expect(comfyPage.page.locator('[data-job-id]').first()).toBeVisible()
|
||||
@@ -80,6 +83,7 @@ test.describe('Queue overlay', () => {
|
||||
|
||||
test('Completed filter shows only completed jobs', async ({ comfyPage }) => {
|
||||
const toggle = comfyPage.page.getByTestId(TestIds.queue.overlayToggle)
|
||||
await expect(toggle).toBeVisible()
|
||||
await toggle.click()
|
||||
|
||||
await expect(comfyPage.page.locator('[data-job-id]').first()).toBeVisible()
|
||||
@@ -98,6 +102,7 @@ test.describe('Queue overlay', () => {
|
||||
|
||||
test('Toggling overlay again closes it', async ({ comfyPage }) => {
|
||||
const toggle = comfyPage.page.getByTestId(TestIds.queue.overlayToggle)
|
||||
await expect(toggle).toBeVisible()
|
||||
await toggle.click()
|
||||
|
||||
await expect(comfyPage.page.locator('[data-job-id]').first()).toBeVisible()
|
||||
|
||||
@@ -334,6 +334,7 @@ test.describe('Release Notifications', () => {
|
||||
)
|
||||
|
||||
// Reopen help center
|
||||
await expect(helpCenterButton).toBeVisible()
|
||||
await helpCenterButton.click()
|
||||
|
||||
// Verify "What's New?" section is now hidden
|
||||
|
||||
@@ -13,9 +13,11 @@ test.describe('Remote COMBO Widget', { tag: '@widget' }, () => {
|
||||
) => {
|
||||
const tab = comfyPage.menu.nodeLibraryTab
|
||||
await tab.open()
|
||||
await expect(tab.getFolder('DevTools')).toBeVisible()
|
||||
await tab.getFolder('DevTools').click()
|
||||
const nodeEntry = tab.getNode(nodeName).first()
|
||||
for (let i = 0; i < count; i++) {
|
||||
await expect(nodeEntry).toBeVisible()
|
||||
await nodeEntry.click()
|
||||
await comfyPage.nextFrame()
|
||||
}
|
||||
|
||||
@@ -23,13 +23,16 @@ test.describe('Reroute Node', { tag: ['@screenshot', '@node'] }, () => {
|
||||
// Insert the workflow
|
||||
const workflowsTab = comfyPage.menu.workflowsTab
|
||||
await workflowsTab.open()
|
||||
await expect(workflowsTab.getPersistedItem(workflowName)).toBeVisible()
|
||||
await workflowsTab.getPersistedItem(workflowName).click({ button: 'right' })
|
||||
const insertButton = comfyPage.page.locator('.p-contextmenu-item-link', {
|
||||
hasText: 'Insert'
|
||||
})
|
||||
await expect(insertButton).toBeVisible()
|
||||
await insertButton.click()
|
||||
|
||||
// Close the sidebar tab
|
||||
await expect(workflowsTab.tabButton).toBeVisible()
|
||||
await workflowsTab.tabButton.click()
|
||||
await workflowsTab.root.waitFor({ state: 'hidden' })
|
||||
await comfyPage.setFocusMode(true)
|
||||
|
||||
@@ -15,6 +15,7 @@ test.describe('MediaLightbox', { tag: ['@slow'] }, () => {
|
||||
'widgets/save_image_and_animated_webp'
|
||||
)
|
||||
await comfyPage.vueNodes.waitForNodes()
|
||||
await expect(comfyPage.runButton).toBeVisible()
|
||||
await comfyPage.runButton.click()
|
||||
|
||||
// Wait for SaveImage node to produce output
|
||||
@@ -24,6 +25,7 @@ test.describe('MediaLightbox', { tag: ['@slow'] }, () => {
|
||||
})
|
||||
|
||||
// Open Assets sidebar tab and wait for it to load
|
||||
await expect(comfyPage.page.locator('.assets-tab-button')).toBeVisible()
|
||||
await comfyPage.page.locator('.assets-tab-button').click()
|
||||
await comfyPage.page
|
||||
.locator('.sidebar-content-container')
|
||||
@@ -39,6 +41,7 @@ test.describe('MediaLightbox', { tag: ['@slow'] }, () => {
|
||||
|
||||
// Hover to reveal zoom button, then click it
|
||||
await assetCard.hover()
|
||||
await expect(assetCard.getByLabel('Zoom in')).toBeVisible()
|
||||
await assetCard.getByLabel('Zoom in').click()
|
||||
|
||||
const { root } = comfyPage.mediaLightbox
|
||||
@@ -62,6 +65,7 @@ test.describe('MediaLightbox', { tag: ['@slow'] }, () => {
|
||||
test('closes gallery when clicking close button', async ({ comfyPage }) => {
|
||||
await runAndOpenGallery(comfyPage)
|
||||
|
||||
await expect(comfyPage.mediaLightbox.closeButton).toBeVisible()
|
||||
await comfyPage.mediaLightbox.closeButton.click()
|
||||
await expect(comfyPage.mediaLightbox.root).not.toBeVisible()
|
||||
})
|
||||
|
||||
@@ -15,10 +15,13 @@ test.describe(
|
||||
test('Can add node', async ({ comfyPage }) => {
|
||||
await comfyPage.canvasOps.rightClick()
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('right-click-menu.png')
|
||||
await expect(comfyPage.page.getByText('Add Node')).toBeVisible()
|
||||
await comfyPage.page.getByText('Add Node').click()
|
||||
await comfyPage.nextFrame()
|
||||
await expect(comfyPage.page.getByText('loaders')).toBeVisible()
|
||||
await comfyPage.page.getByText('loaders').click()
|
||||
await comfyPage.nextFrame()
|
||||
await expect(comfyPage.page.getByText('Load VAE')).toBeVisible()
|
||||
await comfyPage.page.getByText('Load VAE').click()
|
||||
await comfyPage.nextFrame()
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('add-node-node-added.png')
|
||||
@@ -27,6 +30,9 @@ test.describe(
|
||||
test('Can add group', async ({ comfyPage }) => {
|
||||
await comfyPage.canvasOps.rightClick()
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('right-click-menu.png')
|
||||
await expect(
|
||||
comfyPage.page.getByText('Add Group', { exact: true })
|
||||
).toBeVisible()
|
||||
await comfyPage.page.getByText('Add Group', { exact: true }).click()
|
||||
await comfyPage.nextFrame()
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
@@ -62,6 +68,7 @@ test.describe('Node Right Click Menu', { tag: ['@screenshot', '@ui'] }, () => {
|
||||
await comfyPage.page.mouse.move(10, 10)
|
||||
await comfyPage.nextFrame()
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('right-click-node.png')
|
||||
await expect(comfyPage.page.getByText('Properties Panel')).toBeVisible()
|
||||
await comfyPage.page.getByText('Properties Panel').click()
|
||||
await comfyPage.nextFrame()
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
@@ -77,6 +84,7 @@ test.describe('Node Right Click Menu', { tag: ['@screenshot', '@ui'] }, () => {
|
||||
await comfyPage.page.mouse.move(10, 10)
|
||||
await comfyPage.nextFrame()
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('right-click-node.png')
|
||||
await expect(comfyPage.page.getByText('Collapse')).toBeVisible()
|
||||
await comfyPage.page.getByText('Collapse').click()
|
||||
await comfyPage.nextFrame()
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
@@ -100,6 +108,7 @@ test.describe('Node Right Click Menu', { tag: ['@screenshot', '@ui'] }, () => {
|
||||
})
|
||||
await comfyPage.page.mouse.move(10, 10)
|
||||
await comfyPage.nextFrame()
|
||||
await expect(comfyPage.page.getByText('Collapse')).toBeVisible()
|
||||
await comfyPage.page.getByText('Collapse').click()
|
||||
await comfyPage.nextFrame()
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
@@ -115,6 +124,7 @@ test.describe('Node Right Click Menu', { tag: ['@screenshot', '@ui'] }, () => {
|
||||
await comfyPage.page.mouse.move(10, 10)
|
||||
await comfyPage.nextFrame()
|
||||
await expect(comfyPage.canvas).toHaveScreenshot('right-click-node.png')
|
||||
await expect(comfyPage.page.getByText('Bypass')).toBeVisible()
|
||||
await comfyPage.page.getByText('Bypass').click()
|
||||
await comfyPage.nextFrame()
|
||||
await expect(comfyPage.canvas).toHaveScreenshot(
|
||||
@@ -226,6 +236,7 @@ test.describe('Node Right Click Menu', { tag: ['@screenshot', '@ui'] }, () => {
|
||||
const cloneItem = comfyPage.page.locator(
|
||||
'.litemenu-entry:has-text("Clone")'
|
||||
)
|
||||
await expect(cloneItem).toBeVisible()
|
||||
await cloneItem.click()
|
||||
await expect(cloneItem).toHaveCount(0)
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -12,6 +12,7 @@ test.describe('Right Side Panel Tabs', { tag: '@ui' }, () => {
|
||||
test('Properties panel opens with workflow overview', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await expect(comfyPage.actionbar.propertiesButton).toBeVisible()
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
const { propertiesPanel } = comfyPage.menu
|
||||
|
||||
@@ -22,6 +23,7 @@ test.describe('Right Side Panel Tabs', { tag: '@ui' }, () => {
|
||||
test('Properties panel shows node details on selection', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await expect(comfyPage.actionbar.propertiesButton).toBeVisible()
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
const { propertiesPanel } = comfyPage.menu
|
||||
|
||||
@@ -31,6 +33,7 @@ test.describe('Right Side Panel Tabs', { tag: '@ui' }, () => {
|
||||
})
|
||||
|
||||
test('Node title input is editable', async ({ comfyPage }) => {
|
||||
await expect(comfyPage.actionbar.propertiesButton).toBeVisible()
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
const { propertiesPanel } = comfyPage.menu
|
||||
|
||||
@@ -38,6 +41,7 @@ test.describe('Right Side Panel Tabs', { tag: '@ui' }, () => {
|
||||
await expect(propertiesPanel.panelTitle).toContainText('KSampler')
|
||||
|
||||
// Click on the title to enter edit mode
|
||||
await expect(propertiesPanel.panelTitle).toBeVisible()
|
||||
await propertiesPanel.panelTitle.click()
|
||||
const titleInput = propertiesPanel.root.getByTestId(TestIds.node.titleInput)
|
||||
await expect(titleInput).toBeVisible()
|
||||
@@ -49,6 +53,7 @@ test.describe('Right Side Panel Tabs', { tag: '@ui' }, () => {
|
||||
})
|
||||
|
||||
test('Search box filters properties', async ({ comfyPage }) => {
|
||||
await expect(comfyPage.actionbar.propertiesButton).toBeVisible()
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
const { propertiesPanel } = comfyPage.menu
|
||||
|
||||
@@ -77,6 +82,7 @@ test.describe('Right Side Panel Tabs', { tag: '@ui' }, () => {
|
||||
})
|
||||
|
||||
test('Expand all / Collapse all toggles sections', async ({ comfyPage }) => {
|
||||
await expect(comfyPage.actionbar.propertiesButton).toBeVisible()
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
const { propertiesPanel } = comfyPage.menu
|
||||
|
||||
@@ -105,6 +111,7 @@ test.describe('Right Side Panel Tabs', { tag: '@ui' }, () => {
|
||||
})
|
||||
|
||||
test('Properties panel can be closed', async ({ comfyPage }) => {
|
||||
await expect(comfyPage.actionbar.propertiesButton).toBeVisible()
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
const { propertiesPanel } = comfyPage.menu
|
||||
|
||||
@@ -113,6 +120,7 @@ test.describe('Right Side Panel Tabs', { tag: '@ui' }, () => {
|
||||
// The actionbar toggle button hides when the panel is open,
|
||||
// so use the close button inside the panel itself
|
||||
const closeButton = comfyPage.page.getByLabel('Toggle properties panel')
|
||||
await expect(closeButton).toBeVisible()
|
||||
await closeButton.click()
|
||||
await expect(propertiesPanel.root).toBeHidden()
|
||||
})
|
||||
|
||||
@@ -19,6 +19,7 @@ test.describe(
|
||||
)
|
||||
await comfyPage.vueNodes.waitForNodes()
|
||||
|
||||
await expect(comfyPage.runButton).toBeVisible()
|
||||
await comfyPage.runButton.click()
|
||||
|
||||
const saveImageNode = comfyPage.vueNodes.getNodeByTitle('Save Image')
|
||||
|
||||
@@ -45,6 +45,7 @@ test.describe('@canvas Selection Rectangle', () => {
|
||||
})
|
||||
|
||||
test('Single click selects one node', async ({ comfyPage }) => {
|
||||
await expect(comfyPage.page.getByText('Load Checkpoint')).toBeVisible()
|
||||
await comfyPage.page.getByText('Load Checkpoint').click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -52,10 +53,12 @@ test.describe('@canvas Selection Rectangle', () => {
|
||||
})
|
||||
|
||||
test('Ctrl+click adds to selection', async ({ comfyPage }) => {
|
||||
await expect(comfyPage.page.getByText('Load Checkpoint')).toBeVisible()
|
||||
await comfyPage.page.getByText('Load Checkpoint').click()
|
||||
await comfyPage.nextFrame()
|
||||
await expect.poll(() => comfyPage.vueNodes.getSelectedNodeCount()).toBe(1)
|
||||
|
||||
await expect(comfyPage.page.getByText('Empty Latent Image')).toBeVisible()
|
||||
await comfyPage.page.getByText('Empty Latent Image').click({
|
||||
modifiers: ['Control']
|
||||
})
|
||||
@@ -66,6 +69,7 @@ test.describe('@canvas Selection Rectangle', () => {
|
||||
test('Selected nodes have visual indicator', async ({ comfyPage }) => {
|
||||
const checkpointNode = comfyPage.vueNodes.getNodeByTitle('Load Checkpoint')
|
||||
|
||||
await expect(comfyPage.page.getByText('Load Checkpoint')).toBeVisible()
|
||||
await comfyPage.page.getByText('Load Checkpoint').click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
|
||||
@@ -159,6 +159,7 @@ test.describe('Selection Toolbox', { tag: ['@screenshot', '@ui'] }, () => {
|
||||
const blueColorOption = colorPickerGroup.getByTestId(
|
||||
TestIds.selectionToolbox.colorBlue
|
||||
)
|
||||
await expect(blueColorOption).toBeVisible()
|
||||
await blueColorOption.click()
|
||||
|
||||
// Dropdown should close after selection
|
||||
@@ -188,10 +189,12 @@ test.describe('Selection Toolbox', { tag: ['@screenshot', '@ui'] }, () => {
|
||||
await expect(colorPickerButton).not.toHaveAttribute('color')
|
||||
|
||||
// Click color picker and select a color
|
||||
await expect(colorPickerButton).toBeVisible()
|
||||
await colorPickerButton.click()
|
||||
const redColorOption = getColorPickerGroup(comfyPage).getByTestId(
|
||||
TestIds.selectionToolbox.colorRed
|
||||
)
|
||||
await expect(redColorOption).toBeVisible()
|
||||
await redColorOption.click()
|
||||
|
||||
// Button should now show the selected color
|
||||
@@ -203,6 +206,7 @@ test.describe('Selection Toolbox', { tag: ['@screenshot', '@ui'] }, () => {
|
||||
}) => {
|
||||
// Select first node and color it
|
||||
await comfyPage.nodeOps.selectNodes(['KSampler'])
|
||||
await expect(getColorPickerButton(comfyPage)).toBeVisible()
|
||||
await getColorPickerButton(comfyPage).click()
|
||||
await getColorPickerGroup(comfyPage)
|
||||
.getByTestId(TestIds.selectionToolbox.colorBlue)
|
||||
@@ -211,6 +215,7 @@ test.describe('Selection Toolbox', { tag: ['@screenshot', '@ui'] }, () => {
|
||||
|
||||
// Select second node and color it differently
|
||||
await comfyPage.nodeOps.selectNodes(['CLIP Text Encode (Prompt)'])
|
||||
await expect(getColorPickerButton(comfyPage)).toBeVisible()
|
||||
await getColorPickerButton(comfyPage).click()
|
||||
await getColorPickerGroup(comfyPage)
|
||||
.getByTestId(TestIds.selectionToolbox.colorRed)
|
||||
@@ -232,6 +237,7 @@ test.describe('Selection Toolbox', { tag: ['@screenshot', '@ui'] }, () => {
|
||||
}) => {
|
||||
// First color a node
|
||||
await comfyPage.nodeOps.selectNodes(['KSampler'])
|
||||
await expect(getColorPickerButton(comfyPage)).toBeVisible()
|
||||
await getColorPickerButton(comfyPage).click()
|
||||
await getColorPickerGroup(comfyPage)
|
||||
.getByTestId(TestIds.selectionToolbox.colorBlue)
|
||||
@@ -253,6 +259,7 @@ test.describe('Selection Toolbox', { tag: ['@screenshot', '@ui'] }, () => {
|
||||
}) => {
|
||||
// Select a node and color it
|
||||
await comfyPage.nodeOps.selectNodes(['KSampler'])
|
||||
await expect(getColorPickerButton(comfyPage)).toBeVisible()
|
||||
await getColorPickerButton(comfyPage).click()
|
||||
await getColorPickerGroup(comfyPage)
|
||||
.getByTestId(TestIds.selectionToolbox.colorBlue)
|
||||
|
||||
@@ -103,6 +103,9 @@ test.describe(
|
||||
).toBeVisible({
|
||||
timeout: 5000
|
||||
})
|
||||
await expect(
|
||||
comfyPage.page.getByText('Box', { exact: true })
|
||||
).toBeVisible()
|
||||
await comfyPage.page.getByText('Box', { exact: true }).click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -122,9 +125,13 @@ test.describe(
|
||||
)
|
||||
|
||||
await openMoreOptions(comfyPage)
|
||||
await expect(
|
||||
comfyPage.page.getByText('Color', { exact: true })
|
||||
).toBeVisible()
|
||||
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()
|
||||
|
||||
|
||||
@@ -241,6 +241,7 @@ test.describe('Assets sidebar - view mode toggle', () => {
|
||||
|
||||
// Open settings menu and select list view
|
||||
await tab.openSettingsMenu()
|
||||
await expect(tab.listViewOption).toBeVisible()
|
||||
await tab.listViewOption.click()
|
||||
|
||||
// List view items should now be visible
|
||||
@@ -254,10 +255,12 @@ test.describe('Assets sidebar - view mode toggle', () => {
|
||||
|
||||
// Switch to list view
|
||||
await tab.openSettingsMenu()
|
||||
await expect(tab.listViewOption).toBeVisible()
|
||||
await tab.listViewOption.click()
|
||||
await expect(tab.listViewItems.first()).toBeVisible({ timeout: 5000 })
|
||||
|
||||
// Switch back to grid view (settings popover is still open)
|
||||
await expect(tab.gridViewOption).toBeVisible()
|
||||
await tab.gridViewOption.click()
|
||||
await tab.waitForAssets()
|
||||
|
||||
@@ -355,6 +358,7 @@ test.describe('Assets sidebar - selection', () => {
|
||||
await tab.waitForAssets()
|
||||
|
||||
// Click first asset card
|
||||
await expect(tab.assetCards.first()).toBeVisible()
|
||||
await tab.assetCards.first().click()
|
||||
|
||||
// Should have data-selected="true"
|
||||
@@ -371,10 +375,12 @@ test.describe('Assets sidebar - selection', () => {
|
||||
expect(cardCount).toBeGreaterThanOrEqual(2)
|
||||
|
||||
// Click first card
|
||||
await expect(cards.first()).toBeVisible()
|
||||
await cards.first().click()
|
||||
await expect(tab.selectedCards).toHaveCount(1)
|
||||
|
||||
// Ctrl+click second card
|
||||
await expect(cards.nth(1)).toBeVisible()
|
||||
await cards.nth(1).click({ modifiers: ['ControlOrMeta'] })
|
||||
await expect(tab.selectedCards).toHaveCount(2)
|
||||
})
|
||||
@@ -387,6 +393,7 @@ test.describe('Assets sidebar - selection', () => {
|
||||
await tab.waitForAssets()
|
||||
|
||||
// Select an asset
|
||||
await expect(tab.assetCards.first()).toBeVisible()
|
||||
await tab.assetCards.first().click()
|
||||
|
||||
// Footer should show selection count
|
||||
@@ -399,6 +406,7 @@ test.describe('Assets sidebar - selection', () => {
|
||||
await tab.waitForAssets()
|
||||
|
||||
// Select an asset
|
||||
await expect(tab.assetCards.first()).toBeVisible()
|
||||
await tab.assetCards.first().click()
|
||||
await expect(tab.selectedCards).toHaveCount(1)
|
||||
|
||||
@@ -417,6 +425,7 @@ test.describe('Assets sidebar - selection', () => {
|
||||
await tab.waitForAssets()
|
||||
|
||||
// Select an asset
|
||||
await expect(tab.assetCards.first()).toBeVisible()
|
||||
await tab.assetCards.first().click()
|
||||
await expect(tab.selectedCards).toHaveCount(1)
|
||||
|
||||
@@ -451,6 +460,7 @@ test.describe('Assets sidebar - context menu', () => {
|
||||
await tab.waitForAssets()
|
||||
|
||||
// Right-click first asset
|
||||
await expect(tab.assetCards.first()).toBeVisible()
|
||||
await tab.assetCards.first().click({ button: 'right' })
|
||||
|
||||
// Context menu should appear with standard items
|
||||
@@ -465,6 +475,7 @@ test.describe('Assets sidebar - context menu', () => {
|
||||
await tab.open()
|
||||
await tab.waitForAssets()
|
||||
|
||||
await expect(tab.assetCards.first()).toBeVisible()
|
||||
await tab.assetCards.first().click({ button: 'right' })
|
||||
await comfyPage.page
|
||||
.locator('.p-contextmenu')
|
||||
@@ -480,6 +491,7 @@ test.describe('Assets sidebar - context menu', () => {
|
||||
await tab.open()
|
||||
await tab.waitForAssets()
|
||||
|
||||
await expect(tab.assetCards.first()).toBeVisible()
|
||||
await tab.assetCards.first().click({ button: 'right' })
|
||||
await comfyPage.page
|
||||
.locator('.p-contextmenu')
|
||||
@@ -495,6 +507,7 @@ test.describe('Assets sidebar - context menu', () => {
|
||||
await tab.open()
|
||||
await tab.waitForAssets()
|
||||
|
||||
await expect(tab.assetCards.first()).toBeVisible()
|
||||
await tab.assetCards.first().click({ button: 'right' })
|
||||
await comfyPage.page
|
||||
.locator('.p-contextmenu')
|
||||
@@ -510,6 +523,7 @@ test.describe('Assets sidebar - context menu', () => {
|
||||
await tab.open()
|
||||
await tab.waitForAssets()
|
||||
|
||||
await expect(tab.assetCards.first()).toBeVisible()
|
||||
await tab.assetCards.first().click({ button: 'right' })
|
||||
await comfyPage.page
|
||||
.locator('.p-contextmenu')
|
||||
@@ -525,6 +539,7 @@ test.describe('Assets sidebar - context menu', () => {
|
||||
await tab.open()
|
||||
await tab.waitForAssets()
|
||||
|
||||
await expect(tab.assetCards.first()).toBeVisible()
|
||||
await tab.assetCards.first().click({ button: 'right' })
|
||||
|
||||
const contextMenu = comfyPage.page.locator('.p-contextmenu')
|
||||
@@ -553,8 +568,10 @@ test.describe('Assets sidebar - context menu', () => {
|
||||
// Multi-select: use keyboard.down/up so useKeyModifier('Control') detects
|
||||
// the modifier — click({ modifiers }) only sets the mouse event flag and
|
||||
// does not fire a keydown event that VueUse tracks.
|
||||
await expect(cards.first()).toBeVisible()
|
||||
await cards.first().click()
|
||||
await comfyPage.page.keyboard.down('Control')
|
||||
await expect(cards.nth(1)).toBeVisible()
|
||||
await cards.nth(1).click()
|
||||
await comfyPage.page.keyboard.up('Control')
|
||||
|
||||
@@ -599,6 +616,7 @@ test.describe('Assets sidebar - bulk actions', () => {
|
||||
await tab.open()
|
||||
await tab.waitForAssets()
|
||||
|
||||
await expect(tab.assetCards.first()).toBeVisible()
|
||||
await tab.assetCards.first().click()
|
||||
|
||||
// Download button in footer should be visible
|
||||
@@ -612,6 +630,7 @@ test.describe('Assets sidebar - bulk actions', () => {
|
||||
await tab.open()
|
||||
await tab.waitForAssets()
|
||||
|
||||
await expect(tab.assetCards.first()).toBeVisible()
|
||||
await tab.assetCards.first().click()
|
||||
|
||||
// Delete button in footer should be visible
|
||||
@@ -628,7 +647,9 @@ test.describe('Assets sidebar - bulk actions', () => {
|
||||
const cardCount = await cards.count()
|
||||
expect(cardCount).toBeGreaterThanOrEqual(2)
|
||||
|
||||
await expect(cards.first()).toBeVisible()
|
||||
await cards.first().click()
|
||||
await expect(cards.nth(1)).toBeVisible()
|
||||
await cards.nth(1).click({ modifiers: ['ControlOrMeta'] })
|
||||
|
||||
// Selection count should show the count
|
||||
@@ -723,7 +744,9 @@ test.describe('Assets sidebar - delete confirmation', () => {
|
||||
await tab.open()
|
||||
await tab.waitForAssets()
|
||||
|
||||
await expect(tab.assetCards.first()).toBeVisible()
|
||||
await tab.assetCards.first().click({ button: 'right' })
|
||||
await expect(tab.contextMenuItem('Delete')).toBeVisible()
|
||||
await tab.contextMenuItem('Delete').click()
|
||||
|
||||
const dialog = comfyPage.confirmDialog.root
|
||||
@@ -743,12 +766,15 @@ test.describe('Assets sidebar - delete confirmation', () => {
|
||||
|
||||
const initialCount = await tab.assetCards.count()
|
||||
|
||||
await expect(tab.assetCards.first()).toBeVisible()
|
||||
await tab.assetCards.first().click({ button: 'right' })
|
||||
await expect(tab.contextMenuItem('Delete')).toBeVisible()
|
||||
await tab.contextMenuItem('Delete').click()
|
||||
|
||||
const dialog = comfyPage.confirmDialog.root
|
||||
await expect(dialog).toBeVisible()
|
||||
|
||||
await expect(comfyPage.confirmDialog.delete).toBeVisible()
|
||||
await comfyPage.confirmDialog.delete.click()
|
||||
|
||||
await expect(dialog).not.toBeVisible()
|
||||
@@ -767,12 +793,15 @@ test.describe('Assets sidebar - delete confirmation', () => {
|
||||
|
||||
const initialCount = await tab.assetCards.count()
|
||||
|
||||
await expect(tab.assetCards.first()).toBeVisible()
|
||||
await tab.assetCards.first().click({ button: 'right' })
|
||||
await expect(tab.contextMenuItem('Delete')).toBeVisible()
|
||||
await tab.contextMenuItem('Delete').click()
|
||||
|
||||
const dialog = comfyPage.confirmDialog.root
|
||||
await expect(dialog).toBeVisible()
|
||||
|
||||
await expect(comfyPage.confirmDialog.reject).toBeVisible()
|
||||
await comfyPage.confirmDialog.reject.click()
|
||||
|
||||
await expect(dialog).not.toBeVisible()
|
||||
|
||||
@@ -73,6 +73,7 @@ test.describe('Model library sidebar - folders', () => {
|
||||
await tab.open()
|
||||
|
||||
// Click the folder to expand it
|
||||
await expect(tab.getFolderByLabel('checkpoints')).toBeVisible()
|
||||
await tab.getFolderByLabel('checkpoints').click()
|
||||
|
||||
// Models should appear as leaf nodes
|
||||
@@ -89,6 +90,7 @@ test.describe('Model library sidebar - folders', () => {
|
||||
const tab = comfyPage.menu.modelLibraryTab
|
||||
await tab.open()
|
||||
|
||||
await expect(tab.getFolderByLabel('loras')).toBeVisible()
|
||||
await tab.getFolderByLabel('loras').click()
|
||||
|
||||
await expect(tab.getLeafByLabel('detail_tweaker_xl')).toBeVisible({
|
||||
@@ -191,6 +193,7 @@ test.describe('Model library sidebar - refresh', () => {
|
||||
(req) => req.url().endsWith('/experiment/models'),
|
||||
{ timeout: 5000 }
|
||||
)
|
||||
await expect(tab.refreshButton).toBeVisible()
|
||||
await tab.refreshButton.click()
|
||||
await refreshRequest
|
||||
|
||||
@@ -214,6 +217,7 @@ test.describe('Model library sidebar - refresh', () => {
|
||||
{ timeout: 5000 }
|
||||
)
|
||||
|
||||
await expect(tab.loadAllFoldersButton).toBeVisible()
|
||||
await tab.loadAllFoldersButton.click()
|
||||
await folderRequest
|
||||
})
|
||||
|
||||
@@ -54,6 +54,7 @@ test.describe('Node library sidebar', () => {
|
||||
|
||||
test('Node preview and drag to canvas', async ({ comfyPage }) => {
|
||||
const tab = comfyPage.menu.nodeLibraryTab
|
||||
await expect(tab.getFolder('sampling')).toBeVisible()
|
||||
await tab.getFolder('sampling').click()
|
||||
|
||||
// Hover over a node to display the preview
|
||||
@@ -91,9 +92,13 @@ test.describe('Node library sidebar', () => {
|
||||
|
||||
test('Bookmark node', async ({ comfyPage }) => {
|
||||
const tab = comfyPage.menu.nodeLibraryTab
|
||||
await expect(tab.getFolder('sampling')).toBeVisible()
|
||||
await tab.getFolder('sampling').click()
|
||||
|
||||
// Bookmark the node
|
||||
await expect(
|
||||
tab.getNode('KSampler (Advanced)').locator('.bookmark-button')
|
||||
).toBeVisible()
|
||||
await tab.getNode('KSampler (Advanced)').locator('.bookmark-button').click()
|
||||
|
||||
// Verify the bookmark is added to the bookmarks tab
|
||||
@@ -124,6 +129,7 @@ test.describe('Node library sidebar', () => {
|
||||
|
||||
test('Can add new bookmark folder', async ({ comfyPage }) => {
|
||||
const tab = comfyPage.menu.nodeLibraryTab
|
||||
await expect(tab.newFolderButton).toBeVisible()
|
||||
await tab.newFolderButton.click()
|
||||
const textInput = comfyPage.page.locator('.editable-text input')
|
||||
await textInput.waitFor({ state: 'visible' })
|
||||
@@ -138,7 +144,11 @@ test.describe('Node library sidebar', () => {
|
||||
const tab = comfyPage.menu.nodeLibraryTab
|
||||
await expect(tab.getFolder('foo')).toBeVisible()
|
||||
|
||||
await expect(tab.getFolder('foo')).toBeVisible()
|
||||
await tab.getFolder('foo').click({ button: 'right' })
|
||||
await expect(
|
||||
comfyPage.page.getByRole('menuitem', { name: 'New Folder' })
|
||||
).toBeVisible()
|
||||
await comfyPage.page.getByRole('menuitem', { name: 'New Folder' }).click()
|
||||
const textInput = comfyPage.page.locator('.editable-text input')
|
||||
await textInput.waitFor({ state: 'visible' })
|
||||
@@ -154,7 +164,9 @@ test.describe('Node library sidebar', () => {
|
||||
const tab = comfyPage.menu.nodeLibraryTab
|
||||
await expect(tab.getFolder('foo')).toBeVisible()
|
||||
|
||||
await expect(tab.getFolder('foo')).toBeVisible()
|
||||
await tab.getFolder('foo').click({ button: 'right' })
|
||||
await expect(comfyPage.page.getByLabel('Delete')).toBeVisible()
|
||||
await comfyPage.page.getByLabel('Delete').click()
|
||||
|
||||
await expectBookmarks(comfyPage, [])
|
||||
@@ -165,6 +177,7 @@ test.describe('Node library sidebar', () => {
|
||||
const tab = comfyPage.menu.nodeLibraryTab
|
||||
await expect(tab.getFolder('foo')).toBeVisible()
|
||||
|
||||
await expect(tab.getFolder('foo')).toBeVisible()
|
||||
await tab.getFolder('foo').click({ button: 'right' })
|
||||
await comfyPage.page
|
||||
.locator('.p-contextmenu-item-label:has-text("Rename")')
|
||||
@@ -180,6 +193,7 @@ test.describe('Node library sidebar', () => {
|
||||
await comfyPage.settings.setSetting(bookmarksSettingId, ['foo/'])
|
||||
const tab = comfyPage.menu.nodeLibraryTab
|
||||
await expect(tab.getFolder('foo')).toBeVisible()
|
||||
await expect(tab.getFolder('sampling')).toBeVisible()
|
||||
await tab.getFolder('sampling').click()
|
||||
await comfyPage.page.dragAndDrop(
|
||||
tab.nodeSelector('KSampler (Advanced)'),
|
||||
@@ -192,7 +206,11 @@ test.describe('Node library sidebar', () => {
|
||||
comfyPage
|
||||
}) => {
|
||||
const tab = comfyPage.menu.nodeLibraryTab
|
||||
await expect(tab.getFolder('sampling')).toBeVisible()
|
||||
await tab.getFolder('sampling').click()
|
||||
await expect(
|
||||
tab.getNode('KSampler (Advanced)').locator('.bookmark-button')
|
||||
).toBeVisible()
|
||||
await tab.getNode('KSampler (Advanced)').locator('.bookmark-button').click()
|
||||
await expectBookmarks(comfyPage, ['KSamplerAdvanced'])
|
||||
})
|
||||
@@ -203,6 +221,9 @@ test.describe('Node library sidebar', () => {
|
||||
])
|
||||
const tab = comfyPage.menu.nodeLibraryTab
|
||||
await expect(tab.getNode('KSampler (Advanced)')).toHaveCount(1)
|
||||
await expect(
|
||||
tab.getNode('KSampler (Advanced)').locator('.bookmark-button')
|
||||
).toBeVisible()
|
||||
await tab.getNode('KSampler (Advanced)').locator('.bookmark-button').click()
|
||||
await expectBookmarks(comfyPage, [])
|
||||
})
|
||||
@@ -212,6 +233,7 @@ test.describe('Node library sidebar', () => {
|
||||
'KSamplerAdvanced'
|
||||
])
|
||||
const tab = comfyPage.menu.nodeLibraryTab
|
||||
await expect(tab.getFolder('sampling')).toBeVisible()
|
||||
await tab.getFolder('sampling').click()
|
||||
await expect(tab.getNode('KSampler (Advanced)')).toHaveCount(2)
|
||||
await tab
|
||||
@@ -224,20 +246,25 @@ test.describe('Node library sidebar', () => {
|
||||
await comfyPage.settings.setSetting(bookmarksSettingId, ['foo/'])
|
||||
const tab = comfyPage.menu.nodeLibraryTab
|
||||
await expect(tab.getFolder('foo')).toBeVisible()
|
||||
await expect(tab.getFolder('foo')).toBeVisible()
|
||||
await tab.getFolder('foo').click({ button: 'right' })
|
||||
await expect(comfyPage.page.getByLabel('Customize')).toBeVisible()
|
||||
await comfyPage.page.getByLabel('Customize').click()
|
||||
const dialog = comfyPage.page.getByRole('dialog', {
|
||||
name: 'Customize Folder'
|
||||
})
|
||||
// Select Folder icon (2nd button in Icon group)
|
||||
const iconGroup = dialog.getByText('Icon').locator('..').getByRole('group')
|
||||
await expect(iconGroup.getByRole('button').nth(1)).toBeVisible()
|
||||
await iconGroup.getByRole('button').nth(1).click()
|
||||
// Select Blue color (2nd button in Color group)
|
||||
const colorGroup = dialog
|
||||
.getByText('Color')
|
||||
.locator('..')
|
||||
.getByRole('group')
|
||||
await expect(colorGroup.getByRole('button').nth(1)).toBeVisible()
|
||||
await colorGroup.getByRole('button').nth(1).click()
|
||||
await expect(dialog.getByRole('button', { name: 'Confirm' })).toBeVisible()
|
||||
await dialog.getByRole('button', { name: 'Confirm' }).click()
|
||||
await comfyPage.nextFrame()
|
||||
await expectBookmarkCustomization(comfyPage, {
|
||||
@@ -252,14 +279,18 @@ test.describe('Node library sidebar', () => {
|
||||
await comfyPage.settings.setSetting(bookmarksSettingId, ['foo/'])
|
||||
const tab = comfyPage.menu.nodeLibraryTab
|
||||
await expect(tab.getFolder('foo')).toBeVisible()
|
||||
await expect(tab.getFolder('foo')).toBeVisible()
|
||||
await tab.getFolder('foo').click({ button: 'right' })
|
||||
await expect(comfyPage.page.getByLabel('Customize')).toBeVisible()
|
||||
await comfyPage.page.getByLabel('Customize').click()
|
||||
const dialog = comfyPage.page.getByRole('dialog', {
|
||||
name: 'Customize Folder'
|
||||
})
|
||||
// Select Folder icon (2nd button in Icon group)
|
||||
const iconGroup = dialog.getByText('Icon').locator('..').getByRole('group')
|
||||
await expect(iconGroup.getByRole('button').nth(1)).toBeVisible()
|
||||
await iconGroup.getByRole('button').nth(1).click()
|
||||
await expect(dialog.getByRole('button', { name: 'Confirm' })).toBeVisible()
|
||||
await dialog.getByRole('button', { name: 'Confirm' }).click()
|
||||
await comfyPage.nextFrame()
|
||||
await expectBookmarkCustomization(comfyPage, {
|
||||
@@ -276,13 +307,16 @@ test.describe('Node library sidebar', () => {
|
||||
await comfyPage.settings.setSetting(bookmarksSettingId, ['foo/'])
|
||||
const tab = comfyPage.menu.nodeLibraryTab
|
||||
await expect(tab.getFolder('foo')).toBeVisible()
|
||||
await expect(tab.getFolder('foo')).toBeVisible()
|
||||
await tab.getFolder('foo').click({ button: 'right' })
|
||||
await expect(comfyPage.page.getByLabel('Customize')).toBeVisible()
|
||||
await comfyPage.page.getByLabel('Customize').click()
|
||||
|
||||
// Click a color option multiple times
|
||||
const customColorOption = comfyPage.page.locator(
|
||||
'.p-togglebutton-content > .pi-palette'
|
||||
)
|
||||
await expect(customColorOption).toBeVisible()
|
||||
await customColorOption.click()
|
||||
await customColorOption.click()
|
||||
|
||||
@@ -291,6 +325,9 @@ test.describe('Node library sidebar', () => {
|
||||
.getByLabel('Customize Folder')
|
||||
.getByRole('textbox')
|
||||
.click()
|
||||
await expect(
|
||||
comfyPage.page.locator('.p-colorpicker-color-background')
|
||||
).toBeVisible()
|
||||
await comfyPage.page.locator('.p-colorpicker-color-background').click()
|
||||
|
||||
// Finalize the customization
|
||||
@@ -299,7 +336,9 @@ test.describe('Node library sidebar', () => {
|
||||
})
|
||||
// Select Folder icon (2nd button in Icon group)
|
||||
const iconGroup = dialog.getByText('Icon').locator('..').getByRole('group')
|
||||
await expect(iconGroup.getByRole('button').nth(1)).toBeVisible()
|
||||
await iconGroup.getByRole('button').nth(1).click()
|
||||
await expect(dialog.getByRole('button', { name: 'Confirm' })).toBeVisible()
|
||||
await dialog.getByRole('button', { name: 'Confirm' }).click()
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -327,6 +366,7 @@ test.describe('Node library sidebar', () => {
|
||||
})
|
||||
const tab = comfyPage.menu.nodeLibraryTab
|
||||
await expect(tab.getFolder('foo')).toBeVisible()
|
||||
await expect(tab.getFolder('foo')).toBeVisible()
|
||||
await tab.getFolder('foo').click({ button: 'right' })
|
||||
await comfyPage.page
|
||||
.locator('.p-contextmenu-item-label:has-text("Rename")')
|
||||
@@ -365,7 +405,9 @@ test.describe('Node library sidebar', () => {
|
||||
})
|
||||
const tab = comfyPage.menu.nodeLibraryTab
|
||||
await expect(tab.getFolder('foo')).toBeVisible()
|
||||
await expect(tab.getFolder('foo')).toBeVisible()
|
||||
await tab.getFolder('foo').click({ button: 'right' })
|
||||
await expect(comfyPage.page.getByLabel('Delete')).toBeVisible()
|
||||
await comfyPage.page.getByLabel('Delete').click()
|
||||
await comfyPage.nextFrame()
|
||||
await expectBookmarks(comfyPage, [])
|
||||
|
||||
@@ -16,10 +16,12 @@ test.describe('Node library sidebar V2', () => {
|
||||
|
||||
await expect(tab.allTab).toHaveAttribute('aria-selected', 'true')
|
||||
|
||||
await expect(tab.blueprintsTab).toBeVisible()
|
||||
await tab.blueprintsTab.click()
|
||||
await expect(tab.blueprintsTab).toHaveAttribute('aria-selected', 'true')
|
||||
await expect(tab.allTab).toHaveAttribute('aria-selected', 'false')
|
||||
|
||||
await expect(tab.allTab).toBeVisible()
|
||||
await tab.allTab.click()
|
||||
await expect(tab.allTab).toHaveAttribute('aria-selected', 'true')
|
||||
await expect(tab.blueprintsTab).toHaveAttribute('aria-selected', 'false')
|
||||
@@ -114,6 +116,7 @@ test.describe('Node library sidebar V2', () => {
|
||||
test('Sort dropdown shows sorting options', async ({ comfyPage }) => {
|
||||
const tab = comfyPage.menu.nodeLibraryTabV2
|
||||
|
||||
await expect(tab.sortButton).toBeVisible()
|
||||
await tab.sortButton.click()
|
||||
|
||||
// Reka UI DropdownMenuRadioItem renders with role="menuitemradio"
|
||||
|
||||
@@ -89,6 +89,7 @@ test.describe('Workflows sidebar', () => {
|
||||
.poll(() => comfyPage.nodeOps.getNodeCount())
|
||||
.toEqual(originalNodeCount + 1)
|
||||
|
||||
await expect(tab.getPersistedItem('workflow1')).toBeVisible()
|
||||
await tab.getPersistedItem('workflow1').click()
|
||||
await expect.poll(() => comfyPage.nodeOps.getNodeCount()).toEqual(1)
|
||||
})
|
||||
@@ -105,8 +106,10 @@ test.describe('Workflows sidebar', () => {
|
||||
const tab = comfyPage.menu.workflowsTab
|
||||
await tab.open()
|
||||
// Switch to the parent folder
|
||||
await expect(tab.getPersistedItem('foo')).toBeVisible()
|
||||
await tab.getPersistedItem('foo').click()
|
||||
// Switch to the nested workflow
|
||||
await expect(tab.getPersistedItem('bar')).toBeVisible()
|
||||
await tab.getPersistedItem('bar').click()
|
||||
|
||||
const openedWorkflow = tab.getOpenedItem('foo/bar')
|
||||
@@ -247,6 +250,9 @@ test.describe('Workflows sidebar', () => {
|
||||
await expect(errorOverlay).toBeVisible()
|
||||
|
||||
// Dismiss the error overlay
|
||||
await expect(
|
||||
errorOverlay.getByTestId(TestIds.dialogs.errorOverlayDismiss)
|
||||
).toBeVisible()
|
||||
await errorOverlay.getByTestId(TestIds.dialogs.errorOverlayDismiss).click()
|
||||
await expect(errorOverlay).not.toBeVisible()
|
||||
|
||||
@@ -270,6 +276,7 @@ test.describe('Workflows sidebar', () => {
|
||||
const closeButton = comfyPage.page.locator(
|
||||
'.comfyui-workflows-open .close-workflow-button'
|
||||
)
|
||||
await expect(closeButton).toBeVisible()
|
||||
await closeButton.click()
|
||||
await expect
|
||||
.poll(() => comfyPage.menu.workflowsTab.getOpenedWorkflowNames(), {
|
||||
@@ -294,6 +301,7 @@ test.describe('Workflows sidebar', () => {
|
||||
await topbar.saveWorkflow(filename)
|
||||
expect(await workflowsTab.getOpenedWorkflowNames()).toEqual([filename])
|
||||
|
||||
await expect(workflowsTab.getOpenedItem(filename)).toBeVisible()
|
||||
await workflowsTab.getOpenedItem(filename).click({ button: 'right' })
|
||||
await comfyPage.nextFrame()
|
||||
await comfyPage.contextMenu.clickMenuItem('Delete')
|
||||
@@ -312,6 +320,7 @@ test.describe('Workflows sidebar', () => {
|
||||
await topbar.saveWorkflow(filename)
|
||||
expect(await workflowsTab.getOpenedWorkflowNames()).toEqual([filename])
|
||||
|
||||
await expect(workflowsTab.getOpenedItem(filename)).toBeVisible()
|
||||
await workflowsTab.getOpenedItem(filename).click({ button: 'right' })
|
||||
await comfyPage.contextMenu.clickMenuItem('Delete')
|
||||
await comfyPage.nextFrame()
|
||||
@@ -332,6 +341,7 @@ test.describe('Workflows sidebar', () => {
|
||||
const { workflowsTab } = comfyPage.menu
|
||||
await workflowsTab.open()
|
||||
|
||||
await expect(workflowsTab.getPersistedItem('workflow1')).toBeVisible()
|
||||
await workflowsTab.getPersistedItem('workflow1').click({ button: 'right' })
|
||||
await comfyPage.contextMenu.clickMenuItem('Duplicate')
|
||||
await expect
|
||||
|
||||
@@ -9,6 +9,7 @@ import { TestIds } from '@e2e/fixtures/selectors'
|
||||
async function ensurePropertiesPanel(comfyPage: ComfyPage) {
|
||||
const panel = comfyPage.menu.propertiesPanel.root
|
||||
if (!(await panel.isVisible())) {
|
||||
await expect(comfyPage.actionbar.propertiesButton).toBeVisible()
|
||||
await comfyPage.actionbar.propertiesButton.click()
|
||||
}
|
||||
await expect(panel).toBeVisible()
|
||||
@@ -135,6 +136,7 @@ test.describe(
|
||||
TestIds.subgraphEditor.widgetActionsMenuButton
|
||||
)
|
||||
await expect(moreButtons.first()).toBeVisible()
|
||||
await expect(moreButtons.first()).toBeVisible()
|
||||
await moreButtons.first().click()
|
||||
|
||||
const menu = comfyPage.page.getByTestId(TestIds.menu.moreMenuContent)
|
||||
|
||||
@@ -45,6 +45,7 @@ test.describe('Toast Notifications', { tag: '@ui' }, () => {
|
||||
await expect(comfyPage.toast.visibleToasts.first()).toBeVisible()
|
||||
|
||||
const closeButton = comfyPage.page.locator('.p-toast-close-button').first()
|
||||
await expect(closeButton).toBeVisible()
|
||||
await closeButton.click()
|
||||
|
||||
await expect(comfyPage.toast.visibleToasts).toHaveCount(0)
|
||||
|
||||
@@ -23,6 +23,7 @@ test.describe('Workflow tabs', () => {
|
||||
|
||||
expect(await topbar.getTabNames()).toHaveLength(1)
|
||||
|
||||
await expect(topbar.newWorkflowButton).toBeVisible()
|
||||
await topbar.newWorkflowButton.click()
|
||||
await expect.poll(() => topbar.getTabNames()).toHaveLength(2)
|
||||
|
||||
@@ -33,12 +34,14 @@ test.describe('Workflow tabs', () => {
|
||||
test('Switching tabs changes active workflow', async ({ comfyPage }) => {
|
||||
const topbar = comfyPage.menu.topbar
|
||||
|
||||
await expect(topbar.newWorkflowButton).toBeVisible()
|
||||
await topbar.newWorkflowButton.click()
|
||||
await expect.poll(() => topbar.getTabNames()).toHaveLength(2)
|
||||
|
||||
const activeNameBefore = await topbar.getActiveTabName()
|
||||
expect(activeNameBefore).toContain('Unsaved Workflow (2)')
|
||||
|
||||
await expect(topbar.getTab(0)).toBeVisible()
|
||||
await topbar.getTab(0).click()
|
||||
await expect
|
||||
.poll(() => topbar.getActiveTabName())
|
||||
@@ -51,6 +54,7 @@ test.describe('Workflow tabs', () => {
|
||||
test('Closing a tab removes it', async ({ comfyPage }) => {
|
||||
const topbar = comfyPage.menu.topbar
|
||||
|
||||
await expect(topbar.newWorkflowButton).toBeVisible()
|
||||
await topbar.newWorkflowButton.click()
|
||||
await expect.poll(() => topbar.getTabNames()).toHaveLength(2)
|
||||
|
||||
@@ -64,6 +68,7 @@ test.describe('Workflow tabs', () => {
|
||||
test('Right-clicking a tab shows context menu', async ({ comfyPage }) => {
|
||||
const topbar = comfyPage.menu.topbar
|
||||
|
||||
await expect(topbar.getTab(0)).toBeVisible()
|
||||
await topbar.getTab(0).click({ button: 'right' })
|
||||
|
||||
// Reka UI ContextMenuContent gets data-state="open" when active
|
||||
@@ -85,9 +90,11 @@ test.describe('Workflow tabs', () => {
|
||||
}) => {
|
||||
const topbar = comfyPage.menu.topbar
|
||||
|
||||
await expect(topbar.newWorkflowButton).toBeVisible()
|
||||
await topbar.newWorkflowButton.click()
|
||||
await expect.poll(() => topbar.getTabNames()).toHaveLength(2)
|
||||
|
||||
await expect(topbar.getTab(1)).toBeVisible()
|
||||
await topbar.getTab(1).click({ button: 'right' })
|
||||
const contextMenu = comfyPage.page.locator(
|
||||
'[role="menu"][data-state="open"]'
|
||||
@@ -136,12 +143,14 @@ test.describe('Workflow tabs', () => {
|
||||
const topbar = comfyPage.menu.topbar
|
||||
|
||||
// Create 2 additional tabs (3 total)
|
||||
await expect(topbar.newWorkflowButton).toBeVisible()
|
||||
await topbar.newWorkflowButton.click()
|
||||
await expect.poll(() => topbar.getTabNames()).toHaveLength(2)
|
||||
await topbar.newWorkflowButton.click()
|
||||
await expect.poll(() => topbar.getTabNames()).toHaveLength(3)
|
||||
|
||||
// Switch to first tab
|
||||
await expect(topbar.getTab(0)).toBeVisible()
|
||||
await topbar.getTab(0).click()
|
||||
await expect
|
||||
.poll(() => topbar.getActiveTabName())
|
||||
|
||||
@@ -91,6 +91,7 @@ test.describe('Settings Search functionality', { tag: '@settings' }, () => {
|
||||
const categoryCount = await dialog.categories.count()
|
||||
|
||||
if (categoryCount > 1) {
|
||||
await expect(dialog.categories.nth(1)).toBeVisible()
|
||||
await dialog.categories.nth(1).click()
|
||||
|
||||
await expect(dialog.categories.nth(1)).toHaveClass(
|
||||
|
||||
@@ -28,6 +28,7 @@ test.describe('User Select View', { tag: '@settings' }, () => {
|
||||
await page.goto(userSelectPage.url)
|
||||
await expect(page).toHaveURL(userSelectPage.selectionUrl)
|
||||
await userSelectPage.newUserInput.fill(randomUser)
|
||||
await expect(userSelectPage.nextButton).toBeVisible()
|
||||
await userSelectPage.nextButton.click()
|
||||
await expect(page).toHaveURL(userSelectPage.url)
|
||||
})
|
||||
@@ -35,8 +36,13 @@ test.describe('User Select View', { tag: '@settings' }, () => {
|
||||
test('Can choose existing user', async ({ userSelectPage, page }) => {
|
||||
await page.goto(userSelectPage.url)
|
||||
await expect(page).toHaveURL(userSelectPage.selectionUrl)
|
||||
await expect(userSelectPage.existingUserSelect).toBeVisible()
|
||||
await userSelectPage.existingUserSelect.click()
|
||||
await expect(
|
||||
page.locator('.p-select-list .p-select-option').first()
|
||||
).toBeVisible()
|
||||
await page.locator('.p-select-list .p-select-option').first().click()
|
||||
await expect(userSelectPage.nextButton).toBeVisible()
|
||||
await userSelectPage.nextButton.click()
|
||||
await expect(page).toHaveURL(userSelectPage.url)
|
||||
})
|
||||
|
||||
@@ -108,6 +108,7 @@ test.describe('Version Mismatch Warnings', { tag: '@slow' }, () => {
|
||||
})
|
||||
await warningToast.waitFor({ state: 'visible' })
|
||||
const dismissButton = warningToast.getByRole('button', { name: 'Close' })
|
||||
await expect(dismissButton).toBeVisible()
|
||||
await dismissButton.click()
|
||||
|
||||
// Wait for the dismissed state to be persisted
|
||||
|
||||
@@ -120,7 +120,9 @@ test.describe('Vue Node Groups', { tag: '@screenshot' }, () => {
|
||||
})
|
||||
|
||||
test('should allow creating groups with hotkey', async ({ comfyPage }) => {
|
||||
await expect(comfyPage.page.getByText('Load Checkpoint')).toBeVisible()
|
||||
await comfyPage.page.getByText('Load Checkpoint').click()
|
||||
await expect(comfyPage.page.getByText('KSampler')).toBeVisible()
|
||||
await comfyPage.page.getByText('KSampler').click({ modifiers: ['Control'] })
|
||||
await comfyPage.page.keyboard.press(CREATE_GROUP_HOTKEY)
|
||||
await comfyPage.nextFrame()
|
||||
|
||||
@@ -31,6 +31,7 @@ async function openMultiNodeContextMenu(
|
||||
|
||||
for (const title of titles) {
|
||||
const fixture = await comfyPage.vueNodes.getFixtureByTitle(title)
|
||||
await expect(fixture.header).toBeVisible()
|
||||
await fixture.header.click({ modifiers: ['ControlOrMeta'] })
|
||||
}
|
||||
await comfyPage.nextFrame()
|
||||
@@ -356,6 +357,7 @@ test.describe('Vue Node Context Menu', () => {
|
||||
await comfyPage.nodeOps.fillPromptDialog('TestBlueprint')
|
||||
|
||||
// Open node library sidebar and search for the blueprint
|
||||
await expect(comfyPage.menu.nodeLibraryTab.tabButton).toBeVisible()
|
||||
await comfyPage.menu.nodeLibraryTab.tabButton.click()
|
||||
const searchBox = comfyPage.page.getByRole('combobox', {
|
||||
name: 'Search'
|
||||
|
||||
@@ -44,6 +44,7 @@ test.describe('Vue Nodes Image Preview', () => {
|
||||
const { imagePreview } = await loadImageOnNode(comfyPage)
|
||||
|
||||
await imagePreview.getByRole('region').hover()
|
||||
await expect(comfyPage.page.getByLabel('Edit or mask image')).toBeVisible()
|
||||
await comfyPage.page.getByLabel('Edit or mask image').click()
|
||||
|
||||
await expect(comfyPage.page.locator('.mask-editor-dialog')).toBeVisible()
|
||||
@@ -56,6 +57,7 @@ test.describe('Vue Nodes Image Preview', () => {
|
||||
const nodeHeader = comfyPage.vueNodes
|
||||
.getNodeLocator(nodeId)
|
||||
.locator('.lg-node-header')
|
||||
await expect(nodeHeader).toBeVisible()
|
||||
await nodeHeader.click({ button: 'right' })
|
||||
|
||||
const contextMenu = comfyPage.page.locator('.p-contextmenu')
|
||||
|
||||
@@ -91,6 +91,7 @@ test.describe('Vue Nodes - Delete Key Interaction', () => {
|
||||
.first()
|
||||
|
||||
// Click on text widget to focus it
|
||||
await expect(textWidget).toBeVisible()
|
||||
await textWidget.click()
|
||||
await textWidget.fill('test text')
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ test.describe('Vue Node Resizing', () => {
|
||||
if (!initialBox) throw new Error('Node bounding box not found')
|
||||
|
||||
// Select the node first (this was causing the bug)
|
||||
await expect(node.header).toBeVisible()
|
||||
await node.header.click()
|
||||
|
||||
// Get position after selection
|
||||
|
||||
@@ -23,14 +23,17 @@ test.describe('Vue Node Selection', () => {
|
||||
test(`should allow selecting multiple nodes with ${name}+click`, async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await expect(comfyPage.page.getByText('Load Checkpoint')).toBeVisible()
|
||||
await comfyPage.page.getByText('Load Checkpoint').click()
|
||||
await expect.poll(() => comfyPage.vueNodes.getSelectedNodeCount()).toBe(1)
|
||||
|
||||
await expect(comfyPage.page.getByText('Empty Latent Image')).toBeVisible()
|
||||
await comfyPage.page.getByText('Empty Latent Image').click({
|
||||
modifiers: [modifier]
|
||||
})
|
||||
await expect.poll(() => comfyPage.vueNodes.getSelectedNodeCount()).toBe(2)
|
||||
|
||||
await expect(comfyPage.page.getByText('KSampler')).toBeVisible()
|
||||
await comfyPage.page.getByText('KSampler').click({
|
||||
modifiers: [modifier]
|
||||
})
|
||||
@@ -40,9 +43,11 @@ test.describe('Vue Node Selection', () => {
|
||||
test(`should allow de-selecting nodes with ${name}+click`, async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await expect(comfyPage.page.getByText('Load Checkpoint')).toBeVisible()
|
||||
await comfyPage.page.getByText('Load Checkpoint').click()
|
||||
await expect.poll(() => comfyPage.vueNodes.getSelectedNodeCount()).toBe(1)
|
||||
|
||||
await expect(comfyPage.page.getByText('Load Checkpoint')).toBeVisible()
|
||||
await comfyPage.page.getByText('Load Checkpoint').click({
|
||||
modifiers: [modifier]
|
||||
})
|
||||
@@ -68,6 +73,7 @@ test.describe('Vue Node Selection', () => {
|
||||
const PIN_INDICATOR = '[data-testid="node-pin-indicator"]'
|
||||
|
||||
const checkpointNodeHeader = comfyPage.page.getByText('Load Checkpoint')
|
||||
await expect(checkpointNodeHeader).toBeVisible()
|
||||
await checkpointNodeHeader.click()
|
||||
|
||||
await comfyPage.page.keyboard.press(PIN_HOTKEY)
|
||||
|
||||
@@ -19,6 +19,7 @@ test.describe('Vue Node Bypass', () => {
|
||||
'should allow toggling bypass on a selected node with hotkey',
|
||||
{ tag: '@screenshot' },
|
||||
async ({ comfyPage }) => {
|
||||
await expect(comfyPage.page.getByText('Load Checkpoint')).toBeVisible()
|
||||
await comfyPage.page.getByText('Load Checkpoint').click()
|
||||
await comfyPage.page.keyboard.press(BYPASS_HOTKEY)
|
||||
|
||||
@@ -40,7 +41,9 @@ test.describe('Vue Node Bypass', () => {
|
||||
test('should allow toggling bypass on multiple selected nodes with hotkey', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await expect(comfyPage.page.getByText('Load Checkpoint')).toBeVisible()
|
||||
await comfyPage.page.getByText('Load Checkpoint').click()
|
||||
await expect(comfyPage.page.getByText('KSampler')).toBeVisible()
|
||||
await comfyPage.page.getByText('KSampler').click({ modifiers: ['Control'] })
|
||||
|
||||
const checkpointNode = comfyPage.page
|
||||
|
||||
@@ -18,11 +18,13 @@ test.describe('Vue Node Custom Colors', { tag: '@screenshot' }, () => {
|
||||
const loadCheckpointNode = comfyPage.page.locator('[data-node-id]').filter({
|
||||
hasText: 'Load Checkpoint'
|
||||
})
|
||||
await expect(loadCheckpointNode.getByText('Load Checkpoint')).toBeVisible()
|
||||
await loadCheckpointNode.getByText('Load Checkpoint').click()
|
||||
|
||||
const colorPickerButton = comfyPage.page.getByTestId(
|
||||
TestIds.selectionToolbox.colorPickerButton
|
||||
)
|
||||
await expect(colorPickerButton).toBeVisible()
|
||||
await colorPickerButton.click()
|
||||
|
||||
const colorPickerGroup = comfyPage.page.getByRole('group').filter({
|
||||
|
||||
@@ -30,6 +30,7 @@ test.describe('Vue Node Error', () => {
|
||||
}) => {
|
||||
await comfyPage.setup()
|
||||
await comfyPage.workflow.loadWorkflow('nodes/execution_error')
|
||||
await expect(comfyPage.runButton).toBeVisible()
|
||||
await comfyPage.runButton.click()
|
||||
|
||||
const raiseErrorNode = comfyPage.page
|
||||
|
||||
@@ -16,6 +16,7 @@ test.describe('Vue Node Mute', () => {
|
||||
'should allow toggling mute on a selected node with hotkey',
|
||||
{ tag: '@screenshot' },
|
||||
async ({ comfyPage }) => {
|
||||
await expect(comfyPage.page.getByText('Load Checkpoint')).toBeVisible()
|
||||
await comfyPage.page.getByText('Load Checkpoint').click()
|
||||
await comfyPage.page.keyboard.press(MUTE_HOTKEY)
|
||||
|
||||
@@ -34,7 +35,9 @@ test.describe('Vue Node Mute', () => {
|
||||
test('should allow toggling mute on multiple selected nodes with hotkey', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await expect(comfyPage.page.getByText('Load Checkpoint')).toBeVisible()
|
||||
await comfyPage.page.getByText('Load Checkpoint').click()
|
||||
await expect(comfyPage.page.getByText('KSampler')).toBeVisible()
|
||||
await comfyPage.page.getByText('KSampler').click({ modifiers: ['Control'] })
|
||||
|
||||
const checkpointNode = comfyPage.vueNodes.getNodeByTitle('Load Checkpoint')
|
||||
|
||||
@@ -15,6 +15,7 @@ test.describe('Vue Node Pin', () => {
|
||||
test('should allow toggling pin on a selected node with hotkey', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await expect(comfyPage.page.getByText('Load Checkpoint')).toBeVisible()
|
||||
await comfyPage.page.getByText('Load Checkpoint').click()
|
||||
await comfyPage.page.keyboard.press(PIN_HOTKEY)
|
||||
|
||||
@@ -30,7 +31,9 @@ test.describe('Vue Node Pin', () => {
|
||||
test('should allow toggling pin on multiple selected nodes with hotkey', async ({
|
||||
comfyPage
|
||||
}) => {
|
||||
await expect(comfyPage.page.getByText('Load Checkpoint')).toBeVisible()
|
||||
await comfyPage.page.getByText('Load Checkpoint').click()
|
||||
await expect(comfyPage.page.getByText('KSampler')).toBeVisible()
|
||||
await comfyPage.page.getByText('KSampler').click({ modifiers: ['Control'] })
|
||||
|
||||
const checkpointNode = comfyPage.vueNodes.getNodeByTitle('Load Checkpoint')
|
||||
@@ -49,6 +52,7 @@ test.describe('Vue Node Pin', () => {
|
||||
|
||||
test('should not allow dragging pinned nodes', async ({ comfyPage }) => {
|
||||
const checkpointNodeHeader = comfyPage.page.getByText('Load Checkpoint')
|
||||
await expect(checkpointNodeHeader).toBeVisible()
|
||||
await checkpointNodeHeader.click()
|
||||
await comfyPage.page.keyboard.press(PIN_HOTKEY)
|
||||
|
||||
@@ -67,6 +71,7 @@ test.describe('Vue Node Pin', () => {
|
||||
expect(headerPosAfterDrag).toEqual(headerPos)
|
||||
|
||||
// Unpin the node with the hotkey
|
||||
await expect(checkpointNodeHeader).toBeVisible()
|
||||
await checkpointNodeHeader.click()
|
||||
await comfyPage.page.keyboard.press(PIN_HOTKEY)
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ test.describe('Advanced Widget Visibility', () => {
|
||||
await expect(widgets).toHaveCount(2)
|
||||
|
||||
// Click the toggle button to show advanced widgets
|
||||
await expect(node.getByText('Show advanced inputs')).toBeVisible()
|
||||
await node.getByText('Show advanced inputs').click()
|
||||
|
||||
await expect(widgets).toHaveCount(4)
|
||||
@@ -73,6 +74,7 @@ test.describe('Advanced Widget Visibility', () => {
|
||||
await expect(node.getByText('Hide advanced inputs')).toBeVisible()
|
||||
|
||||
// Click again to hide
|
||||
await expect(node.getByText('Hide advanced inputs')).toBeVisible()
|
||||
await node.getByText('Hide advanced inputs').click()
|
||||
await expect(widgets).toHaveCount(2)
|
||||
})
|
||||
|
||||
@@ -40,9 +40,11 @@ test.describe('Vue Integer Widget', () => {
|
||||
await comfyPage.vueNodes.deleteSelected()
|
||||
|
||||
// Test widget works when unlinked
|
||||
await expect(controls.incrementButton).toBeVisible()
|
||||
await controls.incrementButton.click()
|
||||
await expect(controls.input).toHaveValue((initialValue + 1).toString())
|
||||
|
||||
await expect(controls.decrementButton).toBeVisible()
|
||||
await controls.decrementButton.click()
|
||||
await expect(controls.input).toHaveValue(initialValue.toString())
|
||||
})
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user