Skip to content

test(embed): take the panel session id from the test, not from a parsed href - #524

Merged
omridevk merged 2 commits into
mainfrom
fix/panel-session-no-parsing
Aug 16, 2026
Merged

test(embed): take the panel session id from the test, not from a parsed href#524
omridevk merged 2 commits into
mainfrom
fix/panel-session-no-parsing

Conversation

@omridevk

@omridevk omridevk commented Aug 15, 2026

Copy link
Copy Markdown
Contributor

Follow-up to #514. The embed test helpers reconstructed a session id by dissecting a persisted URL. They now take it from the test that created the session.

What was there

packages/embed/tests/e2e/helpers/navigation.ts built a path with a fake id, split it back apart to recover the literal /panel/, then round-tripped to validate:

function panelHref(sessionId: string): string {
  return interpolatePath({path: '/panel/$sessionId', params: {sessionId}}).interpolatedPath
}
function panelSessionIdOf(href: string): string {
  const [panelPrefix] = panelHref(SESSION_PROBE).split(SESSION_PROBE)
  ...
}

The stated point was that the router should own path construction, so a route rename breaks the helper. That never held: '/panel/$sessionId' is a bare string literal, so a rename changes nothing at compile time and the round-trip still passes against the renamed literal. What remained was the indirection without the guarantee.

The right TanStack APIs for this are router.buildLocation({to, params}) and router.matchRoutes(pathname), but both need a router instance. There is none in the Playwright node process — importing @conciv/app/router there fails with ERR_UNKNOWN_FILE_EXTENSION because the route tree pulls Solid .tsx, and the widget deliberately does not expose its router globally (packages/embed/src/mount-impl.tsx:99,109 saves and restores window.__TSR_ROUTER__).

So the fix is not a better parsing API. The test process should not be reconstructing app knowledge at all — the same mistake as the seeding backdoor #514 removed, one layer down.

What it does now

The test creates the session, so the test knows the id. New openPanelOnNewSession(page, suite) in helpers/panel.ts creates the session, attaches the wire watcher before goto, settles boot traffic, opens the panel, and returns the id.

The boot-traffic wait is load-bearing rather than defensive: without it the launcher click can beat the sessions.list/sessions.resolve queries and fall through to /panel/latest, which mints a different id. That is the same race warm-session-resolve.it.test.ts already waits on.

sessions.resolve({}) is not an alternative, and this is worth recording. With no id it does not return the currently-open session, nor the most recently updated one — packages/core/src/chat/session-rows.ts:70 mints a fresh uuid and does not insert a row. panel.latest.tsx uses it as "give me a new session to land on". Reading it from a test would hand back an id no draft is ever written under.

Deleted

helpers/navigation.ts entirely (panelHref, panelSessionIdOf, panelSessionId, SESSION_PROBE, RELATIVE_HREF_BASE, the interpolatePath import), panelDraft (only ever used inside drafts.ts), and the @tanstack/router-core devDependency — confirmed orphaned by grep and fallow dead-code --trace-dependency @tanstack/router-coreUNUSED (0 imports).

One failure worth reporting

The first full run was 98 passed / 1 failed, in native-widget:

Error: until: stall - condition not met within 30000ms
    at native-widget.it.test.ts:157:5

It passed in isolation. Root cause: that file shares one kit across tests, so an earlier test persists a navigation row and the later page boot restores that route instead of consulting the warm session — leaving the grab test on the earlier test's minted session. Fixed by creating the session in beforeAll, before any page boots, so the restored row already points at it. Not retried, not quarantined.

Evidence

Embed suite 99 passed × 3 real runs (cache-bypassed, since turbo went FULL TURBO). extension-testkit and apps/conciv green. Whole-repo typecheck 96/96, lint 101/101, format clean, fallow audit zero introduced, check-changesets exit 0. Zero product-code delta.

Note

panel-session-switch.it.test.ts (from #523) is not on this base and is untouched. When both land it must supply its own session ids the same way — resolve({}) mints, so it cannot be used to disambiguate a switch.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Tests
    • Improved end-to-end coverage for draft persistence, including command-chip text and caret-position restoration after reloads.
    • Increased reliability of native widget and panel tests by explicitly tracking newly created sessions.
    • Streamlined test setup and draft verification across panel, reload, and selection scenarios.

…ed href

The embed e2e helpers rebuilt the panel route prefix with interpolatePath
and a probe id, then dissected the persisted href back into a session id.
The tests now create the session they are about to exercise and pass its
id to untilPanelDraft, so the id comes from the server that minted it.

Deletes helpers/navigation.ts (panelHref, panelSessionIdOf, panelSessionId,
SESSION_PROBE, RELATIVE_HREF_BASE) and the @tanstack/router-core devDep.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@omridevk omridevk added the no-changeset PR intentionally ships no release note label Aug 15, 2026
@coderabbitai

coderabbitai Bot commented Aug 15, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@omridevk, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 3 minutes

Limit details: You’ve used all 3 included reviews currently available under your plan.

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a2cafcd0-2a12-4b95-892e-2c8675ecfe3f

📥 Commits

Reviewing files that changed from the base of the PR and between 3655b8e and f688b8b.

📒 Files selected for processing (1)
  • packages/embed/tests/e2e/helpers/panel.ts

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 80b2bf1d-a955-43a8-a9f8-9338ebc0727e

📥 Commits

Reviewing files that changed from the base of the PR and between 45e328e and 3655b8e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (8)
  • packages/embed/package.json
  • packages/embed/tests/e2e/composer-rich-input.it.test.ts
  • packages/embed/tests/e2e/draft-selection.it.test.ts
  • packages/embed/tests/e2e/helpers/drafts.ts
  • packages/embed/tests/e2e/helpers/navigation.ts
  • packages/embed/tests/e2e/helpers/panel.ts
  • packages/embed/tests/e2e/native-widget.it.test.ts
  • packages/embed/tests/e2e/reload-continuity.it.test.ts
💤 Files with no reviewable changes (2)
  • packages/embed/package.json
  • packages/embed/tests/e2e/helpers/navigation.ts

Included review availability: Your plan includes up to 3 reviews per rolling hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The embed E2E helpers now create sessions explicitly, wait for session boot traffic, and scope draft checks to session IDs. Related panel tests use the new flow. The embed package also removes an unused development dependency.

Changes

Embed E2E session scoping

Layer / File(s) Summary
Session and draft helper updates
packages/embed/tests/e2e/helpers/panel.ts, packages/embed/tests/e2e/helpers/drafts.ts, packages/embed/tests/e2e/helpers/navigation.ts
openPanelOnNewSession creates and boots a session before opening the panel. untilPanelDraft uses an explicit session ID. The previous navigation helper is removed.
Panel and draft test migration
packages/embed/tests/e2e/composer-rich-input.it.test.ts, packages/embed/tests/e2e/draft-selection.it.test.ts, packages/embed/tests/e2e/reload-continuity.it.test.ts
Tests capture session IDs during panel setup and pass them to draft persistence checks.
Native widget session setup
packages/embed/tests/e2e/native-widget.it.test.ts
Native widget tests create a shared session, wait for boot traffic, and scope draft polling to that session.

Embed dependency cleanup

Layer / File(s) Summary
Development dependency removal
packages/embed/package.json
Removes @tanstack/router-core from development dependencies.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: 🔵 Low · up to 3655b

The tests now use session IDs returned when they create sessions, but the boot flow does not explicitly confirm that the created session is the one opened afterward. If selection diverges, assertions could target the wrong session; the change is otherwise mergeable with explicit owner awareness or follow-up.

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: tests now use the created panel session ID instead of parsing it from a URL.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/panel-session-no-parsing

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

…n pill, not an rpc settle

The helper waited on sessions.list/sessions.resolve wire traffic and swallowed
the resolve timeout, so an unfired resolve let the launcher click fall through
to /panel/latest and mint a different session than the one the test created.
It now names the created session, picks it in the session selector, and blocks
on the pill carrying that title.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changeset PR intentionally ships no release note

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant