- Fix widgetTextBox locator in ComfyPage
- Add exact match for 'Add' button in search filter panel
- Fix ClipboardHelper to properly handle undefined vs null locators
- Use canvasOps.dragAndDrop in NodeOperationsHelper
- Use nodeOps.waitForGraphNodes in link interaction tests
- Add typecheck:browser script for browser tests
Amp-Thread-ID: https://ampcode.com/threads/T-019c1696-c595-7724-8dca-64f73f19f478
Co-authored-by: Amp <amp@ampcode.com>
Phase 2 of ComfyPage refactor:
- Add ToastHelper, DragDropHelper, CommandHelper instances to ComfyPage
- Remove migrated methods from ComfyPage (command, toast, dragDrop, workflow, canvasOps, nodeOps methods)
- Update all test files to use new helper paths
- Keep visibleToasts as passthrough getter for backward compatibility
Amp-Thread-ID: https://ampcode.com/threads/T-019c1666-ed27-773c-976a-07cc805d7a6c
Co-authored-by: Amp <amp@ampcode.com>
- nodeSearchBox.spec.ts: Use NodeReference.getOutput() for CLIP output slot position
- rightClickMenu.spec.ts: Use NodeReference.getTitlePosition() for node dragging
- Add getTitlePosition() helper to NodeReference for drag operations
Amp-Thread-ID: https://ampcode.com/threads/T-019c1367-6a59-7752-9329-17cbf152fc62
Co-authored-by: Amp <amp@ampcode.com>
Migrate all test callers to use helper classes directly:
- nodeOps: getGraphNodesCount, getNodeRefById, selectNodes, etc.
- canvasOps: dragAndDrop, zoom, pan, resetView, etc.
- subgraph: rightClickInputSlot, connectToOutput, etc.
Reduces ComfyPage.ts from 1335 to 1085 lines (-250 lines).
Amp-Thread-ID: https://ampcode.com/threads/T-019c1318-58b7-757f-801c-5b676f0d3421
Co-authored-by: Amp <amp@ampcode.com>
- Create browser_tests/fixtures/constants/defaultGraphPositions.ts with all hardcoded default graph positions
- Create browser_tests/fixtures/constants/types.ts with Position and Size interfaces
- Update ComfyPage.ts to import and use DefaultGraphPositions
- Reduces duplication and prepares for further modular extraction
Amp-Thread-ID: https://ampcode.com/threads/T-019c1201-adec-7363-96d5-446d0a98e4cf
Co-authored-by: Amp <amp@ampcode.com>
Per Playwright best practices, assertions belong in tests, not fixtures.
Fixture methods should use waitFor() for preconditions instead.
- vueNodeFixtures.ts: setTitle(), cancelTitleEdit() use waitFor()
- Topbar.ts: closeTopbarMenu() uses waitFor({ state: 'hidden' })
- ComfyPage.ts: ConfirmDialog.click(), closeDialog(), clickDialogButton(),
closeToasts() all converted to waitFor()
- templates.ts: renamed waitForMinimumCardCount to expectMinimumCardCount
to clarify it contains an assertion (uses expect().toPass() pattern)
Amp-Thread-ID: https://ampcode.com/threads/T-019c11f8-acd2-7429-8bec-525ad47a47c4
Co-authored-by: Amp <amp@ampcode.com>
- widget.spec.ts: use expect().toPass() for combo refresh
- subgraph.spec.ts: use comfyPage.setup() after reload
- nodeLibrary.spec.ts: use toHaveCount() for debounced search
- remoteWidgets.spec.ts: use expect().toPass() for backoff test
- litegraphUtils.ts: refactor navigateIntoSubgraph to use toPass()
Amp-Thread-ID: https://ampcode.com/threads/T-019c11f1-e839-772c-8890-b77cfdf70124
Co-authored-by: Amp <amp@ampcode.com>
## Summary
Migrate keybindings domain to `src/platform/keybindings/` following DDD
principles.
## Changes
- **What**: Consolidate keybinding-related code (types, store, service,
defaults, reserved keys) into a single domain module with flat structure
- Extracted `KeyComboImpl` and `KeybindingImpl` classes into separate
files
- Updated all consumers to import from new location
- Colocated tests with source files
- Updated stores/README.md and services/README.md to remove migrated
entries
## Review Focus
- Verify all import paths were updated correctly
- Check that the flat structure is appropriate (vs nested core/data/ui
layers)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8369-refactor-migrate-keybindings-to-DDD-structure-2f66d73d36508120b169dc737075fb45)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Subagent 5 <subagent@example.com>
Co-authored-by: Amp <amp@ampcode.com>
The image input for nodes loaded from templates appears empty in the
Properties Panel.
When the widget's current value (saved in the template) is not in the
available file list returned by the server, the selectedSet is empty,
causing a placeholder to be displayed instead of the actual value.
Added a missingValueItem computed property in WidgetSelectDropdown.vue.
When the current value is not in inputItems or outputItems, it creates a
fallback item and adds it to dropdownItems.
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8276-fix-default-image-input-for-the-template-is-displayed-as-empty-on-dropdown-selection-2f16d73d3650817eaad5e4e33637fb74)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: github-actions <github-actions@github.com>
## Summary
Refactors bootstrap and lifecycle management to parallelize
initialization, use Vue best practices, and fix a logout state bug.
## Changes
### Bootstrap Store (`bootstrapStore.ts`)
- Extract early bootstrap logic into a dedicated store using
`useAsyncState`
- Parallelize settings, i18n, and workflow sync loading (previously
sequential)
- Handle multi-user login scenarios by deferring settings/workflows
until authenticated
### GraphCanvas Refactoring
- Move non-DOM composables (`useGlobalLitegraph`, `useCopy`, `usePaste`,
etc.) to script setup level for earlier initialization
- Move `watch` and `whenever` declarations outside `onMounted` (Vue best
practice)
- Use `until()` from VueUse to await bootstrap store readiness instead
of direct async calls
### GraphView Simplification
- Replace manual `addEventListener`/`removeEventListener` with
`useEventListener`
- Replace `setInterval` with `useIntervalFn` for automatic cleanup
- Move core command registration to script setup level
### Bug Fix
Using `router.push()` for logout caused `isSettingsReady` to persist as
`true`, making new users inherit the previous user's cached settings.
Reverted to `window.location.reload()` with TODOs for future store reset
implementation.
## Testing
- Verified login/logout cycle clears settings correctly
- Verified bootstrap sequence completes without errors
---------
Co-authored-by: Amp <amp@ampcode.com>
## Summary
- Keep all drafts in localStorage, mirroring the logic from VSCode.
- Fix a bug where newly created blank workflow tabs would incorrectly
restore as defaultGraph instead of blankGraph after page refresh.
Resolves https://github.com/Comfy-Org/desktop/issues/910, Resolves
https://github.com/Comfy-Org/ComfyUI_frontend/issues/4057, Fixes
https://github.com/Comfy-Org/ComfyUI_frontend/issues/3665
## Changes
### What
- Fix `restoreWorkflowTabsState` to parse and pass workflow data from
drafts when recreating temporary workflows
- Add error handling for invalid draft data with fallback to default
workflow
- Fix E2E test `should not serialize color adjustments in workflow` to
wait for workflow persistence before assertions
- Add proper validation for workflow nodes array in test assertions
### Breaking
- None
### Dependencies
- No new dependencies added
## Review Focus
1. **Workflow restoration**: Verify that blank workflows correctly
restore as blankGraph after page refresh
2. **Error handling**: Check that invalid draft data gracefully falls
back to default workflow
3. **Test coverage**: Ensure E2E test correctly waits for workflow
persistence before checking node properties
4. **Edge cases**: Test with multiple tabs, switching between tabs, and
rapid refresh scenarios
---------
Co-authored-by: Yourz <crazilou@vip.qq.com>
Refactors modal dialog layouts for improved flexibility and consistency.
**Changes:**
- Add dedicated slot for left panel header title with dynamic
content/icons
- Consolidate side panel rendering within `BaseModalLayout`
- Remove redundant `PanelHeader` and `RightSidePanel` components
- Apply `select-none` to text elements to prevent accidental selection
---------
Co-authored-by: Amp <amp@ampcode.com>
## Summary
Improves type safety in test files by replacing unsafe type patterns
with proper TypeScript idioms.
## Changes
- Define typed `TestWindow` interface extending `Window` for Playwright
tests with custom properties
- Use `Partial<HTMLElement>` with single type assertion for DOM element
mocks
- Remove redundant type imports
- Fix `console.log` → `console.warn` in test fixture
## Files Changed
16 test files across browser_tests, packages, and src/components
## Test Plan
- ✅ `pnpm typecheck` passes
- ✅ No new `any` types introduced
- ✅ All pre-commit hooks pass
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8253-refactor-improve-TypeScript-patterns-in-test-files-Group-1-8-2f16d73d365081548f9ece7bcf0525ee)
by [Unito](https://www.unito.io)
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
## Summary
Refactors `BaseModalLayout` from a flexbox-based layout to CSS Grid,
enabling smoother panel transitions and improved layout control.
## Changes
### Layout Restructure
- **Flexbox → CSS Grid**: Replaced nested flexbox with a 3-column CSS
Grid (`nav | main | aside`)
- **Smooth panel transitions**: Panel show/hide now animates via
`grid-template-columns` instead of Vue `<Transition>` with `translateX`
- **Removed transition CSS**: Deleted `.slide-panel-*` and `.fade-*`
transition styles (no longer needed with grid approach)
### Right Panel Improvements
- **Dedicated header**: Added header with close button, right panel
toggle, and customizable title slot (`rightPanelHeaderTitle`,
`rightPanelHeaderActions`)
- **New prop**: Added `rightPanelTitle` prop for simple text title in
right panel header
### UX & Accessibility
- **ESC key handling**: Pressing Escape closes the right panel (if open)
before closing the dialog
- **Accessibility**: Added `aria-label` attributes to all panel toggle
and close buttons
- **i18n**: Added translation keys: `showLeftPanel`, `hideLeftPanel`,
`showRightPanel`, `hideRightPanel`, `closeDialog`
---------
Co-authored-by: Amp <amp@ampcode.com>