diff --git a/browser_tests/fixtures/ComfyPage.ts b/browser_tests/fixtures/ComfyPage.ts index 2d9028a35..b817b14f8 100644 --- a/browser_tests/fixtures/ComfyPage.ts +++ b/browser_tests/fixtures/ComfyPage.ts @@ -34,6 +34,7 @@ import { SubgraphHelper } from './helpers/SubgraphHelper' import { ToastHelper } from './helpers/ToastHelper' import { WorkflowHelper } from './helpers/WorkflowHelper' import type { NodeReference } from './utils/litegraphUtils' +import type { WorkspaceStore } from '../types/globals' dotenv.config() @@ -139,7 +140,9 @@ class ConfirmDialog { // Wait for workflow service to finish if it's busy await this.page.waitForFunction( - () => window.app?.extensionManager?.workflow?.isBusy === false, + () => + (window.app?.extensionManager as WorkspaceStore | undefined)?.workflow + ?.isBusy === false, undefined, { timeout: 3000 } ) @@ -387,7 +390,7 @@ export class ComfyPage { async setFocusMode(focusMode: boolean) { await this.page.evaluate((focusMode) => { - window.app!.extensionManager.focusMode = focusMode + ;(window.app!.extensionManager as WorkspaceStore).focusMode = focusMode }, focusMode) await this.nextFrame() } diff --git a/browser_tests/fixtures/components/SidebarTab.ts b/browser_tests/fixtures/components/SidebarTab.ts index 0c64f0fe0..20706bcba 100644 --- a/browser_tests/fixtures/components/SidebarTab.ts +++ b/browser_tests/fixtures/components/SidebarTab.ts @@ -1,5 +1,6 @@ import type { Locator, Page } from '@playwright/test' +import type { WorkspaceStore } from '../../types/globals' import { TestIds } from '../selectors' class SidebarTab { @@ -154,7 +155,9 @@ export class WorkflowsSidebarTab extends SidebarTab { // Wait for workflow service to finish renaming await this.page.waitForFunction( - () => !window.app?.extensionManager?.workflow?.isBusy, + () => + !(window.app?.extensionManager as WorkspaceStore | undefined)?.workflow + ?.isBusy, undefined, { timeout: 3000 } ) diff --git a/browser_tests/fixtures/components/Topbar.ts b/browser_tests/fixtures/components/Topbar.ts index e53bf4264..e91311c7b 100644 --- a/browser_tests/fixtures/components/Topbar.ts +++ b/browser_tests/fixtures/components/Topbar.ts @@ -1,5 +1,7 @@ import type { Locator, Page } from '@playwright/test' +import type { WorkspaceStore } from '../../types/globals' + export class Topbar { private readonly menuLocator: Locator private readonly menuTrigger: Locator @@ -85,7 +87,7 @@ export class Topbar { // Wait for workflow service to finish saving await this.page.waitForFunction( - () => !window.app!.extensionManager.workflow.isBusy, + () => !(window.app!.extensionManager as WorkspaceStore).workflow.isBusy, undefined, { timeout: 3000 } ) diff --git a/browser_tests/fixtures/helpers/WorkflowHelper.ts b/browser_tests/fixtures/helpers/WorkflowHelper.ts index 61ea974e8..7f08aeb94 100644 --- a/browser_tests/fixtures/helpers/WorkflowHelper.ts +++ b/browser_tests/fixtures/helpers/WorkflowHelper.ts @@ -1,10 +1,8 @@ import { readFileSync } from 'fs' -import type { useWorkspaceStore } from '../../../src/stores/workspaceStore' +import type { WorkspaceStore } from '../../types/globals' import type { ComfyPage } from '../ComfyPage' -type WorkspaceStore = ReturnType - export type FolderStructure = { [key: string]: FolderStructure | string } @@ -45,7 +43,9 @@ export class WorkflowHelper { } await this.comfyPage.page.evaluate(async () => { - await window.app!.extensionManager.workflow.syncWorkflows() + await ( + window.app!.extensionManager as WorkspaceStore + ).workflow.syncWorkflows() }) // Wait for Vue to re-render the workflow list diff --git a/browser_tests/helpers/actionbar.ts b/browser_tests/helpers/actionbar.ts index be128ba90..196905b84 100644 --- a/browser_tests/helpers/actionbar.ts +++ b/browser_tests/helpers/actionbar.ts @@ -1,6 +1,7 @@ import type { Locator, Page } from '@playwright/test' import type { AutoQueueMode } from '../../src/stores/queueStore' +import type { WorkspaceStore } from '../types/globals' export class ComfyActionbar { public readonly root: Locator @@ -42,13 +43,14 @@ class ComfyQueueButtonOptions { public async setMode(mode: AutoQueueMode) { await this.page.evaluate((mode) => { - window.app!.extensionManager.queueSettings.mode = mode + ;(window.app!.extensionManager as WorkspaceStore).queueSettings.mode = + mode }, mode) } public async getMode() { return await this.page.evaluate(() => { - return window.app!.extensionManager.queueSettings.mode + return (window.app!.extensionManager as WorkspaceStore).queueSettings.mode }) } } diff --git a/browser_tests/tests/actionbar.spec.ts b/browser_tests/tests/actionbar.spec.ts index dbbf08ce4..4d57b65f4 100644 --- a/browser_tests/tests/actionbar.spec.ts +++ b/browser_tests/tests/actionbar.spec.ts @@ -4,6 +4,7 @@ import { expect, mergeTests } from '@playwright/test' import type { StatusWsMessage } from '../../src/schemas/apiSchema' import { comfyPageFixture } from '../fixtures/ComfyPage' import { webSocketFixture } from '../fixtures/ws' +import type { WorkspaceStore } from '../types/globals' const test = mergeTests(comfyPageFixture, webSocketFixture) @@ -54,7 +55,9 @@ test.describe('Actionbar', { tag: '@ui' }, () => { ) node!.widgets![0].value = value - window.app!.extensionManager.workflow.activeWorkflow?.changeTracker.checkState() + ;( + window.app!.extensionManager as WorkspaceStore + ).workflow.activeWorkflow?.changeTracker.checkState() }, value) } diff --git a/browser_tests/tests/browserTabTitle.spec.ts b/browser_tests/tests/browserTabTitle.spec.ts index af75555f0..e70afcd6c 100644 --- a/browser_tests/tests/browserTabTitle.spec.ts +++ b/browser_tests/tests/browserTabTitle.spec.ts @@ -2,6 +2,7 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' import { DefaultGraphPositions } from '../fixtures/constants/defaultGraphPositions' +import type { WorkspaceStore } from '../types/globals' test.describe('Browser tab title', { tag: '@smoke' }, () => { test.describe('Beta Menu', () => { @@ -11,7 +12,8 @@ test.describe('Browser tab title', { tag: '@smoke' }, () => { test('Can display workflow name', async ({ comfyPage }) => { const workflowName = await comfyPage.page.evaluate(async () => { - return window.app!.extensionManager.workflow.activeWorkflow?.filename + return (window.app!.extensionManager as WorkspaceStore).workflow + .activeWorkflow?.filename }) expect(await comfyPage.page.title()).toBe(`*${workflowName} - ComfyUI`) }) @@ -22,7 +24,8 @@ test.describe('Browser tab title', { tag: '@smoke' }, () => { comfyPage }) => { const workflowName = await comfyPage.page.evaluate(async () => { - return window.app!.extensionManager.workflow.activeWorkflow?.filename + return (window.app!.extensionManager as WorkspaceStore).workflow + .activeWorkflow?.filename }) expect(await comfyPage.page.title()).toBe(`${workflowName} - ComfyUI`) @@ -38,7 +41,9 @@ test.describe('Browser tab title', { tag: '@smoke' }, () => { // Delete the saved workflow for cleanup. await comfyPage.page.evaluate(async () => { - return window.app!.extensionManager.workflow.activeWorkflow?.delete() + return ( + window.app!.extensionManager as WorkspaceStore + ).workflow.activeWorkflow?.delete() }) }) }) diff --git a/browser_tests/tests/colorPalette.spec.ts b/browser_tests/tests/colorPalette.spec.ts index 703bea722..de8a4282b 100644 --- a/browser_tests/tests/colorPalette.spec.ts +++ b/browser_tests/tests/colorPalette.spec.ts @@ -1,6 +1,7 @@ import { expect } from '@playwright/test' import { comfyPageFixture as test } from '../fixtures/ComfyPage' +import type { WorkspaceStore } from '../types/globals' test.beforeEach(async ({ comfyPage }) => { await comfyPage.settings.setSetting('Comfy.UseNewMenu', 'Disabled') @@ -178,7 +179,9 @@ test.describe('Color Palette', { tag: ['@screenshot', '@settings'] }, () => { test('Can add custom color palette', async ({ comfyPage }) => { await comfyPage.page.evaluate((p) => { - window.app!.extensionManager.colorPalette.addCustomColorPalette(p) + ;( + window.app!.extensionManager as WorkspaceStore + ).colorPalette.addCustomColorPalette(p) }, customColorPalettes.obsidian_dark) expect(await comfyPage.toast.getToastErrorCount()).toBe(0) diff --git a/browser_tests/types.d.ts b/browser_tests/types.d.ts deleted file mode 100644 index 4bdc398ae..000000000 --- a/browser_tests/types.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Type declarations for browser tests. - * Augments global types with test-specific properties. - */ - -declare global { - interface Window { - /** - * WebSocket store used by test fixtures for mocking WebSocket connections. - * @see browser_tests/fixtures/ws.ts - */ - __ws__?: Record - } -} - -export {} diff --git a/browser_tests/types/globals.d.ts b/browser_tests/types/globals.d.ts index bde4fb7e2..90e7493e7 100644 --- a/browser_tests/types/globals.d.ts +++ b/browser_tests/types/globals.d.ts @@ -1,6 +1,7 @@ -import type { ComfyApp } from '@/scripts/app' import type { LGraph } from '@/lib/litegraph/src/LGraph' import type { LiteGraphGlobal } from '@/lib/litegraph/src/LiteGraphGlobal' +import type { ComfyApp } from '@/scripts/app' +import type { useWorkspaceStore } from '@/stores/workspaceStore' interface AppReadiness { featureFlagsReceived: boolean @@ -29,6 +30,12 @@ declare global { // Feature flags test globals __capturedMessages?: CapturedMessages __appReadiness?: AppReadiness + + /** + * WebSocket store used by test fixtures for mocking WebSocket connections. + * @see browser_tests/fixtures/ws.ts + */ + __ws__?: Record } const app: ComfyApp | undefined @@ -37,4 +44,15 @@ declare global { const LGraphBadge: typeof LGraphBadge | undefined } -export {} +/** + * Internal store type for browser test access. + * Used to access properties not exposed via the public ExtensionManager interface. + * + * @example + * ```ts + * await page.evaluate(() => { + * ;(window.app!.extensionManager as WorkspaceStore).workflow.syncWorkflows() + * }) + * ``` + */ +export type WorkspaceStore = ReturnType diff --git a/src/scripts/app.ts b/src/scripts/app.ts index eddae324d..8d040488a 100644 --- a/src/scripts/app.ts +++ b/src/scripts/app.ts @@ -65,8 +65,9 @@ import { useModelStore } from '@/stores/modelStore' import { SYSTEM_NODE_DEFS, useNodeDefStore } from '@/stores/nodeDefStore' import { useSubgraphStore } from '@/stores/subgraphStore' import { useWidgetStore } from '@/stores/widgetStore' -import { useWorkspaceStore, type WorkspaceStore } from '@/stores/workspaceStore' +import { useWorkspaceStore } from '@/stores/workspaceStore' import type { ComfyExtension, MissingNodeType } from '@/types/comfy' +import type { ExtensionManager } from '@/types/extensionTypes' import type { NodeExecutionId } from '@/types/nodeIdentification' import { graphToPrompt } from '@/utils/executionUtil' import { anyItemOverlapsRect } from '@/utils/mathUtil' @@ -154,7 +155,7 @@ export class ComfyApp { vueAppReady: boolean api: ComfyApi ui: ComfyUI - extensionManager!: WorkspaceStore + extensionManager!: ExtensionManager private _nodeOutputs!: Record nodePreviewImages: Record diff --git a/src/stores/workspaceStore.ts b/src/stores/workspaceStore.ts index 26cc0262f..ac6a044b9 100644 --- a/src/stores/workspaceStore.ts +++ b/src/stores/workspaceStore.ts @@ -111,5 +111,3 @@ const workspaceStoreSetup = () => { } export const useWorkspaceStore = defineStore('workspace', workspaceStoreSetup) - -export type WorkspaceStore = ReturnType