diff --git a/browser_tests/fixtures/ComfyPage.ts b/browser_tests/fixtures/ComfyPage.ts index a8a4185ec..cb37200f7 100644 --- a/browser_tests/fixtures/ComfyPage.ts +++ b/browser_tests/fixtures/ComfyPage.ts @@ -12,6 +12,7 @@ import { ComfyTemplates } from '../helpers/templates' import { ComfyMouse } from './ComfyMouse' import { VueNodeHelpers } from './VueNodeHelpers' import { ComfyNodeSearchBox } from './components/ComfyNodeSearchBox' +import { ContextMenu } from './components/ContextMenu' import { SettingDialog } from './components/SettingDialog' import { NodeLibrarySidebarTab, @@ -184,6 +185,7 @@ export class ComfyPage { public readonly keyboard: KeyboardHelper public readonly clipboard: ClipboardHelper public readonly workflow: WorkflowHelper + public readonly contextMenu: ContextMenu /** Worker index to test user ID */ public readonly userIds: string[] = [] @@ -224,6 +226,7 @@ export class ComfyPage { this.keyboard = new KeyboardHelper(page, this.canvas) this.clipboard = new ClipboardHelper(page, this.canvas) this.workflow = new WorkflowHelper(this) + this.contextMenu = new ContextMenu(page) } convertLeafToContent(structure: FolderStructure): FolderStructure { @@ -736,17 +739,21 @@ export class ComfyPage { await this.nextFrame() } + /** + * @deprecated Use `comfyPage.contextMenu.clickMenuItem(name)` instead. + */ async clickContextMenuItem(name: string): Promise { - await this.page.getByRole('menuitem', { name }).click() + await this.contextMenu.clickMenuItem(name) await this.nextFrame() } /** + * @deprecated Use `comfyPage.contextMenu.clickLitegraphMenuItem(name)` instead. * Clicks on a litegraph context menu item (uses .litemenu-entry selector). * Use this for canvas/node context menus, not PrimeVue menus. */ async clickLitegraphContextMenuItem(name: string): Promise { - await this.page.locator(`.litemenu-entry:has-text("${name}")`).click() + await this.contextMenu.clickLitegraphMenuItem(name) await this.nextFrame() } @@ -828,6 +835,9 @@ export class ComfyPage { await this.nextFrame() } + /** + * @deprecated Use dialog-specific close methods instead (e.g., settingDialog.close()) + */ async closeDialog() { await this.page.locator('.p-dialog-close-button').click({ force: true }) await this.page.locator('.p-dialog').waitFor({ state: 'hidden' }) diff --git a/browser_tests/fixtures/components/BaseDialog.ts b/browser_tests/fixtures/components/BaseDialog.ts new file mode 100644 index 000000000..1fbcf899b --- /dev/null +++ b/browser_tests/fixtures/components/BaseDialog.ts @@ -0,0 +1,31 @@ +import type { Locator, Page } from '@playwright/test' + +export class BaseDialog { + readonly root: Locator + readonly closeButton: Locator + + constructor( + public readonly page: Page, + testId?: string + ) { + this.root = testId ? page.getByTestId(testId) : page.locator('.p-dialog') + this.closeButton = this.root.locator('.p-dialog-close-button') + } + + async isVisible(): Promise { + return this.root.isVisible() + } + + async waitForVisible(): Promise { + await this.root.waitFor({ state: 'visible' }) + } + + async waitForHidden(): Promise { + await this.root.waitFor({ state: 'hidden' }) + } + + async close(): Promise { + await this.closeButton.click({ force: true }) + await this.waitForHidden() + } +} diff --git a/browser_tests/fixtures/components/SettingDialog.ts b/browser_tests/fixtures/components/SettingDialog.ts index 5c6b72150..61c83e91e 100644 --- a/browser_tests/fixtures/components/SettingDialog.ts +++ b/browser_tests/fixtures/components/SettingDialog.ts @@ -2,20 +2,19 @@ import type { Page } from '@playwright/test' import type { ComfyPage } from '../ComfyPage' import { TestIds } from '../selectors' +import { BaseDialog } from './BaseDialog' -export class SettingDialog { +export class SettingDialog extends BaseDialog { constructor( - public readonly page: Page, + page: Page, public readonly comfyPage: ComfyPage - ) {} - - get root() { - return this.page.getByTestId(TestIds.dialogs.settings) + ) { + super(page, TestIds.dialogs.settings) } async open() { await this.comfyPage.executeCommand('Comfy.ShowSettingsDialog') - await this.root.waitFor({ state: 'visible' }) + await this.waitForVisible() } /**