From 5b4e96f6c5963bc5c5428e13bc9d6dd3aad5ee70 Mon Sep 17 00:00:00 2001 From: Chenlei Hu Date: Tue, 23 Jul 2024 17:56:35 -0400 Subject: [PATCH] Test theme toggle feature (#212) * WIP * Add test on theme toggle * Add teardown logic * Cleanup menu setting --- browser_tests/ComfyPage.ts | 94 ++++++++++++++----- browser_tests/menu.spec.ts | 45 +++++++++ src/components/sidebar/SideBarIcon.vue | 5 + .../sidebar/SideBarThemeToggleIcon.vue | 1 + 4 files changed, 120 insertions(+), 25 deletions(-) create mode 100644 browser_tests/menu.spec.ts diff --git a/browser_tests/ComfyPage.ts b/browser_tests/ComfyPage.ts index 9542ce6e4..9fcd08893 100644 --- a/browser_tests/ComfyPage.ts +++ b/browser_tests/ComfyPage.ts @@ -34,6 +34,37 @@ class ComfyNodeSearchBox { } } +class ComfyMenu { + public readonly themeToggleButton: Locator; + + constructor(public readonly page: Page) { + this.themeToggleButton = page.locator(".comfy-vue-theme-toggle"); + } + + async toggleTheme() { + await this.themeToggleButton.click(); + await this.page.evaluate(() => { + return new Promise((resolve) => { + window["app"].ui.settings.addEventListener( + "Comfy.ColorPalette.change", + resolve, + { once: true } + ); + + setTimeout(resolve, 5000); + }); + }); + } + + async getThemeId() { + return await this.page.evaluate(async () => { + return await window["app"].ui.settings.getSettingValue( + "Comfy.ColorPalette" + ); + }); + } +} + export class ComfyPage { public readonly url: string; // All canvas position operations are based on default view of canvas. @@ -46,8 +77,9 @@ export class ComfyPage { // Inputs public readonly workflowUploadInput: Locator; - // Search box + // Components public readonly searchBox: ComfyNodeSearchBox; + public readonly menu: ComfyMenu; constructor(public readonly page: Page) { this.url = process.env.PLAYWRIGHT_TEST_URL || "http://localhost:8188"; @@ -56,6 +88,38 @@ export class ComfyPage { this.resetViewButton = page.getByRole("button", { name: "Reset View" }); this.workflowUploadInput = page.locator("#comfy-file-input"); this.searchBox = new ComfyNodeSearchBox(page); + this.menu = new ComfyMenu(page); + } + + async setup() { + await this.goto(); + // Unify font for consistent screenshots. + await this.page.addStyleTag({ + url: "https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap", + }); + await this.page.addStyleTag({ + url: "https://fonts.googleapis.com/css2?family=Noto+Color+Emoji&family=Roboto+Mono:ital,wght@0,100..700;1,100..700&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap", + }); + await this.page.addStyleTag({ + content: ` + * { + font-family: 'Roboto Mono', 'Noto Color Emoji'; + }`, + }); + await this.page.waitForFunction(() => document.fonts.ready); + await this.page.waitForFunction(() => window["app"] !== undefined); + await this.page.evaluate(() => { + window["app"]["canvas"].show_info = false; + }); + await this.nextFrame(); + // Reset view to force re-rendering of canvas. So that info fields like fps + // become hidden. + await this.resetView(); + } + + async realod() { + await this.page.reload({ timeout: 15000 }); + await this.setup(); } async goto() { @@ -76,7 +140,9 @@ export class ComfyPage { } async resetView() { - await this.resetViewButton.click(); + if (await this.resetViewButton.isVisible()) { + await this.resetViewButton.click(); + } // Avoid "Reset View" button highlight. await this.page.mouse.move(10, 10); await this.nextFrame(); @@ -323,29 +389,7 @@ export class ComfyPage { export const comfyPageFixture = base.extend<{ comfyPage: ComfyPage }>({ comfyPage: async ({ page }, use) => { const comfyPage = new ComfyPage(page); - await comfyPage.goto(); - // Unify font for consistent screenshots. - await page.addStyleTag({ - url: "https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap", - }); - await page.addStyleTag({ - url: "https://fonts.googleapis.com/css2?family=Noto+Color+Emoji&family=Roboto+Mono:ital,wght@0,100..700;1,100..700&family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&display=swap", - }); - await page.addStyleTag({ - content: ` - * { - font-family: 'Roboto Mono', 'Noto Color Emoji'; - }`, - }); - await page.waitForFunction(() => document.fonts.ready); - await page.waitForFunction(() => window["app"] !== undefined); - await page.evaluate(() => { - window["app"]["canvas"].show_info = false; - }); - await comfyPage.nextFrame(); - // Reset view to force re-rendering of canvas. So that info fields like fps - // become hidden. - await comfyPage.resetView(); + await comfyPage.setup(); await use(comfyPage); }, }); diff --git a/browser_tests/menu.spec.ts b/browser_tests/menu.spec.ts new file mode 100644 index 000000000..104e1ed0b --- /dev/null +++ b/browser_tests/menu.spec.ts @@ -0,0 +1,45 @@ +import { expect } from "@playwright/test"; +import { comfyPageFixture as test } from "./ComfyPage"; + +test.describe("Menu", () => { + test.beforeEach(async ({ comfyPage }) => { + await comfyPage.page.evaluate(async () => { + await window["app"].ui.settings.setSettingValueAsync( + "Comfy.UseNewMenu", + "Top" + ); + }); + }); + + test.afterEach(async ({ comfyPage }) => { + const currentThemeId = await comfyPage.menu.getThemeId(); + if (currentThemeId !== "dark") { + await comfyPage.menu.toggleTheme(); + } + await comfyPage.page.evaluate(async () => { + await window["app"].ui.settings.setSettingValueAsync( + "Comfy.UseNewMenu", + "Disabled" + ); + }); + }); + + test("Toggle theme", async ({ comfyPage }) => { + test.setTimeout(30000); + + expect(await comfyPage.menu.getThemeId()).toBe("dark"); + + await comfyPage.menu.toggleTheme(); + + expect(await comfyPage.menu.getThemeId()).toBe("light"); + + // Theme id should persist after reload. + await comfyPage.page.reload(); + await comfyPage.setup(); + expect(await comfyPage.menu.getThemeId()).toBe("light"); + + await comfyPage.menu.toggleTheme(); + + expect(await comfyPage.menu.getThemeId()).toBe("dark"); + }); +}); diff --git a/src/components/sidebar/SideBarIcon.vue b/src/components/sidebar/SideBarIcon.vue index 463eebb38..4957ff766 100644 --- a/src/components/sidebar/SideBarIcon.vue +++ b/src/components/sidebar/SideBarIcon.vue @@ -1,6 +1,7 @@