V3 UI - Tabs & Menu rework (#4374)

Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
pythongosssss
2025-07-24 08:09:12 +01:00
committed by GitHub
parent 2338cbd4c9
commit 62f3ba0689
33 changed files with 1057 additions and 231 deletions

View File

@@ -168,7 +168,7 @@ export class ComfyPage {
this.menu = new ComfyMenu(page)
this.actionbar = new ComfyActionbar(page)
this.templates = new ComfyTemplates(page)
this.settingDialog = new SettingDialog(page)
this.settingDialog = new SettingDialog(page, this)
this.confirmDialog = new ConfirmDialog(page)
}

View File

@@ -1,15 +1,19 @@
import { Page } from '@playwright/test'
import { ComfyPage } from '../ComfyPage'
export class SettingDialog {
constructor(public readonly page: Page) {}
constructor(
public readonly page: Page,
public readonly comfyPage: ComfyPage
) {}
get root() {
return this.page.locator('div.settings-container')
}
async open() {
const button = this.page.locator('button.comfy-settings-btn:visible')
await button.click()
await this.comfyPage.executeCommand('Comfy.ShowSettingsDialog')
await this.page.waitForSelector('div.settings-container')
}

View File

@@ -15,10 +15,6 @@ export class Topbar {
.innerText()
}
async openSubmenuMobile() {
await this.page.locator('.p-menubar-mobile .p-menubar-button').click()
}
getMenuItem(itemLabel: string): Locator {
return this.page.locator(`.p-menubar-item-label:text-is("${itemLabel}")`)
}
@@ -68,31 +64,41 @@ export class Topbar {
await this.getSaveDialog().waitFor({ state: 'hidden', timeout: 500 })
}
async openTopbarMenu() {
await this.page.locator('.comfyui-logo-wrapper').click()
const menu = this.page.locator('.comfy-command-menu')
await menu.waitFor({ state: 'visible' })
return menu
}
async triggerTopbarCommand(path: string[]) {
if (path.length < 2) {
throw new Error('Path is too short')
}
const menu = await this.openTopbarMenu()
const tabName = path[0]
const topLevelMenu = this.page.locator(
`.top-menubar .p-menubar-item-label:text-is("${tabName}")`
const topLevelMenuItem = this.page.locator(
`.p-menubar-item-label:text-is("${tabName}")`
)
const topLevelMenu = menu
.locator('.p-tieredmenu-item')
.filter({ has: topLevelMenuItem })
await topLevelMenu.waitFor({ state: 'visible' })
await topLevelMenu.click()
await topLevelMenu.hover()
let currentMenu = topLevelMenu
for (let i = 1; i < path.length; i++) {
const commandName = path[i]
const menuItem = this.page
const menuItem = currentMenu
.locator(
`.top-menubar .p-menubar-submenu .p-menubar-item:has-text("${commandName}")`
`.p-tieredmenu-submenu .p-tieredmenu-item:has-text("${commandName}")`
)
.first()
await menuItem.waitFor({ state: 'visible' })
await menuItem.hover()
if (i === path.length - 1) {
await menuItem.click()
}
currentMenu = menuItem
}
await currentMenu.click()
}
}

View File

@@ -769,7 +769,8 @@ test.describe('Viewport settings', () => {
}) => {
// Screenshot the canvas element
await comfyPage.menu.topbar.saveWorkflow('Workflow A')
await expect(comfyPage.canvas).toHaveScreenshot('viewport-workflow-a.png')
await comfyPage.nextFrame()
const screenshotA = (await comfyPage.canvas.screenshot()).toString('base64')
// Save workflow as a new file, then zoom out before screen shot
await comfyPage.menu.topbar.saveWorkflowAs('Workflow B')
@@ -777,7 +778,12 @@ test.describe('Viewport settings', () => {
for (let i = 0; i < 4; i++) {
await comfyMouse.wheel(0, 60)
}
await expect(comfyPage.canvas).toHaveScreenshot('viewport-workflow-b.png')
await comfyPage.nextFrame()
const screenshotB = (await comfyPage.canvas.screenshot()).toString('base64')
// Ensure that the screenshots are different due to zoom level
expect(screenshotB).not.toBe(screenshotA)
const tabA = comfyPage.menu.topbar.getWorkflowTab('Workflow A')
const tabB = comfyPage.menu.topbar.getWorkflowTab('Workflow B')
@@ -785,11 +791,15 @@ test.describe('Viewport settings', () => {
// Go back to Workflow A
await tabA.click()
await comfyPage.nextFrame()
await expect(comfyPage.canvas).toHaveScreenshot('viewport-workflow-a.png')
expect((await comfyPage.canvas.screenshot()).toString('base64')).toBe(
screenshotA
)
// And back to Workflow B
await tabB.click()
await comfyPage.nextFrame()
await expect(comfyPage.canvas).toHaveScreenshot('viewport-workflow-b.png')
expect((await comfyPage.canvas.screenshot()).toString('base64')).toBe(
screenshotB
)
})
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

View File

@@ -63,7 +63,7 @@ test.describe('Menu', () => {
test('@mobile Items fully visible on mobile screen width', async ({
comfyPage
}) => {
await comfyPage.menu.topbar.openSubmenuMobile()
await comfyPage.menu.topbar.openTopbarMenu()
const topLevelMenuItem = comfyPage.page
.locator('a.p-menubar-item-link')
.first()
@@ -74,8 +74,9 @@ test.describe('Menu', () => {
})
test('Displays keybinding next to item', async ({ comfyPage }) => {
await comfyPage.menu.topbar.openTopbarMenu()
const workflowMenuItem = comfyPage.menu.topbar.getMenuItem('Workflow')
await workflowMenuItem.click()
await workflowMenuItem.hover()
const exportTag = comfyPage.page.locator('.keybinding-tag', {
hasText: 'Ctrl + s'
})