Skip to content

Define e2e/lifecycle test taxonomy, inventory specs, and run lifecycle tests nightly#1247

Open
Kosinkadink wants to merge 15 commits into
mainfrom
test-taxonomy-1242
Open

Define e2e/lifecycle test taxonomy, inventory specs, and run lifecycle tests nightly#1247
Kosinkadink wants to merge 15 commits into
mainfrom
test-taxonomy-1242

Conversation

@Kosinkadink

@Kosinkadink Kosinkadink commented Jul 14, 2026

Copy link
Copy Markdown
Member

Closes #1242.

What this PR does

Defines a test taxonomy (unit / integration / E2E / lifecycle), applies it to every Playwright spec, and rewrites the lifecycle suite so it actually replaces manual release click-through testing.

Taxonomy + zero-mock policy (e2e/README.md)

  • E2E specs may inject synthetic state via dev hooks and assert on IPC dispatch; they run per-platform on every PR.
  • Lifecycle specs validate full user flows with zero mocking during app execution: real clicks, real downloads, real git, real disk. They run nightly + on demand via .github/workflows/lifecycle.yml (new).
  • Lifecycle tests must trigger the flow under test through the real UI control, never by calling window.api directly or synthesizing internal IPC. A broken button must fail these tests. Allowed scaffolding (fixture staging, stubbed native OS dialogs, read-only observation hooks) is spelled out in the README.
  • Every spec is inventoried with its tag, whether it meets the zero-mock bar, and evidence.

Lifecycle suite rewritten to drive real UI

All lifecycle flows now go through real controls: picker primary CTA, More menu, stopped-card Relaunch, dashboard/chooser kebabs, waffle menu, TrackModal, prompt/confirm surfaces, snapshot rows. Remaining direct bridge calls are fixture setup/cleanup between tests, documented in the README. New test ids: picker-primary-cta, picker-more-trigger, lifecycle-relaunch.

Product bugs the rewrite caught

  • Update-tab staleness gate: the picker re-fired check-update on every open because the dedupe set was per-component-instance and the picker remounts on reopen. Fixed by gating auto-refresh on lastCheckedAt older than 15 min; unit coverage added.
  • First-use Skip Onboarding lockdown: on the first-use Local branch handoff, the takeover unmount and overlay watcher pushed firstUseMode('none') before the chain re-asserted post-consent, briefly exposing the full file menu instead of only Skip Onboarding. Fixed by tracking chain handoffs and re-asserting post-consent at chain start. Caught by the rewritten lifecycle-first-use-skip.test.ts - exactly the regression class the zero-mock policy exists for. The overlay watcher's branching is extracted into a pure firstUseModeForOverlaySwap with table-test coverage, including the stale-chain-flag / ordinary-close case.

Retag: 12 seeded-state specs move to platform projects

Specs that inject synthetic runtime state (seedRunningSession, store seeding, synthetic op errors) or assert IPC dispatch are E2E by the taxonomy, not lifecycle. They are now tagged @windows @macos @linux and join PR-blocking CI; the lifecycle- filename prefix was dropped where present (e.g. lifecycle-port-conflict.test.ts -> port-conflict.test.ts).

The Windows stability pass surfaced a real race in picker-stop-confirm.test.ts: the run-action count poll could be satisfied by the picker's auto check-update before the self-stop wrapper dispatched update-comfyui, flaking the follow-up read. The test now polls for the update-comfyui dispatch itself.

Dead code removal

preview-desktop-migration IPC had no renderer callers (desktop adoption is an in-place reuse confirm with no snapshot preview). Removed the main handler, both preload bridges, the titlepopup shim entry, the channel constant, and the orphaned stageDesktopSnapshot helper.

Verification

  • pnpm run typecheck, typecheck:e2e, lint, build, test (188 files / 2797 tests) - all green.
  • Full --project=lifecycle suite green locally on Windows, including the ~500 MB real-install spec.
  • All 12 retagged specs green under --project=windows (27 tests), plus a repeat-each stability run of the fixed picker-stop-confirm.test.ts.

…le nightly

The lifecycle Playwright project was never wired into CI, so its tests
went stale (#1242). This defines the test categories and revives the
suite as an automated run:

- e2e/README.md: category definitions (unit / integration / e2e /
  lifecycle), the zero-mock policy for lifecycle tests, and a per-spec
  inventory noting which @lifecycle specs inject synthetic state and
  are retag candidates
- test:e2e:lifecycle script (playwright test --project=lifecycle)
- .github/workflows/lifecycle.yml: nightly + manual lifecycle run on
  windows-latest, non-PR-blocking, failure artifacts uploaded
- README: document the new script
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Changes

Lifecycle testing

Layer / File(s) Summary
Lifecycle testing contract and CI
e2e/README.md, TESTING.md, package.json, README.md, .github/workflows/lifecycle.yml
Defines lifecycle test categories and zero-mock rules, adds the dedicated command, and runs scheduled or manual Windows lifecycle tests with failure artifacts.
UI selectors and test observability
src/shared/testIds.ts, src/renderer/..., e2e/support/*, src/main/lib/e2eHooks.ts
Adds stable selectors, visible WebContents lookup, active-operation inspection, and overlay-state coverage for Playwright flows.
Lifecycle installation and operation flows
e2e/lifecycle*.test.ts
Reworks installation, copy, update, restart, stop, migration, onboarding, untrack, and delete scenarios around UI interactions and durable state assertions.
Snapshot and update flows
e2e/lifecycle-snapshot*.test.ts, e2e/lifecycle-update-check.test.ts, src/renderer/src/components/settings/*
Drives snapshot and update scenarios through picker controls, synchronizes rendered state, and gates automatic update checks on channel-card freshness.
First-use chain state and navigation coverage
src/renderer/src/panel/*, src/renderer/src/views/FirstUseTakeover.vue, e2e/lifecycle-first-use-*.test.ts, e2e/nav-matrix-*.test.ts, e2e/picker-*.test.ts
Preserves post-consent mode during takeover handoffs, validates onboarding flows, and retags platform-oriented navigation scenarios.
Desktop migration preview removal
src/main/lib/desktopDetect.ts, src/main/lib/ipc/*, src/main/popups/*, src/preload/*, src/renderer/src/comfyTitlePopup/*, src/types/ipc.ts
Removes desktop migration snapshot staging and its IPC, preload, picker bridge, shim, and contract entries.

Suggested reviewers: deepme987, maanilverma, benceruleanlu

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR documents the test taxonomy and rewrites lifecycle coverage to use real UI flows, fresh setup, and supporting workflow/tests, matching #1242's goals.
Out of Scope Changes check ✅ Passed The listed code changes support lifecycle automation and test-taxonomy work rather than unrelated feature work.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test-taxonomy-1242
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch test-taxonomy-1242

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

- Carve out the harness's global dialog.showErrorBox no-op and native OS
  file-dialog path stubs as allowed scaffolding
- Correct SeedOptions timing: installations/snapshots are written after
  launch, not before
- Reclassify dismiss-error, progress-reboot, deep-links, and nav-matrix-cloud
  as retag candidates based on actual runtime injection evidence
- Recast first-use-migrate and first-use-skip as strengthen-or-retag

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/lifecycle.yml:
- Around line 38-39: Update the lifecycle workflow’s “Build app” step to fetch
or create the required bootstrap-python directory before running pnpm run build,
following the repository’s README bootstrap instructions. Ensure the bootstrap
setup completes first so lifecycle tests and the build use the bundled Git
backend.
- Around line 41-42: Update the “Run lifecycle tests” workflow step to install
the required Playwright browser binaries before executing test:e2e:lifecycle,
using the repository’s existing package manager and Playwright setup
conventions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 78b33e11-868b-47f0-b7b7-08ebc673f468

📥 Commits

Reviewing files that changed from the base of the PR and between 9eecd3d and c3a3cf8.

📒 Files selected for processing (4)
  • .github/workflows/lifecycle.yml
  • README.md
  • e2e/README.md
  • package.json

Comment thread .github/workflows/lifecycle.yml
Comment thread .github/workflows/lifecycle.yml
…ence

- Allow public window.api triggers (runAction, probeInstallation) as
  scaffolding; forbid synthesized internal IPC and renderer-store writes
- Correct lifecycle-deep-links evidence: it replays panel-trigger-overlay
  directly, never exercising real comfy:// handling
- Drop the zero-mock label from the root README script row
- Drop the PT translation from the nightly cron comment
Lifecycle tests exist to replace manual click-through testing, so a broken
button must fail them. Direct window.api triggers (runAction, probe/track)
and synthesized internal IPC are now forbidden; read-only queries remain
fine for assertions. Reclassifies 8 more specs as strengthen-or-retag:
add-existing, copy, copy-update-fail, migrate, snapshot, snapshot-restore,
update-check, and lifecycle.test.ts itself.
The Update-tab watcher fired check-update on every picker open, even
when the selected channel card was checked seconds ago. The per-instance
dedupe set only stops repeats within one component instance, and the
picker remounts on every reopen — so fresh caches were re-fetched
anyway, and the lifecycle dedupe test caught it.

Gate the watcher on data.lastCheckedAt being missing or older than
STALE_CHANNEL_CARD_MS (15 min), matching the original behavior from
b13636c which is not an ancestor of this branch. Also fix
lifecycle-update-check.test.ts to read lastCheckedAt (the actual
channel-card field) instead of checkedAt, and add unit coverage for
the staleness gate.
…ndow.api

Rewrites lifecycle-update-check, lifecycle-snapshot, lifecycle-copy,
lifecycle-snapshot-restore, and lifecycle-copy-update-fail to click the
actual settings tabs, update buttons, snapshot CTA, and prompt inputs a
user would use, per the no-direct-window.api policy. Adds the testids
those flows need (settings tabs, compact check-update button, snapshot
save CTA).

copy-update-fail now seeds a source with ComfyUI/.git plus stale release
metadata so the copy-update button is genuinely reachable through the UI,
and asserts the failure via the durable app log since popup preloads
don't expose comfy-output.
Continuing past the start screen into the Local branch pushed
firstUseMode 'none' twice (FirstUseTakeover unmount + the overlay
watcher) before the chain re-asserted 'post-consent' — and that
re-assert waited on the install wizard's network-bound open(). For
those seconds the waffle menu offered the full file menu instead of
the single Skip Onboarding escape.

Assert 'post-consent' up front in the chain handler and skip the
'none' pushes for chain handoffs: FirstUseTakeover tracks chain exits
and the overlay watcher exempts the first-use -> takeover swap while
the chain is in flight. The chain-migrate path re-asserts immediately
after dismissTakeoverDirect instead of after the migration op.
Rewrites the rest of the lifecycle suite to fire flows from the
controls a user clicks, per the zero-mock policy:

- lifecycle.test.ts: restart via picker primary CTA, stop/relaunch via
  More menu + stopped-card Relaunch, copy via picker/dashboard-kebab
  prompts (BasePrompt ids, registry-record polling), untrack confirm in
  the panel's BaseAlert, RTD confirm helper covers panel and
  system-modal surfaces.
- lifecycle-add-existing: waffle menu -> Add Existing Instance ->
  TrackModal -> Browse -> Track (only the native dir picker stubbed).
- lifecycle-first-use-skip: real ToS -> Local -> Continue -> waffle
  Skip Onboarding.
- lifecycle-first-use-migrate: adoption op really runs; the stub .venv
  raises the real venv-broken prompt, answered Cancel; failure asserted
  in the progress error surface.
- lifecycle-migrate: chooser kebab -> Migrate -> rich adoption confirm
  in the picker popup -> Cancel; R2 CPU-variant contract guard kept.
- lifecycle-delete-untrack, lifecycle-snapshot-roundtrip,
  nav-matrix-cloud: kebab/context-menu/picker window-options flows.
- support: hasActiveOperation dev hook, WebContentsView-aware
  findWebContentsId, evalWithRetry hardening.
- testIds: pickerPrimaryCta, pickerMoreTrigger, lifecycleRelaunch
  production hooks; drop unused pickerRowOpen/pickerRowManage.
@coderabbitai
coderabbitai Bot requested a review from MaanilVerma July 14, 2026 13:59

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@e2e/lifecycle-add-existing.test.ts`:
- Around line 101-130: Make the TrackModal assertions self-contained by ensuring
the test covering `#track-name` and the test covering the probed summary both
perform the title-bar “Add Existing Instance” navigation and Browse setup, or
merge them into one test. Do not rely on modal state left by a preceding test,
so focused execution and worker restarts can run each test independently.

In `@e2e/lifecycle-copy-update-fail.test.ts`:
- Around line 124-132: Update the confirmation handling around confirmSelector
so it waits for either the confirmation control or an observable indication that
the copy operation has started, rather than relying on the fixed 2-second
timeout. Click the confirmation when it appears, while allowing the progress
path to continue when no confirmation is required; preserve behavior across slow
Windows runs without introducing process-lifecycle races.

In `@e2e/lifecycle-first-use-skip.test.ts`:
- Around line 37-40: Update the comment in the test case to describe the merged
consent and cloud/local selection start screen without mentioning the
originating commit hash, leaving the hero and Continue CTA comments unchanged.

In `@e2e/lifecycle-update-check.test.ts`:
- Around line 139-181: Update the test around openPickerOnUpdateTab,
checkButton, and the latestVersion poll to distinguish the manual check from the
tab-open auto-refresh: after the button becomes enabled, reset the run-action
state, click the button, and explicitly wait for a new invocation plus operation
drain or button re-enablement before asserting the remote result and closing the
popup. Use the existing readiness signals/helpers rather than relying on
latestVersion data alone.

In `@e2e/lifecycle.test.ts`:
- Around line 706-719: Update the confirmation handling around panel and
system-modal clicks so clicked is set to true and the loop exits only when the
respective click call returns true. If either click returns false because the
surface disappeared, leave clicked false and continue polling through the
existing lifecycle readiness flow.
- Around line 245-252: Extract the repeated Electron/DOM probe used by both
waits into a shared helper near the lifecycle test utilities, using the existing
webContents lookup and .brand-primary.config-continue selector. Replace both
inline evalWithRetry callbacks with calls to that helper, preserving the current
behavior of returning false when panel.html is unavailable and true only when
the Continue button is enabled.
- Around line 1181-1212: Extract the duplicated prompt-input population and
copy-completion registry polling from the copy flow and the corresponding flow
near the referenced second occurrence into shared helpers in the test file.
Reuse those helpers in both flows, preserving the existing input/change event
behavior, completion timeout and polling intervals, and assignment of the copied
installation record and identifiers.

In `@src/renderer/src/views/FirstUseTakeover.vue`:
- Around line 275-278: Update resetContinue() to clear chainHandoff, and move
the exit-path assignment in emitCompleted() before the completedFired
early-return so every retry or alternate exit recomputes the current handoff
state. Apply the same ordering/reset behavior to the additional emitCompleted
call sites.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 020e4798-cf01-4c56-8505-af03538eb135

📥 Commits

Reviewing files that changed from the base of the PR and between 4c3678f and 7309bc8.

📒 Files selected for processing (26)
  • e2e/README.md
  • e2e/lifecycle-add-existing.test.ts
  • e2e/lifecycle-copy-update-fail.test.ts
  • e2e/lifecycle-copy.test.ts
  • e2e/lifecycle-delete-untrack.test.ts
  • e2e/lifecycle-first-use-migrate.test.ts
  • e2e/lifecycle-first-use-skip.test.ts
  • e2e/lifecycle-migrate.test.ts
  • e2e/lifecycle-snapshot-restore.test.ts
  • e2e/lifecycle-snapshot-roundtrip.test.ts
  • e2e/lifecycle-snapshot.test.ts
  • e2e/lifecycle-update-check.test.ts
  • e2e/lifecycle.test.ts
  • e2e/nav-matrix-cloud.test.ts
  • e2e/support/cdpPages.ts
  • e2e/support/devHooks.ts
  • src/main/lib/e2eHooks.ts
  • src/renderer/src/components/settings/ComfyUISettingsContent.test.ts
  • src/renderer/src/components/settings/ComfyUISettingsContent.vue
  • src/renderer/src/panel/ComfyLifecycleView.vue
  • src/renderer/src/panel/useFirstUseChain.ts
  • src/renderer/src/panel/usePanelOverlays.ts
  • src/renderer/src/views/FirstUseTakeover.vue
  • src/renderer/src/views/comfyUISettings/ChannelPicker.vue
  • src/renderer/src/views/comfyUISettings/SnapshotsView.vue
  • src/shared/testIds.ts

Comment thread e2e/lifecycle-add-existing.test.ts Outdated
Comment thread e2e/lifecycle-copy-update-fail.test.ts Outdated
Comment thread e2e/lifecycle-first-use-skip.test.ts Outdated
Comment thread e2e/lifecycle-update-check.test.ts
Comment thread e2e/lifecycle.test.ts Outdated
Comment thread e2e/lifecycle.test.ts Outdated
Comment thread e2e/lifecycle.test.ts Outdated
Comment thread src/renderer/src/views/FirstUseTakeover.vue Outdated
No renderer ever calls previewDesktopMigration: desktop adoption is an
in-place reuse confirm (useAdoptAction) with no snapshot preview, and the
standalone migrate path uses previewLocalMigration. Remove the dead main
handler, both preload bridges, the titlepopup shim entry, the channel
constant, and the now-orphaned stageDesktopSnapshot helper.
…jects

These specs inject synthetic runtime state (seedRunningSession, store
seeding, synthetic op errors) or assert IPC dispatch instead of real side
effects, which makes them E2E tests under the taxonomy, not zero-mock
lifecycle tests. Tag them @windows @MacOS @linux so they join PR-blocking
CI, and drop the lifecycle- filename prefix where present.

Stability check on Windows surfaced a real race in picker-stop-confirm:
the run-action count poll could be satisfied by the picker's auto
check-update before the self-stop wrapper dispatched update-comfyui,
making the follow-up single read flake. Poll for the update-comfyui
dispatch itself instead.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/lib/desktopDetect.ts (1)

153-153: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove captureDesktopSnapshot if nothing else calls it.
No in-repo references remain, so this looks like orphaned code—time to prune the snap before it becomes a fossil.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/lib/desktopDetect.ts` at line 153, Remove the exported
captureDesktopSnapshot function from desktopDetect.ts because it has no
remaining in-repository callers. Also remove any imports, types, or helper code
used exclusively by this function, while preserving code still used elsewhere.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@e2e/picker-stop-confirm.test.ts`:
- Around line 243-252: Fix the duplicated type assertion in the
getIpcInvocations call so the calls result is cast only once. Extract the
repeated run-action polling logic into a shared variable or helper, then reuse
it for both checks while preserving the existing timeout, intervals, and
actionId matching behavior.
- Around line 198-207: Remove the duplicated type assertion in the
getIpcInvocations call so the calls value has one valid array type annotation.
Extract the repeated run-action polling logic into a shared helper or variable,
parameterized by the required action identifier, and reuse it for both polling
checks to prevent divergence.

---

Outside diff comments:
In `@src/main/lib/desktopDetect.ts`:
- Line 153: Remove the exported captureDesktopSnapshot function from
desktopDetect.ts because it has no remaining in-repository callers. Also remove
any imports, types, or helper code used exclusively by this function, while
preserving code still used elsewhere.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e34c1a5b-8875-4ff9-b2b9-6a07af431168

📥 Commits

Reviewing files that changed from the base of the PR and between 7309bc8 and 8644d1d.

📒 Files selected for processing (22)
  • e2e/README.md
  • e2e/cancel-flow.test.ts
  • e2e/copy-update-destination.test.ts
  • e2e/deep-links.test.ts
  • e2e/dismiss-error.test.ts
  • e2e/lifecycle-first-use-migrate.test.ts
  • e2e/nav-matrix-dashboard.test.ts
  • e2e/nav-matrix-instance.test.ts
  • e2e/picker-cluster.test.ts
  • e2e/picker-settings-staleness.test.ts
  • e2e/picker-stop-confirm.test.ts
  • e2e/port-conflict.test.ts
  • e2e/progress-error-overflow.test.ts
  • e2e/progress-reboot.test.ts
  • src/main/lib/desktopDetect.ts
  • src/main/lib/ipc/registerSnapshotHandlers.ts
  • src/main/lib/ipc/shared.ts
  • src/main/popups/pickerSettingsHandlers.ts
  • src/preload/api.ts
  • src/preload/comfyTitlePopupPreload.ts
  • src/renderer/src/comfyTitlePopup/pickerSettingsApiShim.ts
  • src/types/ipc.ts
💤 Files with no reviewable changes (6)
  • src/preload/api.ts
  • src/main/lib/ipc/registerSnapshotHandlers.ts
  • src/main/popups/pickerSettingsHandlers.ts
  • src/preload/comfyTitlePopupPreload.ts
  • src/renderer/src/comfyTitlePopup/pickerSettingsApiShim.ts
  • src/types/ipc.ts

Comment thread e2e/picker-stop-confirm.test.ts Outdated
Comment thread e2e/picker-stop-confirm.test.ts Outdated
Pull the overlay watcher's lockdown branching into a pure
firstUseModeForOverlaySwap so the chain-handoff exemption is directly
testable: the first-use -> takeover swap must not clobber the chain's
post-consent assert, and a stale chain flag must never suppress the
none push on ordinary overlay closes.
@Kosinkadink

Copy link
Copy Markdown
Member Author

Code review (agent-assisted, full branch diff vs origin/main)

Verdict: no blockers found.

Reviewed with priority on the risk areas of this branch:

  1. First-use mode state machine across takeover swaps - the overlay exemption requires all three of: previous overlay is first-use, next is another takeover, and the chain flag is active. Ordinary closes transition to null and still push firstUseMode('none'); renderer-driven first-use dismissal clears the mode explicitly. A canceled migration leaves the component-local chainHandoff flag set, but no reachable non-chain close path lets that stale flag keep the menu locked. The branching is now extracted into pure firstUseModeForOverlaySwap with table tests covering the stale-flag/ordinary-close and handoff/no-intermediate-none cases.
  2. Staleness gate (ComfyUISettingsContent.vue) - missing/null/zero/older lastCheckedAt refreshes; a fresh timestamp suppresses only the automatic watcher. The manual Check for Update button never consults the gate. Matches the earlier known-good implementation.
  3. preview-desktop-migration removal - no remaining callers, channel strings, bridge methods, types, or imports. Desktop adoption is unaffected: desktopAdopt uses captureDesktopSnapshot directly, which stays.
  4. picker-stop-confirm race fix - polling for the update-comfyui dispatch itself is sound; production awaits stop-and-exit before dispatching it, so the follow-up "stop-comfyui fires exactly once" assertion is stable.
  5. Retagged specs - none of the 12 depends on the lifecycle project's 180 s timeout, test.setTimeout, or cross-spec profile reuse; all launch isolated seeded profiles. Green under --project=windows locally (27 tests); macOS/Linux stability is verified by this PR's own CI.

One practical entry point for the four test categories (unit /
integration / E2E / lifecycle): what each may fake, where specs live,
run commands, which category a new test belongs in, and the CI mapping.
Deep policy and the per-spec inventory stay in e2e/README.md.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/renderer/src/panel/usePanelOverlays.ts`:
- Around line 155-167: In firstUseModeForOverlaySwap, compute
isProgressTakeover(next) once in a shared local variable and reuse it for both
conditional checks, preserving the existing return behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 648d61b0-352b-4ee6-b0fb-0fb7dc806c87

📥 Commits

Reviewing files that changed from the base of the PR and between 8644d1d and 6d41333.

📒 Files selected for processing (4)
  • README.md
  • TESTING.md
  • src/renderer/src/panel/usePanelOverlays.test.ts
  • src/renderer/src/panel/usePanelOverlays.ts

Comment thread src/renderer/src/panel/usePanelOverlays.ts
…etch

- FirstUseTakeover: recompute chainHandoff before the completed-dedupe
  early return and clear it in resetContinue so a cancelled chain can't
  leave a stale handoff suppressing the unmount 'none' push
- lifecycle.yml: fetch bootstrap Python before build so lifecycle CI
  exercises the bundled git backend instead of the runner's system git
- e2e: merge add-existing into one self-contained test; replace the
  fixed 2s confirm guess in copy-update-fail with a confirm-or-started
  poll; assert the manual check-update dispatch (not auto-refresh data)
  in update-check; only mark the RTD confirm clicked when the click
  lands; extract shared helpers (config Continue probe, copy name
  prompt + registration poll, forwarded update dispatch poll)
- usePanelOverlays: reuse the isProgressTakeover(next) result
- drop a stale commit-hash reference from a test comment
… hook

Seeded install records were written to installations.json after launch,
so one-shot hydration missed them, no installations-changed broadcast
fired, and the boot-time sweep could delete records whose dirs held only
ignored entries. Seed via E2E_INSTALLATIONS_SEED before first load
(mirroring E2E_SETTINGS_SEED), create .launcher markers so the sweep
keeps seeded installs, harden popup helpers against destroyed
webContents, and run the port-override launch test last since it leaves
a launch op in flight.
On headless Linux CI, openPath spawned dbus-send (not unref'd) with an
xdg-open fallback; the child kept the main process alive on quit, so
picker-cluster's afterAll hit the 45s worker-teardown timeout. E2E
asserts the run-action IPC fired, not the OS side effect, so gate the
real open behind the existing E2E env check.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Lifecycle tests are very stale and not used now because of that staleness.

1 participant