diff --git a/.storybook/main.ts b/.storybook/main.ts index 0c576b0bde..68e22b2831 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -100,8 +100,7 @@ const config: StorybookConfig = { rolldownOptions: { treeshake: false, output: { - keepNames: true, - strictExecutionOrder: true + keepNames: true }, onwarn: (warning, warn) => { // Suppress specific warnings diff --git a/browser_tests/fixtures/components/SettingDialog.ts b/browser_tests/fixtures/components/SettingDialog.ts index 4587d85f31..4965c08a8b 100644 --- a/browser_tests/fixtures/components/SettingDialog.ts +++ b/browser_tests/fixtures/components/SettingDialog.ts @@ -23,9 +23,7 @@ export class SettingDialog extends BaseDialog { * @param value - The value to set */ async setStringSetting(id: string, value: string) { - const settingInputDiv = this.page.locator( - `div.settings-container div[id="${id}"]` - ) + const settingInputDiv = this.root.locator(`div[id="${id}"]`) await settingInputDiv.locator('input').fill(value) } @@ -34,16 +32,31 @@ export class SettingDialog extends BaseDialog { * @param id - The id of the setting */ async toggleBooleanSetting(id: string) { - const settingInputDiv = this.page.locator( - `div.settings-container div[id="${id}"]` - ) + const settingInputDiv = this.root.locator(`div[id="${id}"]`) await settingInputDiv.locator('input').click() } + get searchBox() { + return this.root.getByPlaceholder(/Search/) + } + + get categories() { + return this.root.locator('nav').getByRole('button') + } + + category(name: string) { + return this.root.locator('nav').getByRole('button', { name }) + } + + get contentArea() { + return this.root.getByRole('main') + } + async goToAboutPanel() { - await this.page.getByTestId(TestIds.dialogs.settingsTabAbout).click() - await this.page - .getByTestId(TestIds.dialogs.about) - .waitFor({ state: 'visible' }) + const aboutButton = this.root.locator('nav').getByRole('button', { + name: 'About' + }) + await aboutButton.click() + await this.page.waitForSelector('.about-container') } } diff --git a/browser_tests/tests/bottomPanelShortcuts.spec.ts b/browser_tests/tests/bottomPanelShortcuts.spec.ts index fba61ebd4b..bebba30de1 100644 --- a/browser_tests/tests/bottomPanelShortcuts.spec.ts +++ b/browser_tests/tests/bottomPanelShortcuts.spec.ts @@ -226,9 +226,7 @@ test.describe('Bottom Panel Shortcuts', { tag: '@ui' }, () => { await expect(bottomPanel.shortcuts.manageButton).toBeVisible() await bottomPanel.shortcuts.manageButton.click() - await expect(comfyPage.page.getByRole('dialog')).toBeVisible() - await expect( - comfyPage.page.getByRole('option', { name: 'Keybinding' }) - ).toBeVisible() + await expect(comfyPage.settingDialog.root).toBeVisible() + await expect(comfyPage.settingDialog.category('Keybinding')).toBeVisible() }) }) diff --git a/browser_tests/tests/dialog.spec.ts b/browser_tests/tests/dialog.spec.ts index c954177d63..eed31cc354 100644 --- a/browser_tests/tests/dialog.spec.ts +++ b/browser_tests/tests/dialog.spec.ts @@ -244,9 +244,13 @@ test.describe('Missing models warning', () => { test.describe('Settings', () => { test('@mobile Should be visible on mobile', async ({ comfyPage }) => { await comfyPage.page.keyboard.press('Control+,') - const settingsContent = comfyPage.page.locator('.settings-content') - await expect(settingsContent).toBeVisible() - const isUsableHeight = await settingsContent.evaluate( + const settingsDialog = comfyPage.page.locator( + '[data-testid="settings-dialog"]' + ) + await expect(settingsDialog).toBeVisible() + const contentArea = settingsDialog.locator('main') + await expect(contentArea).toBeVisible() + const isUsableHeight = await contentArea.evaluate( (el) => el.clientHeight > 30 ) expect(isUsableHeight).toBeTruthy() @@ -256,7 +260,9 @@ test.describe('Settings', () => { await comfyPage.page.keyboard.down('ControlOrMeta') await comfyPage.page.keyboard.press(',') await comfyPage.page.keyboard.up('ControlOrMeta') - const settingsLocator = comfyPage.page.locator('.settings-container') + const settingsLocator = comfyPage.page.locator( + '[data-testid="settings-dialog"]' + ) await expect(settingsLocator).toBeVisible() await comfyPage.page.keyboard.press('Escape') await expect(settingsLocator).not.toBeVisible() @@ -275,10 +281,15 @@ test.describe('Settings', () => { test('Should persist keybinding setting', async ({ comfyPage }) => { // Open the settings dialog await comfyPage.page.keyboard.press('Control+,') - await comfyPage.page.waitForSelector('.settings-container') + await comfyPage.page.waitForSelector('[data-testid="settings-dialog"]') // Open the keybinding tab - await comfyPage.page.getByLabel('Keybinding').click() + const settingsDialog = comfyPage.page.locator( + '[data-testid="settings-dialog"]' + ) + await settingsDialog + .locator('nav [role="button"]', { hasText: 'Keybinding' }) + .click() await comfyPage.page.waitForSelector( '[placeholder="Search Keybindings..."]' ) diff --git a/browser_tests/tests/interaction.spec.ts-snapshots/dragged-node1-chromium-linux.png b/browser_tests/tests/interaction.spec.ts-snapshots/dragged-node1-chromium-linux.png index 188f5b9c97..9bbb027fbd 100644 Binary files a/browser_tests/tests/interaction.spec.ts-snapshots/dragged-node1-chromium-linux.png and b/browser_tests/tests/interaction.spec.ts-snapshots/dragged-node1-chromium-linux.png differ diff --git a/browser_tests/tests/mobileBaseline.spec.ts-snapshots/mobile-settings-dialog-mobile-chrome-linux.png b/browser_tests/tests/mobileBaseline.spec.ts-snapshots/mobile-settings-dialog-mobile-chrome-linux.png index 17de9b03af..71d6ea44e0 100644 Binary files a/browser_tests/tests/mobileBaseline.spec.ts-snapshots/mobile-settings-dialog-mobile-chrome-linux.png and b/browser_tests/tests/mobileBaseline.spec.ts-snapshots/mobile-settings-dialog-mobile-chrome-linux.png differ diff --git a/browser_tests/tests/subgraph.spec.ts b/browser_tests/tests/subgraph.spec.ts index c937573dfc..d31c3bd6a8 100644 --- a/browser_tests/tests/subgraph.spec.ts +++ b/browser_tests/tests/subgraph.spec.ts @@ -826,7 +826,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { // Open settings dialog using hotkey await comfyPage.page.keyboard.press('Control+,') - await comfyPage.page.waitForSelector('.settings-container', { + await comfyPage.page.waitForSelector('[data-testid="settings-dialog"]', { state: 'visible' }) @@ -836,7 +836,7 @@ test.describe('Subgraph Operations', { tag: ['@slow', '@subgraph'] }, () => { // Dialog should be closed await expect( - comfyPage.page.locator('.settings-container') + comfyPage.page.locator('[data-testid="settings-dialog"]') ).not.toBeVisible() // Should still be in subgraph diff --git a/browser_tests/tests/templates.spec.ts-snapshots/template-grid-varying-content-chromium-linux.png b/browser_tests/tests/templates.spec.ts-snapshots/template-grid-varying-content-chromium-linux.png index b1e97d8f80..14b99a2604 100644 Binary files a/browser_tests/tests/templates.spec.ts-snapshots/template-grid-varying-content-chromium-linux.png and b/browser_tests/tests/templates.spec.ts-snapshots/template-grid-varying-content-chromium-linux.png differ diff --git a/browser_tests/tests/useSettingSearch.spec.ts b/browser_tests/tests/useSettingSearch.spec.ts index 43ddd09e79..d71807025f 100644 --- a/browser_tests/tests/useSettingSearch.spec.ts +++ b/browser_tests/tests/useSettingSearch.spec.ts @@ -22,7 +22,6 @@ test.describe('Settings Search functionality', { tag: '@settings' }, () => { name: 'TestSettingsExtension', settings: [ { - // Extensions can register arbitrary setting IDs id: 'TestHiddenSetting' as TestSettingId, name: 'Test Hidden Setting', type: 'hidden', @@ -30,7 +29,6 @@ test.describe('Settings Search functionality', { tag: '@settings' }, () => { category: ['Test', 'Hidden'] }, { - // Extensions can register arbitrary setting IDs id: 'TestDeprecatedSetting' as TestSettingId, name: 'Test Deprecated Setting', type: 'text', @@ -39,7 +37,6 @@ test.describe('Settings Search functionality', { tag: '@settings' }, () => { category: ['Test', 'Deprecated'] }, { - // Extensions can register arbitrary setting IDs id: 'TestVisibleSetting' as TestSettingId, name: 'Test Visible Setting', type: 'text', @@ -52,238 +49,143 @@ test.describe('Settings Search functionality', { tag: '@settings' }, () => { }) test('can open settings dialog and use search box', async ({ comfyPage }) => { - // Open settings dialog - await comfyPage.page.keyboard.press('Control+,') - const settingsDialog = comfyPage.page.locator('.settings-container') - await expect(settingsDialog).toBeVisible() + const dialog = comfyPage.settingDialog + await dialog.open() - // Find the search box - const searchBox = comfyPage.page.locator('.settings-search-box input') - await expect(searchBox).toBeVisible() - - // Verify search box has the correct placeholder - await expect(searchBox).toHaveAttribute( + await expect(dialog.searchBox).toHaveAttribute( 'placeholder', expect.stringContaining('Search') ) }) test('search box is functional and accepts input', async ({ comfyPage }) => { - // Open settings dialog - await comfyPage.page.keyboard.press('Control+,') - const settingsDialog = comfyPage.page.locator('.settings-container') - await expect(settingsDialog).toBeVisible() + const dialog = comfyPage.settingDialog + await dialog.open() - // Find and interact with the search box - const searchBox = comfyPage.page.locator('.settings-search-box input') - await searchBox.fill('Comfy') - - // Verify the input was accepted - await expect(searchBox).toHaveValue('Comfy') + await dialog.searchBox.fill('Comfy') + await expect(dialog.searchBox).toHaveValue('Comfy') }) test('search box clears properly', async ({ comfyPage }) => { - // Open settings dialog - await comfyPage.page.keyboard.press('Control+,') - const settingsDialog = comfyPage.page.locator('.settings-container') - await expect(settingsDialog).toBeVisible() + const dialog = comfyPage.settingDialog + await dialog.open() - // Find and interact with the search box - const searchBox = comfyPage.page.locator('.settings-search-box input') - await searchBox.fill('test') - await expect(searchBox).toHaveValue('test') + await dialog.searchBox.fill('test') + await expect(dialog.searchBox).toHaveValue('test') - // Clear the search box - await searchBox.clear() - await expect(searchBox).toHaveValue('') + await dialog.searchBox.clear() + await expect(dialog.searchBox).toHaveValue('') }) test('settings categories are visible in sidebar', async ({ comfyPage }) => { - // Open settings dialog - await comfyPage.page.keyboard.press('Control+,') - const settingsDialog = comfyPage.page.locator('.settings-container') - await expect(settingsDialog).toBeVisible() + const dialog = comfyPage.settingDialog + await dialog.open() - // Check that the sidebar has categories - const categories = comfyPage.page.locator( - '.settings-sidebar .p-listbox-option' - ) - expect(await categories.count()).toBeGreaterThan(0) - - // Check that at least one category is visible - await expect(categories.first()).toBeVisible() + expect(await dialog.categories.count()).toBeGreaterThan(0) }) test('can select different categories in sidebar', async ({ comfyPage }) => { - // Open settings dialog - await comfyPage.page.keyboard.press('Control+,') - const settingsDialog = comfyPage.page.locator('.settings-container') - await expect(settingsDialog).toBeVisible() + const dialog = comfyPage.settingDialog + await dialog.open() - // Click on a specific category (Appearance) to verify category switching - const appearanceCategory = comfyPage.page.getByRole('option', { - name: 'Appearance' - }) - await appearanceCategory.click() + const categoryCount = await dialog.categories.count() - // Verify the category is selected - await expect(appearanceCategory).toHaveClass(/p-listbox-option-selected/) - }) + if (categoryCount > 1) { + await dialog.categories.nth(1).click() - test('settings content area is visible', async ({ comfyPage }) => { - // Open settings dialog - await comfyPage.page.keyboard.press('Control+,') - const settingsDialog = comfyPage.page.locator('.settings-container') - await expect(settingsDialog).toBeVisible() - - // Check that the content area is visible - const contentArea = comfyPage.page.locator('.settings-content') - await expect(contentArea).toBeVisible() - - // Check that tab panels are visible - const tabPanels = comfyPage.page.locator('.settings-tab-panels') - await expect(tabPanels).toBeVisible() + await expect(dialog.categories.nth(1)).toHaveClass( + /bg-interface-menu-component-surface-selected/ + ) + } }) test('search functionality affects UI state', async ({ comfyPage }) => { - // Open settings dialog - await comfyPage.page.keyboard.press('Control+,') - const settingsDialog = comfyPage.page.locator('.settings-container') - await expect(settingsDialog).toBeVisible() + const dialog = comfyPage.settingDialog + await dialog.open() - // Find the search box - const searchBox = comfyPage.page.locator('.settings-search-box input') - - // Type in search box - await searchBox.fill('graph') - - // Verify that the search input is handled - await expect(searchBox).toHaveValue('graph') + await dialog.searchBox.fill('graph') + await expect(dialog.searchBox).toHaveValue('graph') }) test('settings dialog can be closed', async ({ comfyPage }) => { - // Open settings dialog - await comfyPage.page.keyboard.press('Control+,') - const settingsDialog = comfyPage.page.locator('.settings-container') - await expect(settingsDialog).toBeVisible() + const dialog = comfyPage.settingDialog + await dialog.open() - // Close with escape key await comfyPage.page.keyboard.press('Escape') - - // Verify dialog is closed - await expect(settingsDialog).not.toBeVisible() + await expect(dialog.root).not.toBeVisible() }) test('search box has proper debouncing behavior', async ({ comfyPage }) => { - // Open settings dialog - await comfyPage.page.keyboard.press('Control+,') - const settingsDialog = comfyPage.page.locator('.settings-container') - await expect(settingsDialog).toBeVisible() + const dialog = comfyPage.settingDialog + await dialog.open() - // Type rapidly in search box - const searchBox = comfyPage.page.locator('.settings-search-box input') - await searchBox.fill('a') - await searchBox.fill('ab') - await searchBox.fill('abc') - await searchBox.fill('abcd') + await dialog.searchBox.fill('a') + await dialog.searchBox.fill('ab') + await dialog.searchBox.fill('abc') + await dialog.searchBox.fill('abcd') - // Verify final value - await expect(searchBox).toHaveValue('abcd') + await expect(dialog.searchBox).toHaveValue('abcd') }) test('search excludes hidden settings from results', async ({ comfyPage }) => { - // Open settings dialog - await comfyPage.page.keyboard.press('Control+,') - const settingsDialog = comfyPage.page.locator('.settings-container') - await expect(settingsDialog).toBeVisible() + const dialog = comfyPage.settingDialog + await dialog.open() - // Search for our test settings - const searchBox = comfyPage.page.locator('.settings-search-box input') - await searchBox.fill('Test') + await dialog.searchBox.fill('Test') - // Get all settings content - const settingsContent = comfyPage.page.locator('.settings-tab-panels') - - // Should show visible setting but not hidden setting - await expect(settingsContent).toContainText('Test Visible Setting') - await expect(settingsContent).not.toContainText('Test Hidden Setting') + await expect(dialog.contentArea).toContainText('Test Visible Setting') + await expect(dialog.contentArea).not.toContainText('Test Hidden Setting') }) test('search excludes deprecated settings from results', async ({ comfyPage }) => { - // Open settings dialog - await comfyPage.page.keyboard.press('Control+,') - const settingsDialog = comfyPage.page.locator('.settings-container') - await expect(settingsDialog).toBeVisible() + const dialog = comfyPage.settingDialog + await dialog.open() - // Search for our test settings - const searchBox = comfyPage.page.locator('.settings-search-box input') - await searchBox.fill('Test') + await dialog.searchBox.fill('Test') - // Get all settings content - const settingsContent = comfyPage.page.locator('.settings-tab-panels') - - // Should show visible setting but not deprecated setting - await expect(settingsContent).toContainText('Test Visible Setting') - await expect(settingsContent).not.toContainText('Test Deprecated Setting') + await expect(dialog.contentArea).toContainText('Test Visible Setting') + await expect(dialog.contentArea).not.toContainText( + 'Test Deprecated Setting' + ) }) test('search shows visible settings but excludes hidden and deprecated', async ({ comfyPage }) => { - // Open settings dialog - await comfyPage.page.keyboard.press('Control+,') - const settingsDialog = comfyPage.page.locator('.settings-container') - await expect(settingsDialog).toBeVisible() + const dialog = comfyPage.settingDialog + await dialog.open() - // Search for our test settings - const searchBox = comfyPage.page.locator('.settings-search-box input') - await searchBox.fill('Test') + await dialog.searchBox.fill('Test') - // Get all settings content - const settingsContent = comfyPage.page.locator('.settings-tab-panels') - - // Should only show the visible setting - await expect(settingsContent).toContainText('Test Visible Setting') - - // Should not show hidden or deprecated settings - await expect(settingsContent).not.toContainText('Test Hidden Setting') - await expect(settingsContent).not.toContainText('Test Deprecated Setting') + await expect(dialog.contentArea).toContainText('Test Visible Setting') + await expect(dialog.contentArea).not.toContainText('Test Hidden Setting') + await expect(dialog.contentArea).not.toContainText( + 'Test Deprecated Setting' + ) }) test('search by setting name excludes hidden and deprecated', async ({ comfyPage }) => { - // Open settings dialog - await comfyPage.page.keyboard.press('Control+,') - const settingsDialog = comfyPage.page.locator('.settings-container') - await expect(settingsDialog).toBeVisible() + const dialog = comfyPage.settingDialog + await dialog.open() - const searchBox = comfyPage.page.locator('.settings-search-box input') - const settingsContent = comfyPage.page.locator('.settings-tab-panels') + await dialog.searchBox.clear() + await dialog.searchBox.fill('Hidden') + await expect(dialog.contentArea).not.toContainText('Test Hidden Setting') - // Search specifically for hidden setting by name - await searchBox.clear() - await searchBox.fill('Hidden') + await dialog.searchBox.clear() + await dialog.searchBox.fill('Deprecated') + await expect(dialog.contentArea).not.toContainText( + 'Test Deprecated Setting' + ) - // Should not show the hidden setting even when searching by name - await expect(settingsContent).not.toContainText('Test Hidden Setting') - - // Search specifically for deprecated setting by name - await searchBox.clear() - await searchBox.fill('Deprecated') - - // Should not show the deprecated setting even when searching by name - await expect(settingsContent).not.toContainText('Test Deprecated Setting') - - // Search for visible setting by name - should work - await searchBox.clear() - await searchBox.fill('Visible') - - // Should show the visible setting - await expect(settingsContent).toContainText('Test Visible Setting') + await dialog.searchBox.clear() + await dialog.searchBox.fill('Visible') + await expect(dialog.contentArea).toContainText('Test Visible Setting') }) }) diff --git a/src/components/bottomPanel/BottomPanel.vue b/src/components/bottomPanel/BottomPanel.vue index aa68006779..08f23c5098 100644 --- a/src/components/bottomPanel/BottomPanel.vue +++ b/src/components/bottomPanel/BottomPanel.vue @@ -89,12 +89,12 @@ import { useI18n } from 'vue-i18n' import ExtensionSlot from '@/components/common/ExtensionSlot.vue' import Button from '@/components/ui/button/Button.vue' -import { useDialogService } from '@/services/dialogService' +import { useSettingsDialog } from '@/platform/settings/composables/useSettingsDialog' import { useBottomPanelStore } from '@/stores/workspace/bottomPanelStore' import type { BottomPanelExtension } from '@/types/extensionTypes' const bottomPanelStore = useBottomPanelStore() -const dialogService = useDialogService() +const settingsDialog = useSettingsDialog() const { t } = useI18n() const isShortcutsTabActive = computed(() => { @@ -115,7 +115,7 @@ const getTabDisplayTitle = (tab: BottomPanelExtension): string => { } const openKeybindingSettings = async () => { - dialogService.showSettingsDialog('keybinding') + settingsDialog.show('keybinding') } const closeBottomPanel = () => { diff --git a/src/components/custom/widget/WorkflowTemplateSelectorDialog.vue b/src/components/custom/widget/WorkflowTemplateSelectorDialog.vue index 857356a42c..60c3fb9f6c 100644 --- a/src/components/custom/widget/WorkflowTemplateSelectorDialog.vue +++ b/src/components/custom/widget/WorkflowTemplateSelectorDialog.vue @@ -1,7 +1,7 @@