Commit Graph

233 Commits

Author SHA1 Message Date
jaeone94
cbc479d8b4 refactor: extract test helpers and use UI-based subgraph entry in draft position test (#11327)
## Summary

Follow-up to #10828. Addresses all deferred review nits from @DrJKL
tracked in #10932.

- Remove YAGNI `timeout` parameter from `waitForDraftPersisted` —
default 5s from `waitForFunction` is sufficient
- Extract `reloadAndWaitForApp()` into `WorkflowHelper` — preserves
localStorage (drafts) and URL hash (subgraph navigation), unlike
`ComfyPage.setup()` which clears storage and navigates to base URL
- Replace programmatic `canvas.setGraph()` with
`vueNodes.enterSubgraph()` for real UI-based subgraph entry
- Add `@vue-nodes` tag required for `enterSubgraph()` button rendering
- Extract `getSubgraphNodePositions` to deduplicate three identical
inline `page.evaluate` calls
- Fix vacuous pass: capture `positionsBefore` inside `expect.poll` to
ensure the array is non-empty before the verification loop
- Remove inline comments, relying on descriptive helper method names

## Test plan

- [x] `pnpm typecheck:browser` passes
- [x] `pnpm lint` passes
- [x] `pnpm test:browser:local --
browser_tests/tests/subgraph/subgraphDraftPositions.spec.ts` passes
locally

Fixes #10932

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11327-refactor-extract-test-helpers-and-use-UI-based-subgraph-entry-in-draft-position-test-3456d73d3650813cacc1e69398e3f80a)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: GitHub Action <action@github.com>
2026-04-22 07:59:44 +00:00
Dante
2c772077e0 test: add E2E tests for billing dialogs (CancelSubscription, TopUpCredits) (#10969)
## Summary
- Add Playwright E2E tests for `CancelSubscriptionDialogContent` and
`TopUpCreditsDialogContentLegacy`
- CancelSubscription tests: dialog display with date formatting, keep
subscription dismiss, confirm cancel with mocked API, error handling on
API failure
- TopUpCredits tests: dialog display with preset amounts, insufficient
credits variant, preset selection, close button dismiss, pricing link
visibility

Part of the FixIt Burndown test coverage initiative (Untested Dialogs).

## Test plan
- [ ] Verify tests pass in CI against OSS build
- [ ] `pnpm test:browser:local --
browser_tests/tests/dialogs/cancelSubscriptionDialog.spec.ts`
- [ ] `pnpm test:browser:local --
browser_tests/tests/dialogs/topUpCreditsDialog.spec.ts`

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10969-test-add-E2E-tests-for-billing-dialogs-CancelSubscription-TopUpCredits-33c6d73d36508164b268c08c99464ca1)
by [Unito](https://www.unito.io)
2026-04-21 23:17:58 +00:00
pythongosssss
9ed7a7bd87 test: Add tests for help center (#11475)
## Summary

Test coverage for help center & associated popups

## Changes

- **What**: 
- Adds HelpCenterHelper for mocking endpoints and locators
- Tests for popup, menu items & positioning

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11475-test-Add-tests-for-help-center-3486d73d365081af91a2eb7465e503fe)
by [Unito](https://www.unito.io)
2026-04-20 22:43:28 +00:00
pythongosssss
3e62033f09 test: extract TestIdValue as mapped type (#11474)
## Summary

Prevent needing to update the union with newly added keys

## Changes

- **What**: 
- Change the `TestIdValue` union to a mapped type, excluding function
values

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11474-test-extract-TestIdValue-as-mapped-type-3486d73d365081d299efd87a0c46d66f)
by [Unito](https://www.unito.io)
2026-04-20 20:52:58 +00:00
Benjamin Lu
d83c84aa85 test: extract asset api browser fixture (#11279)
## Summary

Move asset API mocking off `ComfyPage` and into a standalone Playwright
fixture.

## Changes

- add `assetApiFixture` for browser tests that need asset API mocking
- remove `assetApi` from `ComfyPage`
- migrate `browser_tests/tests/assetHelper.spec.ts` to use the
standalone fixture

## Why

This is the first slice of the browser-fixture split. It reduces global
fixture surface area without changing test behavior.

## Validation

- `pnpm typecheck:browser`
- `pnpm exec oxlint browser_tests/fixtures/ComfyPage.ts
browser_tests/fixtures/assetApiFixture.ts
browser_tests/tests/assetHelper.spec.ts --type-aware`
- repo hooks during commit/push: `pnpm typecheck`, `pnpm
typecheck:browser`, `pnpm knip`

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11279-test-extract-asset-api-browser-fixture-3436d73d3650818393bcd43dc909c8a2)
by [Unito](https://www.unito.io)
2026-04-20 18:37:45 +00:00
pythongosssss
35bfe509b3 test: add/update terminal tests (#11239)
## Summary

Adds test coverage for the integrated terminal

## Changes

- **What**: 
- refactor and simplify existing tests
- add new tests for xterm integration

┆Issue is synchronized with this [Notion
page](https://app.notion.com/p/PR-11239-test-add-update-terminal-tests-3426d73d365081c99445c35d8808afb4)
by [Unito](https://www.unito.io)
2026-04-20 10:11:37 +00:00
Christian Byrne
a1ba567dbc test: remove --listen 0.0.0.0 from E2E test mock argv (#11021)
## Summary

Remove `--listen 0.0.0.0` from mock `argv` in E2E test fixtures to avoid
normalizing a flag that exposes the server to all network interfaces.

## Changes

- **What**: Removed `--listen` and `0.0.0.0` from
`mockSystemStats.system.argv` in
`browser_tests/fixtures/data/systemStats.ts` (shared fixture) and the
ManagerDialog-specific override in
`browser_tests/tests/dialogs/managerDialog.spec.ts`. Neither value is
required for any test assertion.

Fixes #11008

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11021-test-remove-listen-0-0-0-0-from-E2E-test-mock-argv-33e6d73d365081c59d3fe9610afbeb6f)
by [Unito](https://www.unito.io)
2026-04-20 01:46:20 +00:00
jaeone94
b157182a20 refactor: inline node footer layout to fix selection bounding box (#10741)
## Summary

Refactor node footer from absolute overlay to inline flow layout, fixing
the selection bounding box not encompassing footer buttons and collapsed
node dimensions.

## Background

The node footer (Enter Subgraph, Advanced, Error buttons) was rendered
as an absolute overlay (`absolute top-full`) outside the node body. This
caused:

1. **Selection bounding box** did not include footer height — the dashed
multi-select border cut through footer buttons
2. **Footer offset compensation** required 3 hardcoded computed classes
(`footerStateOutlineBottomClass`, `footerRootBorderBottomClass`,
`footerResizeHandleBottomClass`) with magic pixel values (31px, 35px,
etc.) that had to stay in sync with CSS

## Solution: Inline Footer with `isolate -z-1`

The footer is moved into normal document flow (no longer `absolute
top-full`). The key challenge was keeping the footer visually behind the
body's rounded bottom edge (the "tuck under" effect) without adding
`z-index` to the body — because adding `z-index` to the body creates a
stacking context that traps slot connection dots, making them appear
behind overlay borders.

The solution uses CSS `isolation: isolate` combined with `-z-1` on the
footer wrapper:

- **`isolate`** creates an independent stacking context for the footer,
so internal z-index (Error button `z-10` above Enter button) does not
leak to the parent
- **`-z-1`** places the entire footer behind the body (`z-index: auto`),
achieving the visual overlap without touching the body's stacking
behavior
- **Slot dots remain free** — the body has no explicit z-index, so slots
participate in the root stacking context and are never trapped behind
overlay borders

This eliminates all 3 footer offset computed classes and their hardcoded
pixel values.

## Selection Box: `min-height` on root + unified size path

Moving `min-h-(--node-height)` from the body (`node-inner-wrapper`) to
the root element makes the footer height naturally included in
`node.size` via ResizeObserver → layoutStore → litegraph sync. This
means `boundingRect` is automatically correct for expanded nodes — no
callbacks or overrides needed.

For collapsed nodes, a pre-existing issue (since v1.40) caused
`_collapsed_width` to fall back to `NODE_COLLAPSED_WIDTH = 80px` because
Vue nodes lack a canvas context for text measurement.

The fix lets collapsed dimensions flow through the **same**
`batchUpdateNodeBounds` path as expanded nodes — no parallel data
structure, no separate accessor, no cache:

1. ResizeObserver writes the collapsed DOM dimensions to
`layoutStore.size` via `batchUpdateNodeBounds`
2. `useLayoutSync` syncs `layoutStore.size` → `liteNode.size` as it does
for any other size change
3. The expanded size survives the collapse→expand round trip via CSS
custom properties — the `isCollapsed` watcher in `LGraphNode.vue` swaps
`--node-width` to `--node-width-x` on collapse and restores it on expand
4. `measure()` reads `this.size` directly for Vue collapsed nodes via a
one-line gate: `if (!this.flags?.collapsed || LiteGraph.vueNodesMode)`.
Legacy behavior is unchanged.

## Changes

- **NodeFooter.vue**: `absolute top-full` overlay → inline flow with
`isolate -z-1` wrappers, Error/Enter button layering via `-mr-5` + DOM
order, reactive props destructuring, static `RADIUS_CLASS` lookup for
Tailwind scanning, Vue 3.3+ `defineEmits` property syntax
- **LGraphNode.vue**: Move `min-h-(--node-height)` from body to root;
remove `footerStateOutlineBottomClass`, `footerRootBorderBottomClass`,
`footerResizeHandleBottomClass`, `hasFooter` computed; replace dynamic
`beforeShapeClass` interpolation with static
`bypassOverlayClass`/`mutedOverlayClass` computeds for Tailwind scanning
- **LGraphNode.ts**: `measure()` collapsed branch gated by `||
LiteGraph.vueNodesMode` — Vue mode defers to `this.size`; legacy path
unchanged
- **useVueNodeResizeTracking.ts**: Collapsed and expanded nodes both
flow through `batchUpdateNodeBounds`; narrowed `useVueElementTracking`
parameter from `MaybeRefOrGetter<string>` to `string`;
`deferredElements.delete(element)` on unmount to prevent memory
retention
- **selectionBorder.ts**: Unchanged — `createBounds` just works because
`boundingRect` is now correct
- **12 parameterized E2E tests**: Vue mode (subgraph/regular ×
expanded/collapsed × bottom-left/bottom-right) + legacy mode
(expanded/collapsed × bottom-left/bottom-right), driven by
`keyboard.collapse()` (Alt+C)
- **Unit tests**: `measure()` branching (legacy fallback, Vue
`this.size` usage, expanded parity)
- **Shared test helpers**: `repositionNodes`, `KeyboardHelper.collapse`,
`measureSelectionBounds`, `assertSelectionEncompassesNodes`

## Review Focus

- `isolate -z-1` CSS layering pattern — is this acceptable long-term?
- `measure()` collapsed branch gated on `LiteGraph.vueNodesMode` —
one-line gate to avoid the canvas-ctx-less fallback in Vue mode
- Footer button overlap design (`-mr-5` with DOM order for painting)

## Screenshots
<img width="1392" height="800" alt="image"
src="https://github.com/user-attachments/assets/abaebff5-bb8c-4b5b-8734-8d44fdee4cb9"
/>
<img width="1493" height="872" alt="image"
src="https://github.com/user-attachments/assets/6b9c77f9-e3ae-4d4e-81dc-acfa9a24c768"
/>
<img width="813" height="515" alt="image"
src="https://github.com/user-attachments/assets/ce15bafb-e157-408c-971b-a650088f316a"
/>
<img width="1031" height="669" alt="image"
src="https://github.com/user-attachments/assets/20fdc336-4bc2-4d47-ab7e-c0cbcee0d150"
/>
<img width="753" height="525" alt="image"
src="https://github.com/user-attachments/assets/2dccbe31-7d18-49bc-9ed4-158b1659fddf"
/>
<img width="730" height="370" alt="image"
src="https://github.com/user-attachments/assets/ab87edfa-a4b4-46f7-86ae-4965a4509b42"
/>
<img width="1132" height="465" alt="image"
src="https://github.com/user-attachments/assets/54643f5b-4a31-4c3d-9475-c433f87aedb0"
/>
<img width="1102" height="449" alt="image"
src="https://github.com/user-attachments/assets/9c045df3-e1f5-481e-b1cb-ead1db1626f5"
/>

---------

Co-authored-by: github-actions <github-actions@github.com>
2026-04-19 04:58:34 +00:00
Kelly Yang
29d6263fb9 test: add Preview3D execution flow E2E tests (#11014)
## Summary
Adds Playwright coverage for `Preview3D execution` and persistence :
real queue execution against a `Load3D → Preview3D` workflow, plus `save
/ full reload / reopen` from the sidebar.

## What these tests do
**Fixture** (every test)
Turns on Vue Nodes, uses the sidebar for workflows, loads a Load3D →
Preview3D workflow, waits for nodes, then clears saved workflows after
the test so runs stay isolated.

**Test 1 — execution updates Preview3D**
Uploads `cube.obj`(the existing test file in the merged version) to
Load3D, runs `Queue Prompt`, then checks that Preview3D’s model_file and
Last Time Model File match and the canvas has non-zero size. No 3D
screenshots (GPU flakiness).

**Test 2 — persistence after reload**
Same upload + queue, then saves the workflow, reloads the page,
re-applies the same UI settings, opens the saved workflow, and checks
the same model path and camera state (with a small numeric tolerance).

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Medium Risk**
> Adds new slow, WebGL-dependent E2E tests and fixtures, which can
increase CI runtime and introduce flakiness due to timing/graphics
variability, but does not change production logic.
> 
> **Overview**
> Adds a new `Load3D → Preview3D` workflow asset and a dedicated
Playwright fixture (`Preview3DPipelineFixture`) to drive real queue
execution, upload a 3D model, and interact with the 3D canvases (orbit
drags) while asserting `model_file`/`Last Time Model File` and camera
state via node properties.
> 
> Introduces camera-state comparison helpers with explicit numeric
tolerances, and adds a new `preview3dExecution.spec.ts` suite that
validates (1) Preview3D updates from execution output and (2) model +
camera persistence across save, full page reload, and reopening the
workflow from the sidebar.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
5f54b0f650. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11014-test-add-Preview3D-execution-flow-E2E-tests-33e6d73d3650811fa298c364ae196606)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Terry Jia <terryjia88@gmail.com>
2026-04-16 18:08:04 -04:00
Johnpaul Chiwetelu
b3b895a2a9 refactor(test): use canvasOps.clickEmptySpace in copyPaste spec (#10991)
## Summary

Replace two hardcoded blank-canvas click positions in
`copyPaste.spec.ts` with the existing
`comfyPage.canvasOps.clickEmptySpace()` helper.

## Changes

- **What**: Both `{ x: 50, y: 500 }` click literals in the `Copy paste
node, image paste onto LoadImage, image paste on empty canvas` test now
use `canvasOps.clickEmptySpace()` (which wraps
`DefaultGraphPositions.emptySpaceClick = { x: 35, y: 31 }`). Redundant
`await nextFrame()` calls dropped — the helper already awaits a frame
internally.

## Review Focus

Draft PR — need CI to confirm `(35, 31)` is a valid blank-canvas click
for the `load_image_with_ksampler` workflow used by this test. The
workflow places `LoadImage` at `[50, 50]` and `KSampler` at `[500, 50]`,
so `(35, 31)` should be clear of both. Locally the test was already
failing on `main` (pre-existing, unrelated), so CI is the source of
truth here. If CI fails, the fallback is to add a dedicated named
constant `emptyCanvasClick: { x: 50, y: 500 }` to
`DefaultGraphPositions` as originally proposed in the issue.

Fixes #10330

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10991-refactor-test-use-canvasOps-clickEmptySpace-in-copyPaste-spec-33d6d73d3650817aa3ccea44cb48c0ae)
by [Unito](https://www.unito.io)
2026-04-16 09:44:06 +00:00
pythongosssss
ecb6fbe8fb test: Add waitForWorkflowIdle & remove redundant nextFrame (#11264)
## Summary

More cleanup and reliability

## Changes

- **What**: 
- Add wait for idle
- Remove redundant nextFrames

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11264-test-Add-waitForWorkflowIdle-remove-redundant-nextFrame-3436d73d3650812c837ac7503ce0947b)
by [Unito](https://www.unito.io)

Co-authored-by: Alexander Brown <drjkl@comfy.org>
2026-04-15 16:52:41 +00:00
Alexander Brown
52ccd9ed1a refactor: internalize nextFrame() into fixture/helper methods (#11166)
## Summary

Internalize `nextFrame()` calls into fixture/helper methods so spec
authors don't need to remember to call it after common operations.
`nextFrame()` waits for one `requestAnimationFrame` (~16ms) — an extra
call is always safe, making this a low-risk refactor.

## Changes

### Phase 1: `SettingsHelper.setSetting()`
`setSetting()` now calls `nextFrame()` internally. Removed 15 redundant
calls across 7 files.

### Phase 2: `CommandHelper.executeCommand()`
`executeCommand()` now calls `nextFrame()` internally. Removed 15
redundant calls across 7 files, including the now-redundant call in
`AppModeHelper.toggleAppMode()`.

### Phase 3: `WorkflowHelper.loadGraphData()`
New helper wraps `page.evaluate(loadGraphData)` + `nextFrame()`.
Migrated `SubgraphHelper.serializeAndReload()` and `groupNode.spec.ts`.

### Phase 4: `NodeReference` cleanup
Removed redundant `nextFrame()` from `copy()`, `convertToGroupNode()`,
`resizeNode()`, `dragTextEncodeNode2()`, and
`convertDefaultKSamplerToSubgraph()`. Removed 6 spec-level calls after
`node.click('title')`.

### Phase 5: `KeyboardHelper.press()` and `delete()`
New convenience methods that press a key and wait one frame. Converted
40 `canvas.press(key)` + `nextFrame()` pairs across 13 spec files.

### Phase 6: `ComfyPage.expectScreenshot()`
New helper combines `nextFrame()` + `toHaveScreenshot()`. Converted 45
pairs across 12 spec files.

## Total impact
- **~130 redundant `nextFrame()` calls eliminated** across ~35
spec/helper files
- **3 new helper methods** added (`loadGraphData`, `press`/`delete`,
`expectScreenshot`)
- **2 existing methods** enhanced (`setSetting`, `executeCommand`)

## What was NOT changed
- `performance.spec.ts` frame-counting loops (intentional)
- `ComfyMouse.ts` / `CanvasHelper.ts` (already internalized)
- `SubgraphHelper.packAllInteriorNodes()` (deliberate orchestration)
- Builder helpers (already internalized)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11166-refactor-internalize-nextFrame-into-fixture-helper-methods-33f6d73d3650817bb5f6fb46e396085e)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-04-15 15:25:47 +00:00
Kelly Yang
92ad6fc798 test: address review nits for image compare E2E (#11260)
## Summary
A follow-up PR of #11196.

| # | Nit | Action | Reason |
| :--- | :--- | :--- | :--- |
| 1 | Replace `page.on('pageerror')` with request-wait | **Left as-is**
| The `pageErrors` array is an accumulator checked at the end via
`expect(pageErrors).toHaveLength(0)` – the goal is to assert that broken
image URLs don't surface as uncaught JS exceptions during the test run.
A request-wait can't substitute for that behavioral assertion, so the
listener pattern is intentional here. |
| 2 | Move helpers to a `vueNodes.getImageCompareHelper()` subclass |
**Left as-is** | Helpers such as `setImageCompareValue` and
`moveToPercentage` are only used in this file, making local
encapsulation enough. Extracting them to a page object would increase
the file/interface surface area and violate YAGNI; additionally,
`AGENTS.md` clearly states to "minimize the exported values of each
module. |
| 3 | Use `TestIds` enum for test ID strings | **Fixed** – added
`imageCompare` section to `TestIds` in `selectors.ts`; replaced all 8
inline string IDs in `imageCompare.spec.ts` with
`TestIds.imageCompare.*` references | The project already has a
`TestIds` convention for centralizing test IDs. Inline strings create
drift risk between the Vue component and the test file. |
| 4 | Move `expect.poll` bounding box check to helper/page object |
**Left as-is** | This logic already lives inside `moveToPercentage`,
which is a local helper. Moving it further to a page object is the same
refactor as #2 above. |
| 5 | Remove `// ---` style section header comments | **Fixed** –
removed all 8 divider blocks from `imageCompare.spec.ts` | Consistent
with project guidelines and your explicit preference. Test names already
describe what each block does. |
| 6 | Name magic numbers `400` and `350` | **Fixed** – introduced
`minWidth = 400` and `minHeight = 350` constants in the test |
Descriptive names make the constraint self-documenting and easier to
update if the workflow asset changes. |

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: changes are limited to Playwright E2E test code and shared
selector constants, with no production logic impacted.
> 
> **Overview**
> **E2E Image Compare tests now use centralized selectors.** Adds an
`imageCompare` section to `TestIds` and updates `imageCompare.spec.ts`
to reference `TestIds.imageCompare.*` instead of inline `data-testid`
strings.
> 
> Cleans up the spec by removing divider comments and naming the minimum
size magic numbers (`minWidth`, `minHeight`) used in the node sizing
assertion.
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
ece25be5cc. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11260-test-address-review-nits-for-image-compare-E2E-3436d73d365081a69cacc1fff390035a)
by [Unito](https://www.unito.io)
2026-04-15 10:50:44 -04:00
pythongosssss
06686a1f50 test: App mode - additional app mode coverage (#11194)
## Summary

Adds additional test coverage for empty state/welcome screen/connect
outputs/vue nodes auto switch

## Changes

- **What**: 
- add tests

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11194-test-App-mode-additional-app-mode-coverage-3416d73d365081ca91d0ed61de19f840)
by [Unito](https://www.unito.io)
2026-04-15 11:42:22 +00:00
Christian Byrne
033b3dad3a feat: add Slack notification workflow for coverage improvements (#10977)
## Summary

Adds a GitHub Actions workflow + TypeScript script that posts to Slack
when a merged PR improves unit or E2E test coverage.

## Changes

- **What**: New `coverage-slack-notify.yaml` workflow triggered on push
to main. Compares current coverage against previous baselines, generates
Slack Block Kit payload with progress bars and milestone celebrations,
posts to `#p-frontend-automated-testing`.
- **Script**: `scripts/coverage-slack-notify.ts` — parses lcov files,
computes deltas, detects milestone crossings (every 5%), builds Slack
payload. Pure functions exported for testability.
- **Tests**: 26 unit tests in `scripts/coverage-slack-notify.test.ts`
covering all pure functions including edge cases (malformed lcov, exact
boundaries, zero coverage).

### Security hardening
- All `${{ }}` expressions moved from `run:` blocks to `env:` variables
- `SLACK_BOT_TOKEN` passed via env var, not inline
- Unique heredoc delimiter (timestamp-based) prevents payload injection
- `parseInt` fallback (`|| 0`) guards against malformed lcov
- PR regex anchored to first line of commit message

### Robustness
- `continue-on-error: true` on Slack post step (outage does not fail the
job)
- Baseline save guarded by `steps.unit-tests.outcome == success`
(prevents corrupt baselines on test failure)
- Channel ID commented for maintainability
- Top-level `text` field added for Slack mobile push notifications
- Author linked to GitHub profile instead of bare `@username`

## Review Focus

- Workflow step ordering and conditional logic
- Security of expression handling and secret management
- Slack payload structure and Block Kit formatting

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10977-feat-add-Slack-notification-workflow-for-coverage-improvements-33d6d73d3650819c8950f483c83f297c)
by [Unito](https://www.unito.io)

---------

Co-authored-by: GitHub Action <action@github.com>
2026-04-14 20:58:47 -07:00
Dante
634d57809b test: add E2E tests for bottom panel core behaviors (#10814)
## Summary
- Add `browser_tests/tests/bottomPanel.spec.ts` with tests for behaviors
not covered by existing `bottomPanelLogs` and `bottomPanelShortcuts`
specs
- Tests cover: close button (X), tab persistence on re-open, resize
gutter visibility and drag, canvas interaction when panel is closed,
cross-panel switching (terminal <-> shortcuts), and registered tab
enumeration
- Extend `BottomPanel` fixture with `closeButton` and `resizeGutter`
locators

## Test plan
- [ ] `pnpm test:browser:local` passes all new tests in
`bottomPanel.spec.ts`
- [ ] Existing `bottomPanelLogs.spec.ts` and
`bottomPanelShortcuts.spec.ts` are unaffected
- [ ] `pnpm typecheck:browser` passes
- [ ] `pnpm lint` passes

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10814-test-add-E2E-tests-for-bottom-panel-core-behaviors-3366d73d365081ea9b90c643897845fa)
by [Unito](https://www.unito.io)

---------

Co-authored-by: dante <dante@danteui-MacStudio.local>
Co-authored-by: GitHub Action <action@github.com>
Co-authored-by: Alexander Brown <drjkl@comfy.org>
2026-04-14 23:33:11 +00:00
Dante
5807e03c74 test: expand E2E coverage for toolbox actions (#10968)
## Summary
- Adds `selectionToolboxMoreActions.spec.ts` with E2E coverage for
previously untested toolbox actions
- Covers: pin/unpin, minimize/expand, adjust size, copy, duplicate,
refresh button, align (top/left), distribute (horizontal/vertical),
alignment options hidden for single selection, multi-node bypass toggle
- Part of the FixIt Burndown test coverage initiative (toolbox actions)

## Test plan
- [ ] All new tests pass in CI
- [ ] No regressions in existing selectionToolbox tests

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10968-test-expand-E2E-coverage-for-toolbox-actions-33c6d73d3650811286cefdd0eb4f5242)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Alexander Brown <drjkl@comfy.org>
2026-04-14 23:20:45 +00:00
AustinMroz
988a546721 Add missing dialog tests (#11133)
Leveraging the fancy coverage functionality of #10930, this PR aims to
add coverage to missing dialogue models.

This has proven quite constructive as many of the dialogues have since
been shown to be bugged.
- The APINodes sign in dialog that displays when attempting to run a
workflow containing Partner nodes while not logged in was intended to
display a list of nodes required to execute the workflow. The import for
this component was forgotten in the original commit (#3532) and the
backing component was later knipped
- Error dialogs resulting are intended to display the file responsible
for the error, but the prop was accidentally left out during the
refactoring of #3265
- ~~The node library migration (#8548) failed to include the 'Edit
Blueprint' button, and had incorrect sizing and color on the 'Delete
Blueprint' button.~~
- On request, the library button changes were spun out to a separate PR

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11133-Add-missing-dialog-tests-33e6d73d3650812cb142d610461adcd4)
by [Unito](https://www.unito.io)

---------

Co-authored-by: GitHub Action <action@github.com>
2026-04-14 14:31:31 -07:00
pythongosssss
165984fe4c test: Improve speed of app mode input corruption test (#11236)
## Summary

Speeds up test that was timing out
https://9b579efd.comfyui-playwright-chromium.pages.dev/#?testId=b97e313f05078cede9be-5e6b75a76880fb6a5d96

## Changes

- **What**:
- load prebuilt workflows to reduce test time (17s -> 11s)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11236-test-Improve-speed-of-app-mode-input-corruption-test-3426d73d3650815b9475ec96dfbd7ad5)
by [Unito](https://www.unito.io)
2026-04-14 18:36:04 +00:00
pythongosssss
a09bb81b98 test: Auto wait for nodes after loadWorkflow in vue-node tests (#11238)
## Summary

Updates tests to auto wait for vue-nodes when loading a workflow in a
test with the vue-nodes tag

## Changes

- **What**: 
- If tag includes vue-nodes, wait 
- Remove all load->wait calls

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11238-test-Auto-wait-for-nodes-after-loadWorkflow-in-vue-node-tests-3426d73d3650810e8760c5601186fde8)
by [Unito](https://www.unito.io)
2026-04-14 17:30:49 +00:00
pythongosssss
5899a9392e test: Simplify vue node/menu test setup (#11184)
## Summary
Simplifies test setup for common settings

## Changes

- **What**: 
- add vue-nodes tag to auto enable nodes 2.0
- remove UseNewMenu Top as this is default

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11184-test-Simplify-vue-node-menu-test-setup-3416d73d3650815487e0c357d28761fe)
by [Unito](https://www.unito.io)
2026-04-13 20:43:25 +00:00
pythongosssss
a373633ab2 refactor: fix lint errors in tests (#11182)
## Summary

Fix tests failing lint

## Changes

- **What**:
- Fix relative imports
- Fix test not using comfyPage

## Review Focus

<!-- Critical design decisions or edge cases that need attention -->

<!-- If this PR fixes an issue, uncomment and update the line below -->
<!-- Fixes #ISSUE_NUMBER -->

## Screenshots (if applicable)

<!-- Add screenshots or video recording to help explain your changes -->

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11182-refactor-fix-lint-errors-in-tests-3416d73d3650812fbf1bc88554c57de2)
by [Unito](https://www.unito.io)
2026-04-13 15:50:11 +00:00
jaeone94
521019d173 fix: exclude muted/bypassed nodes from missing asset detection (#10856)
## Summary

Muted and bypassed nodes are excluded from execution but were still
triggering missing model/media/node warnings. This PR makes the error
system mode-aware: muted/bypassed nodes no longer produce missing asset
errors, and all error lifecycle events (mode toggle, deletion, paste,
undo, tab switch) are handled consistently.

- Fixes Comfy-Org/ComfyUI#13256

## Behavioral notes

- **Tab switch overlay suppression (intentional)**: Switching back to a
workflow with missing assets no longer re-shows the error overlay. This
reverses the behavior introduced in #10190. The error state is still
restored silently in the errors tab — users can access it via the
properties panel without being interrupted by the overlay on every tab
switch.

## Changes

### 1. Scan filtering

- `scanAllModelCandidates`, `scanAllMediaCandidates`,
`scanMissingNodes`: skip nodes with `mode === NEVER || BYPASS`
- `collectMissingNodes` (serialized data): skip error reporting for
muted/bypassed nodes while still calling `sanitizeNodeName` for safe
`configure()`
- `collectEmbeddedModelsWithSource`: skip muted/bypassed nodes;
workflow-level `graphData.models` only create candidates when active
nodes exist
- `enrichWithEmbeddedMetadata`: filter unmatched workflow-level models
when all referencing nodes are inactive

### 2. Realtime mode change handling

- `useErrorClearingHooks.ts` chains `graph.onTrigger` to detect
`node:property:changed` (mode)
- Deactivation (active → muted/bypassed): remove missing
model/media/node errors for the node
- Activation (muted/bypassed → active): scan the node and add confirmed
errors, show overlay
- Subgraph container deactivation: remove all interior node errors
(execution ID prefix match)
- Subgraph container activation: scan all active interior nodes
recursively
- Subgraph interior mode change: resolve node via
`localGraph.getNodeById()` then compute execution ID from root graph

### 3. Node deletion

- `graph.onNodeRemoved`: remove missing model/media/node errors for the
deleted node
- Handle `node.graph === null` at callback time by using
`String(node.id)` for root-level nodes

### 4. Node paste/duplicate

- `graph.onNodeAdded`: scan via `queueMicrotask` (deferred until after
`node.configure()` restores widget values)
- Guard: skip during `ChangeTracker.isLoadingGraph` (undo/redo/tab
switch handled by pipeline)
- Guard: skip muted/bypassed nodes

### 5. Workflow tab switch optimization

- `skipAssetScans` option in `loadGraphData`: skip full pipeline on tab
switch
- Cache missing model/media/node state per workflow via
`PendingWarnings`
- `beforeLoadNewGraph`: save current store state to outgoing workflow's
`pendingWarnings`
- `showPendingWarnings`: restore cached errors silently (no overlay),
always sync missing nodes store (even when null)
- Preserve UI state (`fileSizes`, `urlInputs`) on tab switch by using
`setMissingModels([])` instead of `clearMissingModels()`
- `MissingModelRow.vue`: fetch file size on mount via
`fetchModelMetadata` memory cache

### 6. Undo/redo overlay suppression

- `silentAssetErrors` option propagated through pipeline →
`surfaceMissingModels`/`surfaceMissingMedia` `{ silent }` option
- `showPendingWarnings` `{ silent }` option for missing nodes overlay
- `changeTracker.ts`: pass `silentAssetErrors: true` on undo/redo

### 7. Error tab node filtering

- Selected node filters missing model/media card contents (not just
group visibility)
- `isAssetErrorInSelection`: resolve execution ID → graph node for
selection matching
- Missing nodes intentionally unfiltered (pack-level scope)
- `hasMissingMediaSelected` added to `RightSidePanel.vue` error tab
visibility
- Download All button: show only when 2+ downloadable models exist

### 8. New store functions

- `missingModelStore`: `addMissingModels`, `removeMissingModelsByNodeId`
- `missingMediaStore`: `addMissingMedia`, `removeMissingMediaByNodeId`
- `missingNodesErrorStore`: `removeMissingNodesByNodeId`
- `missingModelScan`: `scanNodeModelCandidates` (extracted single-node
scan)
- `missingMediaScan`: `scanNodeMediaCandidates` (extracted single-node
scan)

### 9. Test infrastructure improvements

- `data-testid` on `RightSidePanel.vue` tabs (`panel-tab-{value}`)
- Error-related TestIds moved from `dialogs` to `errorsTab` namespace in
`selectors.ts`
- Removed unused `TestIdValue` type
- Extracted `cleanupFakeModel` to shared `ErrorsTabHelper.ts`
- Renamed `openErrorsTabViaSeeErrors` → `loadWorkflowAndOpenErrorsTab`
- Added `aria-label` to pencil edit button and subgraph toggle button

## Test plan

### Unit tests (41 new)

- Store functions: `addMissing*`, `removeMissing*ByNodeId`
- `executionErrorStore`: `surfaceMissing*` silent option
- Scan functions: muted/bypassed filtering, `scanNodeModelCandidates`,
`scanNodeMediaCandidates`
- `workflowService`: `showPendingWarnings` silent, `beforeLoadNewGraph`
caching

### E2E tests (17 new in `errorsTabModeAware.spec.ts`)

**Missing nodes**
- [x] Deleting a missing node removes its error from the errors tab
- [x] Undo after bypass restores error without showing overlay

**Missing models**
- [x] Loading a workflow with all nodes bypassed shows no errors
- [x] Bypassing a node hides its error, un-bypassing restores it
- [x] Deleting a node with missing model removes its error
- [x] Undo after bypass restores error without showing overlay
- [x] Pasting a node with missing model increases referencing node count
- [x] Pasting a bypassed node does not add a new error
- [x] Selecting a node filters errors tab to only that node

**Missing media**
- [x] Loading a workflow with all nodes bypassed shows no errors
- [x] Bypassing a node hides its error, un-bypassing restores it
- [x] Pasting a bypassed node does not add a new error
- [x] Selecting a node filters errors tab to only that node

**Subgraph**
- [x] Bypassing a subgraph hides interior errors, un-bypassing restores
them
- [x] Bypassing a node inside a subgraph hides its error, un-bypassing
restores it

**Workflow switching**
- [x] Does not resurface error overlay when switching back to workflow
with missing nodes
- [x] Restores missing nodes in errors tab when switching back to
workflow

# Screenshots


https://github.com/user-attachments/assets/e0a5bcb8-69ba-4120-ab7f-5c83e4cfc3c5



## Follow-up work

- Extract error-detection computed properties from `RightSidePanel.vue`
into a composable (e.g. `useErrorsTabVisibility`)

---------

Co-authored-by: github-actions <github-actions@github.com>
Co-authored-by: GitHub Action <action@github.com>
2026-04-13 12:51:19 +00:00
Kelly Yang
bd82c855e0 test: add minimap E2E tests for graph content and click-to-navigate (#10738)
## Summary

Adds Playwright E2E tests verifying that 
1. the minimap canvas renders node content
2. clears when the graph is empty
3. correctly navigates the main canvas on click

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10738-test-add-minimap-E2E-tests-for-graph-content-and-click-to-navigate-3336d73d365081eb955ce711b3efc57f)
by [Unito](https://www.unito.io)

<!-- CURSOR_SUMMARY -->
---

> [!NOTE]
> **Low Risk**
> Low risk: changes are limited to adding `data-testid` attributes to
the minimap UI and expanding Playwright E2E assertions, with no
production behavior changes expected.
> 
> **Overview**
> Strengthens minimap E2E coverage by switching existing assertions from
CSS selectors to new `data-testid`-based selectors and adding helper
utilities for canvas/overlay interactions.
> 
> Adds new Playwright tests that verify the minimap canvas renders
content when nodes exist, clears when the graph is emptied, and that
clicking the minimap pans the main canvas (including a
post-`fitViewToSelectionAnimated` tolerance check).
> 
> <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit
06e7542af1. Bugbot is set up for automated
code reviews on this repo. Configure
[here](https://www.cursor.com/dashboard/bugbot).</sup>
<!-- /CURSOR_SUMMARY -->

---------

Co-authored-by: Alexander Brown <drjkl@comfy.org>
Co-authored-by: Alexander Brown <DrJKL0424@gmail.com>
Co-authored-by: GitHub Action <action@github.com>
2026-04-13 04:28:04 +00:00
Alexander Brown
6f579c5992 fix: enable playwright/no-force-option lint rule (#11164)
## Summary

Enable the previously disabled `playwright/no-force-option` lint rule at
error level and resolve all 29 violations across 10 files.

## Changes

### Lint rule
- `.oxlintrc.json`: `playwright/no-force-option` changed from `off` to
`error`

### Shared utility
- `CanvasHelper.ts`: Add `mouseClickAt()` and `mouseDblclickAt()`
methods that convert canvas-element-relative positions to absolute page
coordinates and use `page.mouse` APIs, avoiding Playwright's locator
actionability checks that fail when Vue DOM overlays sit above the
`<canvas>` element

### Force removal (20 violations)
- `selectionToolboxActions.spec.ts`: Remove `force: true` from 8 toolbox
button clicks (the `pointer-events: none` splitter overlay does not
intercept `elementFromPoint()`)
- `selectionToolboxSubmenus.spec.ts`: Remove `force: true` from 2
popover menu item clicks
- `BuilderSelectHelper.ts`: Remove `force: true` from 2 widget/node
clicks (builder mode does not disable pointer events)
- `linkInteraction.spec.ts`: Remove `force: true` from 3 slot `dragTo()`
calls (`::after` pseudo-elements do not intercept `elementFromPoint()`)
- `SidebarTab.ts`: Remove `force: true` from toast dismissal (`.catch()`
already handles failures)
- `nodeHelp.spec.ts`: Remove `force: true` from info button click
(preceding `toBeVisible()` assertion is sufficient)

### Rewrites (3 violations)
- `integerWidget.spec.ts`: Replace force-clicking disabled buttons with
`toBeDisabled()` assertions
- `Topbar.ts`: Replace force-click with `waitFor({ state: 'visible' })`
after hover

### Canvas coordinate clicks (9 violations)
- `litegraphUtils.ts`: Convert `NodeReference.click()` and
`navigateIntoSubgraph()` to use
`canvasOps.mouseClickAt()`/`mouseDblclickAt()`
- `subgraphPromotion.spec.ts`: Convert 3 right-click canvas calls to
`canvasOps.mouseClickAt()`
- `selectionToolboxSubmenus.spec.ts`: Convert 1 canvas dismiss-click to
`canvasOps.mouseClickAt()`

## Rationale

The original `force: true` usages were added defensively based on
incorrect assumptions about the `z-999 pointer-events: none` splitter
overlay intercepting Playwright's actionability checks. In reality,
`elementFromPoint()` skips elements with `pointer-events: none`, so the
overlay is transparent to Playwright's hit-test.

For canvas coordinate clicks, `force: true` on a locator does not tunnel
through DOM overlays — it only skips Playwright's preflight checks.
`page.mouse.click()` is the correct API for coordinate-based canvas
interactions.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11164-fix-enable-playwright-no-force-option-lint-rule-33f6d73d365081e78601c6114121d272)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-04-11 19:59:34 +00:00
Alexander Brown
8c9328c1b2 feat: add eslint-plugin-playwright via oxlint JS plugins (#11136)
## Summary

Add eslint-plugin-playwright as an oxlint JS plugin scoped to
browser_tests/, enforcing Playwright best practices at lint time.

## Changes

- **What**: Configure eslint-plugin-playwright@2.10.1 via oxlint's alpha
`jsPlugins` field (`.oxlintrc.json` override scoped to
`browser_tests/**/*.ts`). 18 recommended rules +
`prefer-native-locators` + `require-to-pass-timeout` at error severity.
All 173 initial violations resolved (config, auto-fix, manual fixes).
`no-force-option` set to off — 28 violations need triage (canvas overlay
workarounds vs unnecessary force) in a dedicated PR.
- **Dependencies**: `eslint-plugin-playwright@^2.10.1` (devDependency,
required by oxlint jsPlugins at runtime)

## Review Focus

- `.oxlintrc.json` override structure — this is the first use of
oxlint's JS plugins alpha feature in this repo
- Manual fixes in spec files: `waitForSelector` → `locator.waitFor`,
deprecated page methods → locator equivalents, `toPass()` timeout
additions
- Compound CSS selectors replaced with `.and()` (Playwright native
locator composition) to avoid `prefer-native-locators` suppressions
- Lint script changes in `package.json` to include `browser_tests/` in
oxlint targets

---------

Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: GitHub Action <action@github.com>
2026-04-11 01:25:14 +00:00
pythongosssss
82fb8ce658 test: App mode - Execution tests (#10801)
## Summary

Adds tests that simulate the execution flow and output feed

## Changes

- **What**: 
- Add ExecutionHelper for mocking network activity
- Refactor ws fixture to use Playwright websocket helper instead of
patching window
- 

## Review Focus

<!-- Critical design decisions or edge cases that need attention -->

<!-- If this PR fixes an issue, uncomment and update the line below -->
<!-- Fixes #ISSUE_NUMBER -->

## Screenshots (if applicable)

<!-- Add screenshots or video recording to help explain your changes -->

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10801-test-App-mode-Execution-tests-3356d73d365081e4acf0c34378600031)
by [Unito](https://www.unito.io)
2026-04-10 23:31:56 +00:00
Alexander Brown
0353524e6f refactor: standardize Page Object locators as public readonly instead of getters (#11135)
*PR Created by the Glary-Bot Agent*

---

## Summary

- Convert ~120 getter-based locators across 18 browser test fixture
files to `public readonly` constructor-assigned properties
- Removes unnecessary indirection, makes object shape explicit, and
improves IDE auto-complete / type inference
- Keeps lazy-init getters (`??=`), computed properties, and `private get
page()` convenience accessors as getters

## Changes

**`browser_tests/fixtures/components/`** (6 files):
`ComfyNodeSearchBox`, `ContextMenu`, `SettingDialog`, `SignInDialog`,
`SidebarTab` (all 6 classes), `Topbar`

**`browser_tests/fixtures/`** (4 files): `ComfyPage` (ComfyMenu.buttons,
ComfyPage.visibleToasts), `UserSelectPage`, `ComfyMouse`,
`VueNodeHelpers`

**`browser_tests/fixtures/helpers/`** (7 files): `AppModeHelper`,
`BuilderFooterHelper`, `BuilderSaveAsHelper`, `BuilderSelectHelper`,
`BuilderStepsHelper`, `ToastHelper`, `NodeOperationsHelper`

**`browser_tests/fixtures/utils/`** (1 file): `vueNodeFixtures`

## Validation

- `pnpm typecheck` 
- `pnpm typecheck:browser` 
- `pnpm exec eslint browser_tests/fixtures/` 
- All pre-commit hooks pass (oxfmt, oxlint, eslint, typecheck,
typecheck:browser) 
- No visual/manual verification needed — changes are test fixture
locator declarations only (no UI or runtime behavior change)

Fixes #11131

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-11135-refactor-standardize-Page-Object-locators-as-public-readonly-instead-of-getters-33e6d73d3650819690cbc639f3d30daf)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Glary-Bot <glary-bot@users.noreply.github.com>
2026-04-10 21:10:17 +00:00
Alexander Brown
f1bb756929 fix: remove redundant and counterproductive e2e timeout overrides (#11110)
## Summary

Alright, alright, alright. These e2e tests have been runnin' around like
they're late for somethin', settin' tight little timeouts like the
world's gonna end in 250 milliseconds. Man, you gotta *breathe*. Let the
framework do its thing. Go slow to go fast, that's what I always say.

## Changes

- **What**: Removed ~120 redundant timeout overrides from auto-retrying
Playwright assertions (`toBeVisible`, `toBeHidden`, `toHaveCount`,
`toBeEnabled`, `toHaveAttribute`, `toContainText`, `expect.poll`) where
5000ms is already the default. Also removed sub-5s timeouts (1s, 2s, 3s)
that were just *begging* for flaky failures — like wearin' a belt and
suspenders and also holdin' your pants up with both hands. Raised the
absurdly short timeouts in `customMatchers.ts` (250ms `toPass` → 5000ms,
256ms poll → default). Kept `timeout: 5000` on `.toPass()` calls
(defaults to 0), `.waitFor()`, `waitForRequest`, `waitForFunction`,
intentionally-short timeouts inside retry loops, and conditional
`.isVisible()/.catch()` checks — those fellas actually need the help.

## Review Focus

Every remaining timeout in the diff is there for a *reason*. The ones on
`.toPass()` stay because that API defaults to zero — it won't retry at
all without one. The ones on `.waitFor()` and `waitForRequest` stay
because those are locator actions, not auto-retrying assertions. The
intentionally-short ones inside `toPass` retry loops
(`interaction.spec.ts`) and the negative assertions (`actionbar.spec.ts`
confirming no response arrives) — those are *supposed* to be tight.

The short timeouts on regular assertions were actively *encouragin'*
flaky failures. That's like settin' your alarm for 4 AM and then gettin'
mad you're tired. Just... don't do that, man. Let things take the time
they need.

38 files, net -115 lines. Less code, more chill. That's livin'.

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-04-10 19:47:20 +00:00
Alexander Brown
0132c77c7d test: harden 82 Playwright specs for deterministic CI runs (#10967)
## Summary

Harden 98 E2E spec files and 8 fixtures/helpers for deterministic CI
runs by replacing race-prone patterns with retry-safe alternatives.

No source code changes -- only `browser_tests/` is touched.

## Changes

- **E2E spec hardening** (98 spec files, 6 fixtures, 2 helpers):

  | Fix class | Sites | Examples |
  |-----------|-------|---------:|
| `expect(await ...)` -> `expect.poll()` | ~153 | interaction,
defaultKeybindings, workflows, featureFlags |
| `const x = await loc.count(); expect(x)` -> `toHaveCount()` | ~19 |
menu, linkInteraction, assets, bottomPanelShortcuts |
| `nextFrame()` -> `waitForHidden()` after menu clicks | ~22 |
contextMenu, rightClickMenu, subgraphHelper |
| Redundant `nextFrame()` removed | many | defaultKeybindings, minimap,
builderSaveFlow |
| `expect(async () => { ... }).toPass()` retry blocks | 5 | interaction
(graphdialog dismiss guard) |
| `force:true` removed from `BaseDialog.close()` | 1 | BaseDialog
fixture |
| ContextMenu `waitForHidden` simplified (check-then-act race removed) |
1 | ContextMenu fixture |
| Non-deterministic node order -> proximity-based selection | 1 |
interaction (toggle dom widget) |
  | Tight poll timeout (250ms) -> >=2000ms | 2 | templates |

- **Helper improvements**: Exposed locator getters on
`ComfyPage.domWidgets`, `ToastHelper.toastErrors`, and
`WorkflowsSidebarTab.activeWorkflowLabel` so callers can use retrying
assertions (`toHaveCount()`, `toHaveText()`) directly.

- **Flake pattern catalog**: Added section 7 table to
`browser_tests/FLAKE_PREVENTION_RULES.md` documenting 8 pattern classes
for reviewers and future authors.

- **Docs**: Fixed bad examples in `browser_tests/README.md` to use
`expect.poll()`.

- **Breaking**: None
- **Dependencies**: None

## Review Focus

- All fixes follow the rules in
`browser_tests/FLAKE_PREVENTION_RULES.md`
- No behavioral changes to tests -- only timing/retry strategy is
updated
- The `ContextMenu.waitForHidden` simplification removes a
swallowed-error anti-pattern; both locators now use direct `waitFor({
state: 'hidden' })`

---------

Co-authored-by: Amp <amp@ampcode.com>
Co-authored-by: github-actions <github-actions@github.com>
2026-04-09 20:50:56 -07:00
Terry Jia
277ee5c32e test: add E2E tests for Load3D model upload and drag-drop and basic e2e for 3d viewer (#10957)
## Summary
Add tests verifying real model loading:
- Upload cube.obj via file chooser button
- Drag-and-drop cube.obj onto the 3D canvas
- Add data-testid to LoadingOverlay for stable test selectors.
Add tests verifying 3d viewer openning:
- Open viewer from Load3D node via expand button, verify canvas and
controls sidebar
- Cancel button closes the viewer dialog

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10957-test-add-E2E-tests-for-Load3D-model-upload-and-drag-drop-and-basic-e2e-for-3d-viewer-33c6d73d3650810c8ff8ed656a5164a6)
by [Unito](https://www.unito.io)

---------

Co-authored-by: github-actions <github-actions@github.com>
2026-04-09 21:36:07 -04:00
Christian Byrne
9b769656ac test: add ShareWorkflow dialog E2E tests (DLG-05) (#10588)
## Summary
Adds Playwright E2E tests for the ShareWorkflow dialog component and its
various states.

## Tests added
- Dialog opens and shows unsaved state for new workflows (save prompt)
- Ready state shows create link button for saved but unpublished
workflows
- Shared state shows copy URL field with share link after publishing
- Stale state shows update link button when workflow modified after
publishing
- Close button dismisses dialog
- Create link transitions dialog from ready to shared state
- Tab switching between share link and publish to hub (when
comfyHubUploadEnabled)
- Tab aria-selected states update correctly on switch

## Approach
- Share dialog is gated behind `isCloud` (compile-time constant), so
tests invoke it directly via `page.evaluate()` importing
`useShareDialog`
- Share service API calls (`/api/userdata/*/publish`,
`/api/assets/from-workflow`) mocked via `page.route()` for deterministic
state testing
- Dialog state (loading → unsaved → ready → shared → stale) controlled
by mock responses
- Feature flags set via `serverFeatureFlags.value` for tab visibility
testing

## Notes
- All pre-existing TS2307 errors are `.vue` module resolution — no new
type errors
- Tests cover the 5 dialog states: loading, unsaved, ready, shared,
stale

## Task
Part of Test Coverage Q2 Overhaul (DLG-05).

## Conventions
- Uses Vue nodes with new menu enabled
- Tests read as user stories
- No full-page screenshots
- Proper waits, no sleeps
- All API calls mocked

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10588-test-add-ShareWorkflow-dialog-E2E-tests-DLG-05-3306d73d365081a0ab15f333707e493b)
by [Unito](https://www.unito.io)

---------

Co-authored-by: GitHub Action <action@github.com>
2026-04-08 14:14:47 -07:00
pythongosssss
4b0b8e7240 test: App mode - Welcome screen state (#10747)
## Summary

Adds tests for validating welcome screen state

## Changes

- **What**: 
- add clear graph util function

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10747-test-App-mode-Welcome-screen-state-3336d73d365081f0ba27d567c3c81505)
by [Unito](https://www.unito.io)
2026-04-08 12:33:51 -07:00
Alexander Brown
3b78dfbe1c test: migrate browser_tests/ to @e2e/ path alias and add lint rule (#10958)
## Summary

Complete the @e2e/ path alias migration started in #10735 by converting
all 354 remaining relative imports and adding a lint rule to prevent
backsliding.

## Changes

- **What**: Migrate all relative imports in browser_tests/ to use
`@e2e/` (intra-directory) and `@/` (src/ imports) path aliases. Add
`no-restricted-imports` ESLint rule banning `./` and `../` imports in
`browser_tests/**/*.ts`. Suppress pre-existing oxlint `no-eval` and
`no-console` warnings exposed by touching those files.

## Review Focus

- ESLint flat-config merging: the `@playwright/test` ban and
relative-import ban are in two separate blocks to avoid last-match-wins
collision with the `useI18n`/`useVirtualList` blocks higher in the
config.
- The `['./**', '../**']` glob patterns (not `['./*', '../*']`) are
needed to catch multi-level relative paths like `../../../src/foo`.

Follows up on #10735

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10958-test-migrate-browser_tests-to-e2e-path-alias-and-add-lint-rule-33c6d73d365081649d1be771eac986fd)
by [Unito](https://www.unito.io)

Co-authored-by: Amp <amp@ampcode.com>
2026-04-08 11:28:59 -07:00
pythongosssss
036be1c7e9 test: App mode - Pruning tests (#10805)
## Summary

Adds tests that deleted nodes automatically remove selections from app
mode

## Changes

- **What**: 
- always prune when entering app builder (fix)
- add tests (delete output node, delete input node, change dynamic
widget value)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10805-test-App-mode-Pruning-tests-3356d73d365081bcb12fc226af31a724)
by [Unito](https://www.unito.io)
2026-04-08 10:42:47 -07:00
jaeone94
3f375bea9c test: comprehensive E2E tests for error dialog, overlay, and errors tab (#10848)
## Summary

Comprehensive Playwright E2E tests for the error systems: ErrorDialog,
ErrorOverlay, and the errors tab (missing nodes, models, media,
execution errors).

## Changes

- **What**:
- **ErrorDialog** (`errorDialog.spec.ts`, 7 tests): configure/prompt
error triggers, Show Report, Copy to Clipboard, Find Issues on GitHub,
Contact Support
- **ErrorOverlay** (`errorOverlay.spec.ts`, 12 tests): error count
labels, per-type button labels (missing nodes/models/media/multiple),
See Errors flow (open panel, dismiss, close), undo/redo persistence
- **Errors tab — common** (`errorsTab.spec.ts`, 3 tests): tab
visibility, search/filter execution errors
- **Errors tab — Missing nodes** (`errorsTabMissingNodes.spec.ts`, 5
tests): MissingNodeCard, packs group, expand/collapse, locate button
- **Errors tab — Missing models** (`errorsTabMissingModels.spec.ts`, 6
tests): group display, model name, expand/referencing nodes, clipboard
copy, OSS Copy URL/Download buttons
- **Errors tab — Missing media** (`errorsTabMissingMedia.spec.ts`, 7
tests): migrated from `missingMedia.spec.ts` with detection,
upload/library/cancel flows, locate
- **Errors tab — Execution** (`errorsTabExecution.spec.ts`, 2 tests):
Find on GitHub/Copy buttons, runtime error panel
- **Shared helpers**: `ErrorsTabHelper.ts` (openErrorsTabViaSeeErrors),
`clipboardSpy.ts` (interceptClipboardWrite/getClipboardText)
- **Component changes**: added `data-testid` to
`ErrorDialogContent.vue`, `FindIssueButton.vue`, `MissingModelRow.vue`,
`MissingModelCard.vue`
  - **Selectors**: registered all new test IDs in `selectors.ts`
- **Test assets**: `missing_nodes_and_media.json` (compound errors),
`missing_models_with_nodes.json` (expand/locate)
- **Migrations**: error tests from `dialog.spec.ts` → dedicated files,
`errorOverlaySeeErrors.spec.ts` → `errorOverlay.spec.ts`,
`missingMedia.spec.ts` → `errorsTabMissingMedia.spec.ts`

## Review Focus

- OSS tests (`@oss` tag) verify Download/Copy URL buttons appear for
models with embedded URLs.
- The `missing_models.json` fixture must remain without nodes — adding
`CheckpointLoaderSimple` nodes causes directory mismatch in
`enrichWithEmbeddedMetadata` that prevents URL enrichment. A separate
`missing_models_with_nodes.json` fixture is used for expand/locate
tests.

## Cloud tests deferred

Missing model cloud environment tests (`@cloud` tag — hidden buttons,
import-unsupported notice) are deferred to a follow-up PR. The
`comfyPage` fixture cannot bypass the Firebase auth guard in cloud
builds, causing `window.app` initialization timeout. A separate infra PR
is needed to add cloud auth bypass to the fixture.

## Bug Discovery

During testing, a bug was found where the **Locate button for missing
nodes in subgraphs fails on initial workflow load**.
`collectMissingNodes` in `loadGraphData` captures execution IDs using
pre-`configure()` JSON node IDs, but `configure()` triggers subgraph
node ID deduplication (PR #8762, always-on since PR #9510) which remaps
colliding IDs. This will be addressed in a follow-up PR.

- Fixes #10847 (tracked, fix pending in separate PR)

## Testing

- 42 new/migrated E2E tests across 8 spec files
- All OSS tests pass locally and in CI

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10848-test-comprehensive-E2E-tests-for-error-dialog-overlay-and-errors-tab-3386d73d36508137a5e4cec8b12fa2fa)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 14:45:17 +09:00
Alexander Brown
4cb83353cb test: stabilize flaky Playwright tests (#10817)
Stabilize flaky Playwright tests by improving test reliability.

This PR aims to identify and fix flaky e2e tests.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10817-test-stabilize-flaky-Playwright-tests-3366d73d365081ada40de73ce11af625)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Amp <amp@ampcode.com>
2026-04-07 19:47:27 -07:00
Johnpaul Chiwetelu
4078f8be8f test: add E2E test for subgraph duplicate independent widget values (#10949)
## Summary
- Add E2E test verifying duplicated subgraphs maintain independent
widget values (convert CLIP node to subgraph, duplicate, set different
text in each, assert no bleed)
- Extract `clickMenuItemExact` and `openForVueNode` into `ContextMenu`
fixture for reuse across Vue node tests
- Refactor `contextMenu.spec.ts` to delegate to the new fixture methods

## Test plan
- [x] `pnpm typecheck:browser` passes
- [x] `pnpm lint` passes
- [x] New test passes locally (`pnpm test:browser:local --
browser_tests/tests/subgraph/subgraphDuplicateIndependentValues.spec.ts`)

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10949-test-add-E2E-test-for-subgraph-duplicate-independent-widget-values-33b6d73d3650818191c1f78ef8db4455)
by [Unito](https://www.unito.io)
2026-04-08 00:20:23 +01:00
Benjamin Lu
fd9c67ade8 test: type asset helper update payload (#10751)
What changed

- Typed the `PUT /assets/:id` mock body in `AssetHelper` as
`AssetUpdatePayload` instead of treating it as an untyped record.

Why

- Keeps the mock aligned with the frontend update contract used by the
asset service.
- Narrows the helper without changing behavior, so follow-up typing work
can build on a smaller base.

Validation

- `pnpm typecheck`
- `pnpm typecheck:browser`

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10751-test-type-asset-helper-update-payload-3336d73d365081fd8f1bc0c7c49c5ddb)
by [Unito](https://www.unito.io)
2026-04-07 14:26:56 -07:00
Christian Byrne
83f4e7060a test(infra): AssetHelper with builder pattern + deterministic fixtures (#10545)
## What

Adds `AssetHelper` — a builder-pattern helper for mocking asset-related
API endpoints in Playwright E2E tests, plus deterministic fixture data.

## Why

12+ asset-related API endpoints need mocking for asset browser tests
(PNL-02), cloud dialog testing (DLG-08), and other asset-dependent E2E
scenarios. Random mock data from existing `createMockAssets()` is
unsuitable for deterministic E2E assertions.

## What's included

### `AssetHelper.ts` (307 LOC)
- Fluent builder API: `assetHelper.withModels(3).withImages(5).mock()`
- Stateful mock store (Map) for upload→verify→delete flows
- Endpoint coverage: GET/POST/PUT/DELETE `/assets`, download progress
- `mockError()` for error state testing
- `clearMocks()` cleanup matching QueueHelper/FeatureFlagHelper pattern

### `assetFixtures.ts` (304 LOC)
- 11 stable named constants (checkpoints, loras, VAE, embedding, inputs,
outputs)
- Factory functions: `generateModels()`, `generateInputFiles()`,
`generateOutputAssets()`
- Fixed IDs/dates/sizes — no randomness, safe for screenshot comparisons

### ComfyPage integration
- Available as `comfyPage.assets` in all tests

## Testing
- TypeScript compiles clean
- Follows existing QueueHelper/FeatureFlagHelper conventions

## Unblocks
- PNL-02: Asset browser tests (@Jaewon Yoon)
- DLG-08: Assets modal / cloud dialog testing

Part of: Test Coverage Q2 Overhaul

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10545-test-infra-AssetHelper-with-builder-pattern-deterministic-fixtures-32f6d73d365081d3985ef079ff3dbede)
by [Unito](https://www.unito.io)

---------

Co-authored-by: GitHub Action <action@github.com>
2026-04-07 14:23:36 -07:00
pythongosssss
1b05927ff4 test: App mode - setting widget value test (#10746)
## Summary

Adds a test for setting various types of widgets in app mode, then
validating the /prompt API is called with the expected values

## Changes

- **What**: 
- extract duplicated enableLinearMode
- add AppModeWidgetHelper for setting values

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10746-test-App-mode-setting-widget-value-test-3336d73d365081739598fb5280d0127e)
by [Unito](https://www.unito.io)
2026-04-07 13:53:01 -07:00
pythongosssss
6f8e58bfa5 test: App Mode - widget reordering (#10685)
## Summary

Adds tests that simulate the user sorting the inputs and ensures they
are persisted and visible in app mode

## Changes

- **What**: 
- rework input/output selection helpers to accept widget/node names
- extract additional shared helpers

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10685-test-App-Mode-widget-reordering-3316d73d3650813b8348da5f29fd01f8)
by [Unito](https://www.unito.io)
2026-04-07 11:56:43 -07:00
jaeone94
a8d23275d9 fix: prevent subgraph node position corruption during graph transitions (#10828)
## Summary

Fix subgraph internal node positions being permanently corrupted when
entering a subgraph after a draft workflow reload. The corruption
accumulated across page refreshes, causing nodes to progressively drift
apart or compress together.

## Changes

- **What**: In the `ResizeObserver` callback
(`useVueNodeResizeTracking.ts`), node positions are now read from the
Layout Store (source of truth, initialized from LiteGraph) instead of
reverse-converting DOM screen coordinates via `getBoundingClientRect()`
+ `clientPosToCanvasPos()`. The fallback to DOM-based conversion is
retained only for nodes not yet present in the Layout Store.

## Root Cause

`ResizeObserver` was using `getBoundingClientRect()` to get DOM element
positions, then converting them to canvas coordinates via
`clientPosToCanvasPos()`. This conversion depends on the current
`canvas.ds.scale` and `canvas.ds.offset`.

During graph transitions (e.g., entering a subgraph from a draft-loaded
workflow), the canvas viewport was stale — it still had the **parent
graph's zoom level** because `fitView()` hadn't run yet (it's scheduled
via `requestAnimationFrame`). The `ResizeObserver` callback fired before
`fitView`, converting DOM positions using the wrong scale/offset, and
writing the corrupted positions to the Layout Store. The `useLayoutSync`
writeback then permanently overwrote the LiteGraph node positions.

The corruption accumulated across sessions:
1. Load workflow → enter subgraph → `ResizeObserver` writes corrupted
positions
2. Draft auto-saves the corrupted positions to localStorage
3. Page refresh → draft loads with corrupted positions → enter subgraph
→ positions corrupted further
4. Each cycle amplifies the drift based on the parent graph's zoom level

This is the same class of bug that PR #9121 fixed for **slot** positions
— the DOM→canvas coordinate conversion is inherently fragile during
viewport transitions. This PR applies the same principle to **node**
positions.

## Why This Only Affects `main` (No Backport Needed)

This bug requires two features that only exist on `main`, not on
`core/1.41` or `core/1.42`:

1. **PR #10247** changed `subgraphNavigationStore`'s watcher to `flush:
'sync'` and added `requestAnimationFrame(fitView)` on viewport cache
miss. This creates the timing window where `ResizeObserver` fires before
`fitView` corrects the canvas scale.
2. **PR #6811** added hash-based subgraph auto-entry on page load, which
triggers graph transitions during the draft reload flow.

On 1.41/1.42, `restoreViewport` does nothing on cache miss (no `fitView`
scheduling), and the watcher uses default async flush — so the
`ResizeObserver` never runs with a stale viewport.

## Review Focus

- The core change is small: use `nodeLayout.position` (already in the
Layout Store from `initializeFromLiteGraph`) instead of computing
position from `getBoundingClientRect()`. This eliminates the dependency
on canvas scale/offset being up-to-date during `ResizeObserver`
callbacks.
- The fallback path (`getBoundingClientRect` → `clientPosToCanvasPos`)
is retained for nodes not yet in the Layout Store (e.g., first render of
a newly created node). At that point the canvas transform is stable, so
the conversion is safe.
- Unit tests updated to reflect that position is no longer overwritten
from DOM when Layout Store already has the position.
- E2E test added: load subgraph workflow → enter subgraph → reload
(draft) → verify positions preserved.

## E2E Test Fixes

- `subgraphDraftPositions.spec.ts`: replaced `comfyPage.setup({
clearStorage: false })` with `page.reload()` + explicit draft
persistence polling. The `setup()` method performs a full navigation via
`goto()` which bypassed the draft auto-load flow.
- `SubgraphHelper.packAllInteriorNodes`: replaced `canvas.click()` with
`dispatchEvent('pointerdown'/'pointerup')`. The position fix places
subgraph nodes at their correct locations, which now overlap with DOM
widget textareas that intercept pointer events.

## Test Plan

- [x] Unit tests pass (`useVueNodeResizeTracking.test.ts`)
- [x] E2E test: `subgraphDraftPositions.spec.ts` — draft reload
preserves subgraph node positions
- [x] Manual: load workflow with subgraph, zoom in/out on root graph,
enter subgraph, verify no position drift
- [x] Manual: repeat with page refresh (draft reload) — positions should
be stable across reloads
- [x] Manual: drag nodes inside subgraph — positions should update
correctly
- [x] Manual: create new node inside subgraph — position should be set
correctly (fallback path)

## Screenshots
Before
<img width="1331" height="879" alt="스크린샷 2026-04-03 오전 3 56 48"
src="https://github.com/user-attachments/assets/377d1b2e-6d47-4884-8181-920e22fa6541"
/>

After
<img width="1282" height="715" alt="스크린샷 2026-04-03 오전 3 58 24"
src="https://github.com/user-attachments/assets/34528f6c-0225-4538-9383-227c849bccad"
/>


┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10828-fix-prevent-subgraph-node-position-corruption-during-graph-transitions-3366d73d365081418502dbb78da54013)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Alexander Brown <drjkl@comfy.org>
2026-04-07 14:34:56 +09:00
Christian Byrne
3a73ce72bb refactor: replace inline getByRole('dialog') with page objects in E2E tests (#10724)
## Summary

Replace remaining inline `getByRole('dialog')` calls in E2E tests with
page object accessors, following the pattern from PR #10586.

**Note:** The original scope covered 9 calls across 5 files. Three of
those refactors (ConfirmDialog, MediaLightbox, TemplatesDialog) were
already merged into main via other PRs, so this PR now covers only the
remaining 3 files.

## Changes

- **ComfyNodeSearchBox.ts**: Extract a `root` locator on
`ComfyNodeSearchFilterSelectionPanel` so `header` getter uses
`this.root` instead of an inline `page.getByRole('dialog')`
- **AppModeHelper.ts**: Add `imagePickerPopover` getter that locates the
PrimeVue Popover (`role="dialog"`) filtered by a button named "All"
- **appModeDropdownClipping.spec.ts**: Replace 4-line inline
`getByRole('dialog')` chain with `comfyPage.appMode.imagePickerPopover`

## Review Focus

Pure test infrastructure refactor — no production code changes. Each
page object follows existing conventions.

Fixes #10723
2026-04-06 16:42:09 -07:00
Dante
64f75f0727 test(assets): add E2E tests for delete confirmation flow (#10785)
## Summary

Add E2E Playwright tests for the asset delete confirmation dialog flow.

## Changes

- **What**: New `Assets sidebar - delete confirmation` describe block in
`assets.spec.ts` covering right-click delete showing confirmation
dialog, confirming delete removes asset with success toast, and
cancelling delete preserves asset. Added `mockDeleteHistory()` to
`AssetsHelper` to intercept POST `/api/history` delete payloads and
update mock state.

## Review Focus

Tests use existing `ConfirmDialog` page object and `AssetsHelper` mock
infrastructure. The `mockDeleteHistory` handler removes jobs from the
in-memory mock array so subsequent `/api/jobs` fetches reflect the
deletion.

Fixes #10781

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10785-test-assets-add-E2E-tests-for-delete-confirmation-flow-3356d73d365081fb90c8e2a69de3a666)
by [Unito](https://www.unito.io)
2026-04-06 10:17:23 -07:00
Dante
0d535631a5 refactor(test): extract dialog page objects from inline getByRole usage (#10822)
## Summary

Extract inline `getByRole('dialog')` calls across E2E tests into
reusable page objects.

## Changes

- **What**: Extract `ConfirmDialog` class from `ComfyPage.ts` into
`browser_tests/fixtures/components/ConfirmDialog.ts` with new `save`
button locator. Add `MediaLightbox` and `TemplatesDialog` page objects.
Refactor 4 test files to use these page objects instead of raw dialog
locators.
- **Skipped**: `appModeDropdownClipping.spec.ts` uses
`getByRole('dialog')` for a PrimeVue Popover (not a true dialog), left
as-is.

## Review Focus

The `ConfirmDialog.click()` method now supports a `save` action used by
`workflowPersistence.spec.ts`, which also waits for the dialog mask to
disappear and workflow service to settle.

Fixes #10723

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10822-refactor-test-extract-dialog-page-objects-from-inline-getByRole-usage-3366d73d365081b3bc0ee7ef0ddce658)
by [Unito](https://www.unito.io)
2026-04-06 09:49:32 -07:00
Benjamin Lu
b61e15293c test: address review comments on new browser tests (#10852) 2026-04-04 19:26:55 -07:00
Dante
899660b135 test: add queue overlay and workflow search E2E tests (#10802)
## Summary
- Add queue overlay E2E tests: toggle, filter tabs, completed filter,
close (5 tests)
- Add workflow sidebar search E2E tests: search input, filter by name,
clear, no matches (4 tests)
- Fix AssetsHelper mock timestamps from seconds to milliseconds
(matching backend's `int(time.time() * 1000)`)
- Type AssetsHelper response pagination with `JobsListResponse` from
`@comfyorg/ingest-types`

## Test plan
- [ ] CI passes all Playwright shards
- [ ] `pnpm typecheck:browser` passes
- [ ] `pnpm lint` passes

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10802-test-add-queue-overlay-and-workflow-search-E2E-tests-3356d73d365081018df8c7061c0854ee)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Benjamin Lu <benjaminlu1107@gmail.com>
2026-04-04 13:15:17 -07:00
Dante
17d2870ef4 test(modelLibrary): add E2E tests for model library sidebar tab (#10789)
## Summary
- Add `ModelLibraryHelper` mock helper for `/experiment/models` and
`/view_metadata` endpoints
- Add `ModelLibrarySidebarTab` page object fixture with search, folder,
and leaf locators
- Add 11 E2E test scenarios covering tab open/close, folder display,
folder expansion, search with debounce, refresh, load all folders, and
empty state

## Test plan
- [ ] CI passes all Playwright shards
- [ ] `pnpm typecheck:browser` passes
- [ ] `pnpm lint` passes

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10789-test-modelLibrary-add-E2E-tests-for-model-library-sidebar-tab-3356d73d365081b49a7ed752512164da)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 08:04:46 +09:00
Dante
8912f4159a test: add E2E tests for workflow tab operations (#10796)
## Summary

Add Playwright E2E tests for workflow tab interactions in the topbar.

## Changes

- **What**: New test file
`browser_tests/tests/topbar/workflowTabs.spec.ts` with 5 tests covering
default tab visibility, tab creation, switching, closing, and context
menu. Added `newWorkflowButton`, `getTab()`, and `getActiveTab()`
locators to `Topbar.ts` fixture.

## Review Focus

Tests are focused on tab UI interactions only (sidebar workflow
operations are already covered in `workflows.spec.ts`). Context menu
assertion uses Reka UI's `data-reka-context-menu-content` attribute.

┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-10796-test-add-E2E-tests-for-workflow-tab-operations-3356d73d36508170a657ef816e23b71c)
by [Unito](https://www.unito.io)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 07:07:31 +09:00