diff --git a/browser_tests/actionbar.spec.ts b/browser_tests/actionbar.spec.ts index 96a2d3a72..b85e284f8 100644 --- a/browser_tests/actionbar.spec.ts +++ b/browser_tests/actionbar.spec.ts @@ -52,7 +52,9 @@ test.describe('Actionbar', () => { (n) => n.type === 'EmptyLatentImage' ) node.widgets[0].value = value - window['app'].workflowManager.activeWorkflow.changeTracker.checkState() + window[ + 'app' + ].extensionManager.workflow.activeWorkflow.changeTracker.checkState() }, value) } diff --git a/browser_tests/browserTabTitle.spec.ts b/browser_tests/browserTabTitle.spec.ts index b5c02812a..43439bbd9 100644 --- a/browser_tests/browserTabTitle.spec.ts +++ b/browser_tests/browserTabTitle.spec.ts @@ -9,24 +9,22 @@ test.describe('Browser tab title', () => { test('Can display workflow name', async ({ comfyPage }) => { const workflowName = await comfyPage.page.evaluate(async () => { - return window['app'].workflowManager.activeWorkflow.name + return window['app'].extensionManager.workflow.activeWorkflow.filename }) - // Note: unsaved workflow name is always prepended with "*". - expect(await comfyPage.page.title()).toBe(`*${workflowName} - ComfyUI`) + expect(await comfyPage.page.title()).toBe(`${workflowName} - ComfyUI`) }) - // Broken by https://github.com/Comfy-Org/ComfyUI_frontend/pull/893 - // Release blocker for v1.3.0 + // Failing on CI + // Cannot reproduce locally test.skip('Can display workflow name with unsaved changes', async ({ comfyPage }) => { const workflowName = await comfyPage.page.evaluate(async () => { - return window['app'].workflowManager.activeWorkflow.name + return window['app'].extensionManager.workflow.activeWorkflow.filename }) - // Note: unsaved workflow name is always prepended with "*". - expect(await comfyPage.page.title()).toBe(`*${workflowName} - ComfyUI`) + expect(await comfyPage.page.title()).toBe(`${workflowName} - ComfyUI`) - await comfyPage.menu.saveWorkflow('test') + await comfyPage.menu.topbar.saveWorkflow('test') expect(await comfyPage.page.title()).toBe('test - ComfyUI') const textBox = comfyPage.widgetTextBox @@ -36,7 +34,7 @@ test.describe('Browser tab title', () => { // Delete the saved workflow for cleanup. await comfyPage.page.evaluate(async () => { - window['app'].workflowManager.activeWorkflow.delete() + return window['app'].extensionManager.workflow.activeWorkflow.delete() }) }) }) diff --git a/browser_tests/fixtures/components/Topbar.ts b/browser_tests/fixtures/components/Topbar.ts index fc0692b66..bc64fea1d 100644 --- a/browser_tests/fixtures/components/Topbar.ts +++ b/browser_tests/fixtures/components/Topbar.ts @@ -36,6 +36,14 @@ export class Topbar { await this.page.waitForTimeout(300) } + async saveWorkflowAs(workflowName: string) { + await this.triggerTopbarCommand(['Workflow', 'Save As']) + await this.page.locator('.p-dialog-content input').fill(workflowName) + await this.page.keyboard.press('Enter') + // Wait for the dialog to close. + await this.page.waitForTimeout(300) + } + async triggerTopbarCommand(path: string[]) { if (path.length < 2) { throw new Error('Path is too short') diff --git a/browser_tests/menu.spec.ts b/browser_tests/menu.spec.ts index 5b2f33dfa..adf509238 100644 --- a/browser_tests/menu.spec.ts +++ b/browser_tests/menu.spec.ts @@ -392,7 +392,7 @@ test.describe('Menu', () => { await tab.newBlankWorkflowButton.click() expect(await tab.getOpenedWorkflowNames()).toEqual([ '*Unsaved Workflow.json', - '*Unsaved Workflow (2).json' + 'Unsaved Workflow (2).json' ]) }) @@ -411,6 +411,19 @@ test.describe('Menu', () => { ) }) + test('Can save workflow as', async ({ comfyPage }) => { + await comfyPage.menu.workflowsTab.newBlankWorkflowButton.click() + await comfyPage.menu.topbar.saveWorkflowAs('workflow3.json') + expect( + await comfyPage.menu.workflowsTab.getOpenedWorkflowNames() + ).toEqual(['*Unsaved Workflow.json', 'workflow3.json']) + + await comfyPage.menu.topbar.saveWorkflowAs('workflow4.json') + expect( + await comfyPage.menu.workflowsTab.getOpenedWorkflowNames() + ).toEqual(['*Unsaved Workflow.json', 'workflow3.json', 'workflow4.json']) + }) + test('Does not report warning when switching between opened workflows', async ({ comfyPage }) => { @@ -441,7 +454,7 @@ test.describe('Menu', () => { await closeButton.click() expect( await comfyPage.menu.workflowsTab.getOpenedWorkflowNames() - ).toEqual(['*Unsaved Workflow (2).json']) + ).toEqual(['Unsaved Workflow.json']) }) }) @@ -466,7 +479,7 @@ test.describe('Menu', () => { expect(await comfyPage.menu.topbar.getTabNames()).toEqual([workflowName]) await comfyPage.menu.topbar.closeWorkflowTab(workflowName) expect(await comfyPage.menu.topbar.getTabNames()).toEqual([ - 'Unsaved Workflow (2)' + 'Unsaved Workflow' ]) }) }) diff --git a/src/components/BrowserTabTitle.vue b/src/components/BrowserTabTitle.vue index 34cd792a7..33647e2f6 100644 --- a/src/components/BrowserTabTitle.vue +++ b/src/components/BrowserTabTitle.vue @@ -26,10 +26,10 @@ const betaMenuEnabled = computed( const workflowStore = useWorkflowStore() const isUnsavedText = computed(() => - workflowStore.activeWorkflow?.unsaved ? ' *' : '' + workflowStore.activeWorkflow?.isModified ? ' *' : '' ) const workflowNameText = computed(() => { - const workflowName = workflowStore.activeWorkflow?.name + const workflowName = workflowStore.activeWorkflow?.filename return workflowName ? isUnsavedText.value + workflowName + TITLE_SUFFIX : DEFAULT_TITLE diff --git a/src/components/graph/GraphCanvas.vue b/src/components/graph/GraphCanvas.vue index 2e993e329..5465e4410 100644 --- a/src/components/graph/GraphCanvas.vue +++ b/src/components/graph/GraphCanvas.vue @@ -55,6 +55,7 @@ import GraphCanvasMenu from '@/components/graph/GraphCanvasMenu.vue' import { usePragmaticDroppable } from '@/hooks/dndHooks' import { useWorkflowStore } from '@/stores/workflowStore' import { setStorageValue } from '@/scripts/utils' +import { ChangeTracker } from '@/scripts/changeTracker' const emit = defineEmits(['ready']) const canvasRef = ref(null) @@ -147,7 +148,7 @@ const workflowStore = useWorkflowStore() watchEffect(() => { if (workflowStore.activeWorkflow) { const workflow = workflowStore.activeWorkflow - setStorageValue('Comfy.PreviousWorkflow', workflow.path ?? workflow.name) + setStorageValue('Comfy.PreviousWorkflow', workflow.key) } }) @@ -222,6 +223,9 @@ onMounted(async () => { comfyApp.vueAppReady = true workspaceStore.spinner = true + // ChangeTracker needs to be initialized before setup, as it will overwrite + // some listeners of litegraph canvas. + ChangeTracker.init(comfyApp) await comfyApp.setup(canvasRef.value) canvasStore.canvas = comfyApp.canvas workspaceStore.spinner = false diff --git a/src/components/sidebar/tabs/WorkflowsSidebarTab.vue b/src/components/sidebar/tabs/WorkflowsSidebarTab.vue index 5c1388689..df8c6e90f 100644 --- a/src/components/sidebar/tabs/WorkflowsSidebarTab.vue +++ b/src/components/sidebar/tabs/WorkflowsSidebarTab.vue @@ -43,20 +43,22 @@