diff --git a/apps/desktop-ui/src/i18n.ts b/apps/desktop-ui/src/i18n.ts index 350376ff7a..a978ddcefa 100644 --- a/apps/desktop-ui/src/i18n.ts +++ b/apps/desktop-ui/src/i18n.ts @@ -1,13 +1,13 @@ // Import only English locale eagerly as the default/fallback // ESLint cannot statically resolve dynamic imports with path aliases (@frontend-locales/*), // but these are properly configured in tsconfig.json and resolved by Vite at build time. -// eslint-disable-next-line import-x/no-unresolved + import enCommands from '@frontend-locales/en/commands.json' with { type: 'json' } -// eslint-disable-next-line import-x/no-unresolved + import en from '@frontend-locales/en/main.json' with { type: 'json' } -// eslint-disable-next-line import-x/no-unresolved + import enNodes from '@frontend-locales/en/nodeDefs.json' with { type: 'json' } -// eslint-disable-next-line import-x/no-unresolved + import enSettings from '@frontend-locales/en/settings.json' with { type: 'json' } import { createI18n } from 'vue-i18n' @@ -27,7 +27,7 @@ function buildLocale< // Locale loader map - dynamically import locales only when needed // ESLint cannot statically resolve these dynamic imports, but they are valid at build time -/* eslint-disable import-x/no-unresolved */ + const localeLoaders: Record< string, () => Promise<{ default: Record }> diff --git a/browser_tests/fixtures/ComfyPage.ts b/browser_tests/fixtures/ComfyPage.ts index aed8a40728..a9ae09dfe5 100644 --- a/browser_tests/fixtures/ComfyPage.ts +++ b/browser_tests/fixtures/ComfyPage.ts @@ -1272,9 +1272,6 @@ export class ComfyPage { }, 'image/png') }) }, filename) - - // Wait a bit for the download to process - await this.page.waitForTimeout(500) } /** diff --git a/browser_tests/fixtures/components/ComfyNodeSearchBox.ts b/browser_tests/fixtures/components/ComfyNodeSearchBox.ts index fd40ca9113..51b5a89280 100644 --- a/browser_tests/fixtures/components/ComfyNodeSearchBox.ts +++ b/browser_tests/fixtures/components/ComfyNodeSearchBox.ts @@ -60,9 +60,6 @@ export class ComfyNodeSearchBox { await this.input.waitFor({ state: 'visible' }) await this.input.fill(nodeName) await this.dropdown.waitFor({ state: 'visible' }) - // Wait for some time for the auto complete list to update. - // The auto complete list is debounced and may take some time to update. - await this.page.waitForTimeout(500) await this.dropdown .locator('li') .nth(options?.suggestionIndex || 0) diff --git a/browser_tests/fixtures/components/SidebarTab.ts b/browser_tests/fixtures/components/SidebarTab.ts index 1700866f23..00ec8a5b09 100644 --- a/browser_tests/fixtures/components/SidebarTab.ts +++ b/browser_tests/fixtures/components/SidebarTab.ts @@ -116,7 +116,6 @@ export class WorkflowsSidebarTab extends SidebarTab { async switchToWorkflow(workflowName: string) { const workflowLocator = this.getOpenedItem(workflowName) await workflowLocator.click() - await this.page.waitForTimeout(300) } getOpenedItem(name: string) { @@ -138,7 +137,6 @@ export class WorkflowsSidebarTab extends SidebarTab { .click() await this.page.keyboard.type(newName) await this.page.keyboard.press('Enter') - await this.page.waitForTimeout(300) } async insertWorkflow(locator: Locator) { diff --git a/browser_tests/fixtures/components/Topbar.ts b/browser_tests/fixtures/components/Topbar.ts index 804793963c..289ca641bc 100644 --- a/browser_tests/fixtures/components/Topbar.ts +++ b/browser_tests/fixtures/components/Topbar.ts @@ -95,7 +95,6 @@ export class Topbar { } async openTopbarMenu() { - await this.page.waitForTimeout(1000) await this.menuTrigger.click() await this.menuLocator.waitFor({ state: 'visible' }) return this.menuLocator diff --git a/browser_tests/fixtures/utils/litegraphUtils.ts b/browser_tests/fixtures/utils/litegraphUtils.ts index 5533fcaaa6..832db63249 100644 --- a/browser_tests/fixtures/utils/litegraphUtils.ts +++ b/browser_tests/fixtures/utils/litegraphUtils.ts @@ -462,7 +462,6 @@ export class NodeReference { async convertToSubgraph() { await this.clickContextMenuOption('Convert to Subgraph') await this.comfyPage.nextFrame() - await this.comfyPage.page.waitForTimeout(256) const nodes = await this.comfyPage.getNodeRefsByTitle('New Subgraph') if (nodes.length !== 1) { throw new Error( @@ -511,7 +510,6 @@ export class NodeReference { // Double-click to enter subgraph await this.comfyPage.canvas.dblclick({ position, force: true }) await this.comfyPage.nextFrame() - await this.comfyPage.page.waitForTimeout(500) // Check if we successfully entered the subgraph isInSubgraph = await this.comfyPage.page.evaluate(() => { diff --git a/browser_tests/tests/backgroundImageUpload.spec.ts b/browser_tests/tests/backgroundImageUpload.spec.ts index 7f3ed6a3d4..44ae2d6aea 100644 --- a/browser_tests/tests/backgroundImageUpload.spec.ts +++ b/browser_tests/tests/backgroundImageUpload.spec.ts @@ -75,9 +75,6 @@ test.describe('Background Image Upload', () => { // Upload the test image await fileChooser.setFiles(comfyPage.assetPath('image32x32.webp')) - // Wait for upload to complete and verify the setting was updated - await comfyPage.page.waitForTimeout(500) // Give time for file reading - // Verify the URL input now has an API URL const urlInput = backgroundImageSetting.locator('input[type="text"]') const inputValue = await urlInput.inputValue() @@ -191,14 +188,11 @@ test.describe('Background Image Upload', () => { ) await uploadButton.hover() - // Wait for tooltip to appear and verify it exists - await comfyPage.page.waitForTimeout(700) // Tooltip delay const uploadTooltip = comfyPage.page.locator('.p-tooltip:visible') await expect(uploadTooltip).toBeVisible() // Move away to hide tooltip await comfyPage.page.locator('body').hover() - await comfyPage.page.waitForTimeout(100) // Set a background to enable clear button const urlInput = backgroundImageSetting.locator('input[type="text"]') @@ -209,8 +203,6 @@ test.describe('Background Image Upload', () => { const clearButton = backgroundImageSetting.locator('button:has(.pi-trash)') await clearButton.hover() - // Wait for tooltip to appear and verify it exists - await comfyPage.page.waitForTimeout(700) // Tooltip delay const clearTooltip = comfyPage.page.locator('.p-tooltip:visible') await expect(clearTooltip).toBeVisible() }) diff --git a/browser_tests/tests/colorPalette.spec.ts b/browser_tests/tests/colorPalette.spec.ts index 6dd53c194f..ce372ddfa6 100644 --- a/browser_tests/tests/colorPalette.spec.ts +++ b/browser_tests/tests/colorPalette.spec.ts @@ -203,7 +203,6 @@ test.describe('Node Color Adjustments', () => { comfyPage }) => { await comfyPage.setSetting('Comfy.Node.Opacity', 0.5) - await comfyPage.page.waitForTimeout(128) // Drag mouse to force canvas to redraw await comfyPage.page.mouse.move(0, 0) @@ -211,7 +210,6 @@ test.describe('Node Color Adjustments', () => { await expect(comfyPage.canvas).toHaveScreenshot('node-opacity-0.5.png') await comfyPage.setSetting('Comfy.Node.Opacity', 1.0) - await comfyPage.page.waitForTimeout(128) await comfyPage.page.mouse.move(8, 8) await expect(comfyPage.canvas).toHaveScreenshot('node-opacity-1.png') @@ -235,7 +233,6 @@ test.describe('Node Color Adjustments', () => { await comfyPage.setSetting('Comfy.Node.Opacity', 0.5) await comfyPage.setSetting('Comfy.ColorPalette', 'light') const saveWorkflowInterval = 1000 - await comfyPage.page.waitForTimeout(saveWorkflowInterval) const workflow = await comfyPage.page.evaluate(() => { return localStorage.getItem('workflow') }) diff --git a/browser_tests/tests/dialog.spec.ts b/browser_tests/tests/dialog.spec.ts index 269df33870..aef13f0cfe 100644 --- a/browser_tests/tests/dialog.spec.ts +++ b/browser_tests/tests/dialog.spec.ts @@ -43,7 +43,6 @@ test('Does not report warning on undo/redo', async ({ comfyPage }) => { // Wait for any async operations to complete after dialog closes await comfyPage.nextFrame() - await comfyPage.page.waitForTimeout(100) // Make a change to the graph await comfyPage.doubleClickCanvas() diff --git a/browser_tests/tests/execution.spec.ts b/browser_tests/tests/execution.spec.ts index 075025a3ab..ed77b79497 100644 --- a/browser_tests/tests/execution.spec.ts +++ b/browser_tests/tests/execution.spec.ts @@ -36,10 +36,6 @@ test.describe('Execute to selected output nodes', () => { await output1.click('title') await comfyPage.executeCommand('Comfy.QueueSelectedOutputNodes') - // @note: Wait for the execution to finish. We might want to move to a more - // reliable way to wait for the execution to finish. Workflow in this test - // is simple enough that this is fine for now. - await comfyPage.page.waitForTimeout(200) expect(await (await input.getWidget(0)).getValue()).toBe('foo') expect(await (await output1.getWidget(0)).getValue()).toBe('foo') diff --git a/browser_tests/tests/execution.spec.ts-snapshots/execution-error-unconnected-slot-chromium-linux.png b/browser_tests/tests/execution.spec.ts-snapshots/execution-error-unconnected-slot-chromium-linux.png index c352f301eb..dd7bda4c85 100644 Binary files a/browser_tests/tests/execution.spec.ts-snapshots/execution-error-unconnected-slot-chromium-linux.png and b/browser_tests/tests/execution.spec.ts-snapshots/execution-error-unconnected-slot-chromium-linux.png differ diff --git a/browser_tests/tests/featureFlags.spec.ts b/browser_tests/tests/featureFlags.spec.ts index 38286b3990..7079768291 100644 --- a/browser_tests/tests/featureFlags.spec.ts +++ b/browser_tests/tests/featureFlags.spec.ts @@ -94,9 +94,6 @@ test.describe('Feature Flags', () => { test('Server feature flags are received and accessible', async ({ comfyPage }) => { - // Wait for connection to establish - await comfyPage.page.waitForTimeout(1000) - // Get the actual server feature flags from the backend const serverFlags = await comfyPage.page.evaluate(() => { return window['app'].api.serverFeatureFlags @@ -116,9 +113,6 @@ test.describe('Feature Flags', () => { test('serverSupportsFeature method works with real backend flags', async ({ comfyPage }) => { - // Wait for connection - await comfyPage.page.waitForTimeout(1000) - // Test serverSupportsFeature with real backend flags const supportsPreviewMetadata = await comfyPage.page.evaluate(() => { return window['app'].api.serverSupportsFeature( @@ -170,9 +164,6 @@ test.describe('Feature Flags', () => { test('getServerFeature method works with real backend data', async ({ comfyPage }) => { - // Wait for connection - await comfyPage.page.waitForTimeout(1000) - // Test getServerFeature method const previewMetadataValue = await comfyPage.page.evaluate(() => { return window['app'].api.getServerFeature('supports_preview_metadata') @@ -199,9 +190,6 @@ test.describe('Feature Flags', () => { test('getServerFeatures returns all backend feature flags', async ({ comfyPage }) => { - // Wait for connection - await comfyPage.page.waitForTimeout(1000) - // Test getServerFeatures returns all flags const allFeatures = await comfyPage.page.evaluate(() => { return window['app'].api.getServerFeatures() @@ -248,9 +236,6 @@ test.describe('Feature Flags', () => { test('Server features are immutable when accessed via getServerFeatures', async ({ comfyPage }) => { - // Wait for connection to establish - await comfyPage.page.waitForTimeout(1000) - const immutabilityTest = await comfyPage.page.evaluate(() => { // Get a copy of server features const features1 = window['app'].api.getServerFeatures() diff --git a/browser_tests/tests/groupNode.spec.ts b/browser_tests/tests/groupNode.spec.ts index 5bbda7b03b..9d67a0951a 100644 --- a/browser_tests/tests/groupNode.spec.ts +++ b/browser_tests/tests/groupNode.spec.ts @@ -104,8 +104,6 @@ test.describe('Group Node', () => { await comfyPage.setSetting('Comfy.EnableTooltips', true) await comfyPage.convertAllNodesToGroupNode('Group Node') await comfyPage.page.mouse.move(47, 173) - const tooltipTimeout = 500 - await comfyPage.page.waitForTimeout(tooltipTimeout + 16) await expect(comfyPage.page.locator('.node-tooltip')).toBeVisible() }) @@ -320,14 +318,12 @@ test.describe('Group Node', () => { test('Convert to group node, no selection', async ({ comfyPage }) => { expect(await comfyPage.getVisibleToastCount()).toBe(0) await comfyPage.page.keyboard.press('Alt+g') - await comfyPage.page.waitForTimeout(300) expect(await comfyPage.getVisibleToastCount()).toBe(1) }) test('Convert to group node, selected 1 node', async ({ comfyPage }) => { expect(await comfyPage.getVisibleToastCount()).toBe(0) await comfyPage.clickTextEncodeNode1() await comfyPage.page.keyboard.press('Alt+g') - await comfyPage.page.waitForTimeout(300) expect(await comfyPage.getVisibleToastCount()).toBe(1) }) }) diff --git a/browser_tests/tests/interaction.spec.ts b/browser_tests/tests/interaction.spec.ts index 454b56ccf8..37442bf4e0 100644 --- a/browser_tests/tests/interaction.spec.ts +++ b/browser_tests/tests/interaction.spec.ts @@ -307,8 +307,6 @@ test.describe('Node Interaction', () => { position: numberWidgetPos }) await expect(comfyPage.canvas).toHaveScreenshot('prompt-dialog-opened.png') - // Wait for 1s so that it does not trigger the search box by double click. - await comfyPage.page.waitForTimeout(1000) await comfyPage.canvas.click({ position: { x: 10, @@ -332,7 +330,6 @@ test.describe('Node Interaction', () => { await expect(comfyPage.canvas).toHaveScreenshot( 'prompt-dialog-opened-text.png' ) - await comfyPage.page.waitForTimeout(1000) await comfyPage.canvas.click({ position: { x: 10, @@ -663,9 +660,6 @@ test.describe('Load workflow', () => { await comfyPage.loadWorkflow('nodes/single_ksampler') const node = (await comfyPage.getFirstNodeRef())! await node.click('collapse') - // Wait 300ms between 2 clicks so that it is not treated as a double click - // by litegraph. - await comfyPage.page.waitForTimeout(300) await comfyPage.clickEmptySpace() await expect(comfyPage.canvas).toHaveScreenshot( 'single_ksampler_modified.png' diff --git a/browser_tests/tests/nodeSearchBox.spec.ts b/browser_tests/tests/nodeSearchBox.spec.ts index 98ba335836..ce8875defc 100644 --- a/browser_tests/tests/nodeSearchBox.spec.ts +++ b/browser_tests/tests/nodeSearchBox.spec.ts @@ -104,9 +104,6 @@ test.describe('Node search box', () => { await comfyPage.searchBox.input.waitFor({ state: 'visible' }) await comfyPage.searchBox.input.fill(node) await comfyPage.searchBox.dropdown.waitFor({ state: 'visible' }) - // Wait for some time for the auto complete list to update. - // The auto complete list is debounced and may take some time to update. - await comfyPage.page.waitForTimeout(500) const firstResult = comfyPage.searchBox.dropdown.locator('li').first() await expect(firstResult).toHaveAttribute('aria-label', node) @@ -125,7 +122,6 @@ test.describe('Node search box', () => { await comfyPage.canvas.tap({ position: screenCenter }) - await comfyPage.page.waitForTimeout(256) await expect(comfyPage.searchBox.input).not.toHaveCount(0) }) diff --git a/browser_tests/tests/releaseNotifications.spec.ts b/browser_tests/tests/releaseNotifications.spec.ts index 19d09327d0..3b16be2496 100644 --- a/browser_tests/tests/releaseNotifications.spec.ts +++ b/browser_tests/tests/releaseNotifications.spec.ts @@ -212,9 +212,6 @@ test.describe('Release Notifications', () => { await comfyPage.setup({ mockReleases: false }) - // Wait a bit to ensure any potential API calls would have been made - await comfyPage.page.waitForTimeout(1000) - // Verify no API calls were made expect(apiCallCount).toBe(0) }) diff --git a/browser_tests/tests/remoteWidgets.spec.ts b/browser_tests/tests/remoteWidgets.spec.ts index 7a54cae07b..b717f62824 100644 --- a/browser_tests/tests/remoteWidgets.spec.ts +++ b/browser_tests/tests/remoteWidgets.spec.ts @@ -49,8 +49,6 @@ test.describe('Remote COMBO Widget', () => { const waitForWidgetUpdate = async (comfyPage: ComfyPage) => { // Force re-render to trigger first access of widget's options await comfyPage.page.mouse.click(400, 300) - // Wait for the widget to actually update instead of fixed timeout - await comfyPage.page.waitForTimeout(300) } test.beforeEach(async ({ comfyPage }) => { @@ -92,7 +90,6 @@ test.describe('Remote COMBO Widget', () => { }) => { const nodeName = 'Remote Widget Node' await comfyPage.loadWorkflow('inputs/remote_widget') - await comfyPage.page.waitForTimeout(512) const node = await comfyPage.page.evaluate((name) => { return window['app'].graph.nodes.find((node) => node.title === name) @@ -160,8 +157,6 @@ test.describe('Remote COMBO Widget', () => { } }) - // Wait a reasonable time to ensure no request is made - await comfyPage.page.waitForTimeout(512) expect(requestWasMade).toBe(false) }) @@ -214,16 +209,9 @@ test.describe('Remote COMBO Widget', () => { await waitForWidgetUpdate(comfyPage) const initialOptions = await getWidgetOptions(comfyPage, nodeName) - // Wait for the refresh (TTL) to expire with extra buffer for processing - // TTL is 300ms, wait 600ms to ensure it has expired - await comfyPage.page.waitForTimeout(600) - // Click on the canvas to trigger widget refresh await comfyPage.page.mouse.click(400, 300) - // Wait a bit for the refresh to complete - await comfyPage.page.waitForTimeout(100) - const refreshedOptions = await getWidgetOptions(comfyPage, nodeName) expect(refreshedOptions).not.toEqual(initialOptions) }) @@ -331,7 +319,6 @@ test.describe('Remote COMBO Widget', () => { // Click refresh button await clickRefreshButton(comfyPage, nodeName) - await comfyPage.page.waitForTimeout(200) // Verify the selected value of the widget is the first option in the refreshed list const refreshedValue = await getWidgetValue(comfyPage, nodeName) diff --git a/browser_tests/tests/rightClickMenu.spec.ts b/browser_tests/tests/rightClickMenu.spec.ts index f7718122b7..d2c17b43db 100644 --- a/browser_tests/tests/rightClickMenu.spec.ts +++ b/browser_tests/tests/rightClickMenu.spec.ts @@ -118,7 +118,6 @@ test.describe('Node Right Click Menu', () => { await comfyPage.rightClickEmptyLatentNode() await comfyPage.page.click('.litemenu-entry:has-text("Unpin")') await comfyPage.nextFrame() - await comfyPage.page.waitForTimeout(256) await comfyPage.dragAndDrop({ x: 496, y: 618 }, { x: 200, y: 590 }) await expect(comfyPage.canvas).toHaveScreenshot( 'right-click-unpinned-node-moved.png' diff --git a/browser_tests/tests/selectionToolboxSubmenus.spec.ts b/browser_tests/tests/selectionToolboxSubmenus.spec.ts index db63261528..5c7d380a53 100644 --- a/browser_tests/tests/selectionToolboxSubmenus.spec.ts +++ b/browser_tests/tests/selectionToolboxSubmenus.spec.ts @@ -34,7 +34,6 @@ test.describe('Selection Toolbox - More Options Submenus', () => { await ksamplerNodes[0].click('title') await comfyPage.nextFrame() - await comfyPage.page.waitForTimeout(500) await expect(comfyPage.page.locator('.selection-toolbox')).toBeVisible({ timeout: 5000 @@ -59,7 +58,6 @@ test.describe('Selection Toolbox - More Options Submenus', () => { await moreOptionsBtn.click({ force: true }) await comfyPage.nextFrame() - await comfyPage.page.waitForTimeout(2000) const menuOptionsVisibleAfterClick = await comfyPage.page .getByText('Rename') @@ -172,7 +170,6 @@ test.describe('Selection Toolbox - More Options Submenus', () => { } }) await comfyPage.nextFrame() - await comfyPage.page.waitForTimeout(500) await expect( comfyPage.page.getByText('Rename', { exact: true }) diff --git a/browser_tests/tests/sidebar/workflows.spec.ts b/browser_tests/tests/sidebar/workflows.spec.ts index 1b3f21ff4d..b14ba8eb0b 100644 --- a/browser_tests/tests/sidebar/workflows.spec.ts +++ b/browser_tests/tests/sidebar/workflows.spec.ts @@ -104,10 +104,8 @@ test.describe('Workflows sidebar', () => { await tab.open() // Switch to the parent folder await tab.getPersistedItem('foo').click() - await comfyPage.page.waitForTimeout(300) // Switch to the nested workflow await tab.getPersistedItem('bar').click() - await comfyPage.page.waitForTimeout(300) const openedWorkflow = tab.getOpenedItem('foo/bar') await tab.renameWorkflow(openedWorkflow, 'foo/baz') @@ -193,7 +191,6 @@ test.describe('Workflows sidebar', () => { await comfyPage.menu.topbar.saveWorkflowAs('workflow5.json') await comfyPage.confirmDialog.click('overwrite') - await comfyPage.page.waitForTimeout(200) expect(await comfyPage.menu.workflowsTab.getOpenedWorkflowNames()).toEqual([ 'workflow5.json' ]) @@ -228,7 +225,6 @@ test.describe('Workflows sidebar', () => { await topbar.saveWorkflowAs('workflow1.json') await comfyPage.confirmDialog.click('overwrite') - await comfyPage.page.waitForTimeout(200) // The old workflow1.json should be deleted and the new one should be saved. expect(await comfyPage.menu.workflowsTab.getOpenedWorkflowNames()).toEqual([ 'workflow2.json', @@ -362,8 +358,6 @@ test.describe('Workflows sidebar', () => { '#graph-canvas', { targetPosition } ) - // Wait for the workflow to be inserted - await comfyPage.page.waitForTimeout(200) expect(await comfyPage.getGraphNodesCount()).toBe(nodeCount * 2) }) }) diff --git a/browser_tests/tests/subgraph.spec.ts b/browser_tests/tests/subgraph.spec.ts index 87ea504bb5..06a09210c5 100644 --- a/browser_tests/tests/subgraph.spec.ts +++ b/browser_tests/tests/subgraph.spec.ts @@ -308,8 +308,6 @@ test.describe('Subgraph Operations', () => { } }) - // Wait for dialog to appear - await comfyPage.page.waitForTimeout(200) await comfyPage.nextFrame() await comfyPage.page.waitForSelector(SELECTORS.promptDialog, { @@ -656,7 +654,6 @@ test.describe('Subgraph Operations', () => { await comfyPage.rightClickSubgraphInputSlot('text') await comfyPage.clickLitegraphContextMenuItem('Remove Slot') - await comfyPage.page.waitForTimeout(200) // Wait for breadcrumb to be visible await comfyPage.page.waitForSelector(SELECTORS.breadcrumb, { @@ -673,7 +670,6 @@ test.describe('Subgraph Operations', () => { await homeBreadcrumb.waitFor({ state: 'visible' }) await homeBreadcrumb.click() await comfyPage.nextFrame() - await comfyPage.page.waitForTimeout(300) // Check that the subgraph node has no widgets after removing the text slot const widgetCount = await comfyPage.page.evaluate(() => { diff --git a/browser_tests/tests/templates.spec.ts b/browser_tests/tests/templates.spec.ts index 6252332135..1e0d24dd68 100644 --- a/browser_tests/tests/templates.spec.ts +++ b/browser_tests/tests/templates.spec.ts @@ -170,9 +170,7 @@ test.describe('Templates', () => { // Verify English titles are shown as fallback await expect( - comfyPage.templates.content.getByRole('heading', { - name: 'Image Generation' - }) + comfyPage.page.getByRole('main').getByText('All Templates') ).toBeVisible() }) diff --git a/browser_tests/tests/useSettingSearch.spec.ts b/browser_tests/tests/useSettingSearch.spec.ts index a817616f8b..f022bb4bd2 100644 --- a/browser_tests/tests/useSettingSearch.spec.ts +++ b/browser_tests/tests/useSettingSearch.spec.ts @@ -150,7 +150,6 @@ test.describe('Settings Search functionality', () => { // Type in search box await searchBox.fill('graph') - await comfyPage.page.waitForTimeout(200) // Wait for debounce // Verify that the search input is handled await expect(searchBox).toHaveValue('graph') @@ -182,9 +181,6 @@ test.describe('Settings Search functionality', () => { await searchBox.fill('abc') await searchBox.fill('abcd') - // Wait for debounce - await comfyPage.page.waitForTimeout(200) - // Verify final value await expect(searchBox).toHaveValue('abcd') }) @@ -200,7 +196,6 @@ test.describe('Settings Search functionality', () => { // Search for our test settings const searchBox = comfyPage.page.locator('.settings-search-box input') await searchBox.fill('Test') - await comfyPage.page.waitForTimeout(300) // Wait for debounce // Get all settings content const settingsContent = comfyPage.page.locator('.settings-tab-panels') @@ -221,7 +216,6 @@ test.describe('Settings Search functionality', () => { // Search for our test settings const searchBox = comfyPage.page.locator('.settings-search-box input') await searchBox.fill('Test') - await comfyPage.page.waitForTimeout(300) // Wait for debounce // Get all settings content const settingsContent = comfyPage.page.locator('.settings-tab-panels') @@ -242,7 +236,6 @@ test.describe('Settings Search functionality', () => { // Search for our test settings const searchBox = comfyPage.page.locator('.settings-search-box input') await searchBox.fill('Test') - await comfyPage.page.waitForTimeout(300) // Wait for debounce // Get all settings content const settingsContent = comfyPage.page.locator('.settings-tab-panels') @@ -269,7 +262,6 @@ test.describe('Settings Search functionality', () => { // Search specifically for hidden setting by name await searchBox.clear() await searchBox.fill('Hidden') - await comfyPage.page.waitForTimeout(300) // Should not show the hidden setting even when searching by name await expect(settingsContent).not.toContainText('Test Hidden Setting') @@ -277,7 +269,6 @@ test.describe('Settings Search functionality', () => { // Search specifically for deprecated setting by name await searchBox.clear() await searchBox.fill('Deprecated') - await comfyPage.page.waitForTimeout(300) // Should not show the deprecated setting even when searching by name await expect(settingsContent).not.toContainText('Test Deprecated Setting') @@ -285,7 +276,6 @@ test.describe('Settings Search functionality', () => { // Search for visible setting by name - should work await searchBox.clear() await searchBox.fill('Visible') - await comfyPage.page.waitForTimeout(300) // Should show the visible setting await expect(settingsContent).toContainText('Test Visible Setting') diff --git a/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-create-group-chromium-linux.png b/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-create-group-chromium-linux.png index aa60c90eb0..8a0fb4f928 100644 Binary files a/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-create-group-chromium-linux.png and b/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-create-group-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-fit-to-contents-chromium-linux.png b/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-fit-to-contents-chromium-linux.png index 7874e1fb4d..31f835b9f9 100644 Binary files a/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-fit-to-contents-chromium-linux.png and b/browser_tests/tests/vueNodes/groups/groups.spec.ts-snapshots/vue-groups-fit-to-contents-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/interactions/canvas/pan.spec.ts-snapshots/vue-nodes-paned-with-touch-mobile-chrome-linux.png b/browser_tests/tests/vueNodes/interactions/canvas/pan.spec.ts-snapshots/vue-nodes-paned-with-touch-mobile-chrome-linux.png index c473af74e0..6a9ffbf9f1 100644 Binary files a/browser_tests/tests/vueNodes/interactions/canvas/pan.spec.ts-snapshots/vue-nodes-paned-with-touch-mobile-chrome-linux.png and b/browser_tests/tests/vueNodes/interactions/canvas/pan.spec.ts-snapshots/vue-nodes-paned-with-touch-mobile-chrome-linux.png differ diff --git a/browser_tests/tests/vueNodes/interactions/canvas/zoom.spec.ts-snapshots/zoomed-in-ctrl-shift-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/canvas/zoom.spec.ts-snapshots/zoomed-in-ctrl-shift-chromium-linux.png index 1c87757c5d..a372972914 100644 Binary files a/browser_tests/tests/vueNodes/interactions/canvas/zoom.spec.ts-snapshots/zoomed-in-ctrl-shift-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/canvas/zoom.spec.ts-snapshots/zoomed-in-ctrl-shift-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-dragging-link-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-dragging-link-chromium-linux.png index c454a29773..c7bc0306a8 100644 Binary files a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-dragging-link-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-dragging-link-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-ctrl-alt-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-ctrl-alt-chromium-linux.png index 8bbbade09a..47d59a3567 100644 Binary files a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-ctrl-alt-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-ctrl-alt-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-reuses-origin-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-reuses-origin-chromium-linux.png index ddeed325af..826de88153 100644 Binary files a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-reuses-origin-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-input-drag-reuses-origin-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-input-drag-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-input-drag-chromium-linux.png index c1b84f2cd3..92b7b91f5b 100644 Binary files a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-input-drag-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-input-drag-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-output-shift-drag-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-output-shift-drag-chromium-linux.png index bc40dbb141..19b2f4746b 100644 Binary files a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-output-shift-drag-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-reroute-output-shift-drag-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-shift-output-multi-link-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-shift-output-multi-link-chromium-linux.png index 6ac61c8b0c..abb9f398a5 100644 Binary files a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-shift-output-multi-link-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-shift-output-multi-link-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-node-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-node-chromium-linux.png index be53102c58..f886dbbf8a 100644 Binary files a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-node-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-node-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-slot-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-slot-chromium-linux.png index 33dbd25598..fbcf5f4e9d 100644 Binary files a/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-slot-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/links/linkInteraction.spec.ts-snapshots/vue-node-snap-to-slot-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-chromium-linux.png b/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-chromium-linux.png index a025ece449..edfb82f6e6 100644 Binary files a/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-chromium-linux.png and b/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-touch-mobile-chrome-linux.png b/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-touch-mobile-chrome-linux.png index 44387515dd..fddd996742 100644 Binary files a/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-touch-mobile-chrome-linux.png and b/browser_tests/tests/vueNodes/interactions/node/move.spec.ts-snapshots/vue-node-moved-node-touch-mobile-chrome-linux.png differ diff --git a/browser_tests/tests/vueNodes/interactions/node/resize.spec.ts b/browser_tests/tests/vueNodes/interactions/node/resize.spec.ts index 7ea5bf965b..c8e015ffa4 100644 --- a/browser_tests/tests/vueNodes/interactions/node/resize.spec.ts +++ b/browser_tests/tests/vueNodes/interactions/node/resize.spec.ts @@ -19,7 +19,6 @@ test.describe('Vue Node Resizing', () => { // Select the node first (this was causing the bug) await node.header.click() - await comfyPage.page.waitForTimeout(100) // Brief pause after selection // Get position after selection const selectedBox = await node.boundingBox() diff --git a/browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts-snapshots/vue-node-bypassed-state-chromium-linux.png b/browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts-snapshots/vue-node-bypassed-state-chromium-linux.png index dc585c6d81..665d96d913 100644 Binary files a/browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts-snapshots/vue-node-bypassed-state-chromium-linux.png and b/browser_tests/tests/vueNodes/nodeStates/bypass.spec.ts-snapshots/vue-node-bypassed-state-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-color-blue-chromium-linux.png b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-color-blue-chromium-linux.png index f5ba72c46c..fd349491db 100644 Binary files a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-color-blue-chromium-linux.png and b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-color-blue-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-dark-all-colors-chromium-linux.png b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-dark-all-colors-chromium-linux.png index 3759efb2d4..7ddb546ebe 100644 Binary files a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-dark-all-colors-chromium-linux.png and b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-dark-all-colors-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-light-all-colors-chromium-linux.png b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-light-all-colors-chromium-linux.png index 98507102bc..0b3686ba90 100644 Binary files a/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-light-all-colors-chromium-linux.png and b/browser_tests/tests/vueNodes/nodeStates/colors.spec.ts-snapshots/vue-node-custom-colors-light-all-colors-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/nodeStates/mute.spec.ts-snapshots/vue-node-muted-state-chromium-linux.png b/browser_tests/tests/vueNodes/nodeStates/mute.spec.ts-snapshots/vue-node-muted-state-chromium-linux.png index b71272bace..6067bf18be 100644 Binary files a/browser_tests/tests/vueNodes/nodeStates/mute.spec.ts-snapshots/vue-node-muted-state-chromium-linux.png and b/browser_tests/tests/vueNodes/nodeStates/mute.spec.ts-snapshots/vue-node-muted-state-chromium-linux.png differ diff --git a/browser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts-snapshots/vue-nodes-upload-widgets-chromium-linux.png b/browser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts-snapshots/vue-nodes-upload-widgets-chromium-linux.png index d6aa02b4eb..7924bcf19f 100644 Binary files a/browser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts-snapshots/vue-nodes-upload-widgets-chromium-linux.png and b/browser_tests/tests/vueNodes/widgets/load/uploadWidgets.spec.ts-snapshots/vue-nodes-upload-widgets-chromium-linux.png differ diff --git a/browser_tests/tests/widget.spec.ts b/browser_tests/tests/widget.spec.ts index 3b9c057847..7afa823e35 100644 --- a/browser_tests/tests/widget.spec.ts +++ b/browser_tests/tests/widget.spec.ts @@ -95,7 +95,6 @@ test.describe('Boolean widget', () => { test.describe('Slider widget', () => { test('Can drag adjust value', async ({ comfyPage }) => { await comfyPage.loadWorkflow('inputs/simple_slider') - await comfyPage.page.waitForTimeout(300) const node = (await comfyPage.getFirstNodeRef())! const widget = await node.getWidget(0) @@ -117,7 +116,6 @@ test.describe('Slider widget', () => { test.describe('Number widget', () => { test('Can drag adjust value', async ({ comfyPage }) => { await comfyPage.loadWorkflow('widgets/seed_widget') - await comfyPage.page.waitForTimeout(300) const node = (await comfyPage.getFirstNodeRef())! const widget = await node.getWidget(0) @@ -141,7 +139,6 @@ test.describe('Dynamic widget manipulation', () => { comfyPage }) => { await comfyPage.loadWorkflow('nodes/single_ksampler') - await comfyPage.page.waitForTimeout(300) await comfyPage.page.evaluate(() => { window['graph'].nodes[0].addWidget('number', 'new_widget', 10) @@ -234,9 +231,6 @@ test.describe('Animated image widget', () => { 'animated_image_preview_drag_and_dropped.png' ) - // Wait for animation to go to next frame - await comfyPage.page.waitForTimeout(512) - // Move mouse and click on canvas to trigger render await comfyPage.page.mouse.click(64, 64) @@ -260,7 +254,6 @@ test.describe('Animated image widget', () => { await comfyPage.dragAndDropFile('animated_webp.webp', { dropPosition: { x, y } }) - await comfyPage.page.waitForTimeout(200) // Expect the filename combo value to be updated const fileComboWidget = await loadAnimatedWebpNode.getWidget(0) @@ -306,9 +299,6 @@ test.describe('Animated image widget', () => { ) await comfyPage.nextFrame() - // Wait for animation to go to next frame - await comfyPage.page.waitForTimeout(512) - // Move mouse and click on canvas to trigger render await comfyPage.page.mouse.click(64, 64) diff --git a/package.json b/package.json index 1ef37695cb..1762ba3c26 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@comfyorg/comfyui-frontend", "private": true, - "version": "1.34.6", + "version": "1.34.7", "type": "module", "repository": "https://github.com/Comfy-Org/ComfyUI_frontend", "homepage": "https://comfy.org", diff --git a/src/components/TopMenuSection.vue b/src/components/TopMenuSection.vue index a0b5085540..7b9d88b0e3 100644 --- a/src/components/TopMenuSection.vue +++ b/src/components/TopMenuSection.vue @@ -115,6 +115,7 @@ const cancelJobTooltipConfig = computed(() => // Right side panel toggle const { isOpen: isRightSidePanelOpen } = storeToRefs(rightSidePanelStore) + const rightSidePanelTooltipConfig = computed(() => buildTooltipConfig(t('rightSidePanel.togglePanel')) ) diff --git a/src/components/common/SearchBox.vue b/src/components/common/SearchBox.vue index 8fbf3a34a0..00b705ce17 100644 --- a/src/components/common/SearchBox.vue +++ b/src/components/common/SearchBox.vue @@ -10,6 +10,7 @@ @click="$emit('showFilter', $event)" /> () +const inputRef = ref() + +defineExpose({ + focus: () => { + inputRef.value?.$el?.focus() + } +}) + const emitSearch = debounce((value: string) => { emit('search', value, filters) }, debounceTime) diff --git a/src/components/common/VirtualGrid.vue b/src/components/common/VirtualGrid.vue index 89de6e421b..134778778a 100644 --- a/src/components/common/VirtualGrid.vue +++ b/src/components/common/VirtualGrid.vue @@ -117,16 +117,7 @@ onBeforeUnmount(() => { .scroll-container { height: 100%; overflow-y: auto; - - /* Firefox */ - scrollbar-width: none; - - &::-webkit-scrollbar { - width: 1px; - } - - &::-webkit-scrollbar-thumb { - background-color: transparent; - } + scrollbar-width: thin; + scrollbar-color: var(--dialog-surface) transparent; } diff --git a/src/components/graph/GraphCanvas.vue b/src/components/graph/GraphCanvas.vue index 3d10328e62..35f2290340 100644 --- a/src/components/graph/GraphCanvas.vue +++ b/src/components/graph/GraphCanvas.vue @@ -132,7 +132,7 @@ import { useCopy } from '@/composables/useCopy' import { useGlobalLitegraph } from '@/composables/useGlobalLitegraph' import { usePaste } from '@/composables/usePaste' import { useVueFeatureFlags } from '@/composables/useVueFeatureFlags' -import { i18n, t } from '@/i18n' +import { mergeCustomNodesI18n, t } from '@/i18n' import { LiteGraph } from '@/lib/litegraph/src/litegraph' import { useLitegraphSettings } from '@/platform/settings/composables/useLitegraphSettings' import { CORE_SETTINGS } from '@/platform/settings/constants/coreSettings' @@ -391,9 +391,7 @@ useEventListener( const loadCustomNodesI18n = async () => { try { const i18nData = await api.getCustomNodesI18n() - Object.entries(i18nData).forEach(([locale, message]) => { - i18n.global.mergeLocaleMessage(locale, message) - }) + mergeCustomNodesI18n(i18nData) } catch (error) { console.error('Failed to load custom nodes i18n', error) } diff --git a/src/components/queue/job/JobGroupsList.vue b/src/components/queue/job/JobGroupsList.vue index 2aee8b03e0..482016d346 100644 --- a/src/components/queue/job/JobGroupsList.vue +++ b/src/components/queue/job/JobGroupsList.vue @@ -36,12 +36,12 @@ diff --git a/src/components/queue/job/QueueJobItem.vue b/src/components/queue/job/QueueJobItem.vue index fc9c8d6d0e..9936b47c6a 100644 --- a/src/components/queue/job/QueueJobItem.vue +++ b/src/components/queue/job/QueueJobItem.vue @@ -361,7 +361,10 @@ const baseActions = computed(() => { ariaLabel: t('g.delete'), tooltip: deleteTooltipConfig.value, isVisible: () => props.state === 'failed' && computedShowClear.value, - onClick: () => emit('delete') + onClick: () => { + onRowLeave() + emit('delete') + } }, { key: 'cancel-hover', @@ -377,7 +380,10 @@ const baseActions = computed(() => { props.state !== 'running' && props.state !== 'failed' && computedShowClear.value, - onClick: () => emit('cancel') + onClick: () => { + onRowLeave() + emit('cancel') + } }, { key: 'view', @@ -401,7 +407,10 @@ const baseActions = computed(() => { ariaLabel: t('g.cancel'), tooltip: cancelTooltipConfig.value, isVisible: () => props.state === 'running' && computedShowClear.value, - onClick: () => emit('cancel') + onClick: () => { + onRowLeave() + emit('cancel') + } } ] }) diff --git a/src/components/sidebar/tabs/ModelLibrarySidebarTab.vue b/src/components/sidebar/tabs/ModelLibrarySidebarTab.vue index 9ff7bd7638..c5cf5e9bd0 100644 --- a/src/components/sidebar/tabs/ModelLibrarySidebarTab.vue +++ b/src/components/sidebar/tabs/ModelLibrarySidebarTab.vue @@ -21,6 +21,7 @@