diff --git a/browser_tests/fixtures/ComfyPage.ts b/browser_tests/fixtures/ComfyPage.ts index 00c9ca098..51bcf5ce1 100644 --- a/browser_tests/fixtures/ComfyPage.ts +++ b/browser_tests/fixtures/ComfyPage.ts @@ -133,6 +133,9 @@ export class ComfyPage { // Inputs public readonly workflowUploadInput: Locator + // Toasts + public readonly visibleToasts: Locator + // Components public readonly searchBox: ComfyNodeSearchBox public readonly menu: ComfyMenu @@ -159,6 +162,8 @@ export class ComfyPage { this.resetViewButton = page.getByRole('button', { name: 'Reset View' }) this.queueButton = page.getByRole('button', { name: 'Queue Prompt' }) this.workflowUploadInput = page.locator('#comfy-file-input') + this.visibleToasts = page.locator('.p-toast-message:visible') + this.searchBox = new ComfyNodeSearchBox(page) this.menu = new ComfyMenu(page) this.actionbar = new ComfyActionbar(page) @@ -397,6 +402,30 @@ export class ComfyPage { await this.nextFrame() } + async deleteWorkflow( + workflowName: string, + whenMissing: 'ignoreMissing' | 'throwIfMissing' = 'ignoreMissing' + ) { + // Open workflows tab + const { workflowsTab } = this.menu + await workflowsTab.open() + + // Action to take if workflow missing + if (whenMissing === 'ignoreMissing') { + const workflows = await workflowsTab.getTopLevelSavedWorkflowNames() + if (!workflows.includes(workflowName)) return + } + + // Delete workflow + await workflowsTab.getPersistedItem(workflowName).click({ button: 'right' }) + await this.clickContextMenuItem('Delete') + await this.confirmDialog.delete.click() + + // Clear toast & close tab + await this.closeToasts(1) + await workflowsTab.close() + } + async resetView() { if (await this.resetViewButton.isVisible()) { await this.resetViewButton.click() @@ -413,7 +442,20 @@ export class ComfyPage { } async getVisibleToastCount() { - return await this.page.locator('.p-toast-message:visible').count() + return await this.visibleToasts.count() + } + + async closeToasts(requireCount = 0) { + if (requireCount) await expect(this.visibleToasts).toHaveCount(requireCount) + + // Clear all toasts + const toastCloseButtons = await this.page + .locator('.p-toast-close-button') + .all() + for (const button of toastCloseButtons) { + await button.click() + } + await expect(this.visibleToasts).toHaveCount(0) } async clickTextEncodeNode1() { diff --git a/browser_tests/tests/interaction.spec.ts b/browser_tests/tests/interaction.spec.ts index fa907d738..552878a26 100644 --- a/browser_tests/tests/interaction.spec.ts +++ b/browser_tests/tests/interaction.spec.ts @@ -1,6 +1,6 @@ import { expect } from '@playwright/test' -import { comfyPageFixture as test } from '../fixtures/ComfyPage' +import { type ComfyPage, comfyPageFixture as test } from '../fixtures/ComfyPage' test.describe('Item Interaction', () => { test('Can select/delete all items', async ({ comfyPage }) => { @@ -689,3 +689,42 @@ test.describe('Load duplicate workflow', () => { expect(await comfyPage.getGraphNodesCount()).toBe(1) }) }) + +test.describe('Viewport settings', () => { + test.beforeEach(async ({ comfyPage }) => { + await comfyPage.setSetting('Comfy.UseNewMenu', 'Top') + await comfyPage.setSetting('Comfy.Workflow.WorkflowTabsPosition', 'Topbar') + + await comfyPage.setupWorkflowsDirectory({}) + }) + + test('Keeps viewport settings when changing tabs', async ({ + comfyPage, + comfyMouse + }) => { + // Screenshot the canvas element + await comfyPage.menu.topbar.saveWorkflow('Workflow A') + await expect(comfyPage.canvas).toHaveScreenshot('viewport-workflow-a.png') + + // Save workflow as a new file, then zoom out before screen shot + await comfyPage.menu.topbar.saveWorkflowAs('Workflow B') + await comfyMouse.move(comfyPage.emptySpace) + for (let i = 0; i < 4; i++) { + await comfyMouse.wheel(0, 60) + } + await expect(comfyPage.canvas).toHaveScreenshot('viewport-workflow-b.png') + + const tabA = comfyPage.menu.topbar.getWorkflowTab('Workflow A') + const tabB = comfyPage.menu.topbar.getWorkflowTab('Workflow B') + + // Go back to Workflow A + await tabA.click() + await comfyPage.nextFrame() + await expect(comfyPage.canvas).toHaveScreenshot('viewport-workflow-a.png') + + // And back to Workflow B + await tabB.click() + await comfyPage.nextFrame() + await expect(comfyPage.canvas).toHaveScreenshot('viewport-workflow-b.png') + }) +}) diff --git a/browser_tests/tests/interaction.spec.ts-snapshots/viewport-workflow-a-chromium-linux.png b/browser_tests/tests/interaction.spec.ts-snapshots/viewport-workflow-a-chromium-linux.png new file mode 100644 index 000000000..a6b932e14 Binary files /dev/null and b/browser_tests/tests/interaction.spec.ts-snapshots/viewport-workflow-a-chromium-linux.png differ diff --git a/browser_tests/tests/interaction.spec.ts-snapshots/viewport-workflow-b-chromium-linux.png b/browser_tests/tests/interaction.spec.ts-snapshots/viewport-workflow-b-chromium-linux.png new file mode 100644 index 000000000..2c7d67ed8 Binary files /dev/null and b/browser_tests/tests/interaction.spec.ts-snapshots/viewport-workflow-b-chromium-linux.png differ