Skip to content

Lead polish 2: full-split drop target, Favorite splits past 12, e2e evaluate race - #10

Merged
siyabendoezdemir merged 10 commits into
mainfrom
lead/polish2
Oct 10, 2026
Merged

siyabendoezdemir merged 10 commits into
mainfrom
lead/polish2

Conversation

@siyabendoezdemir

@siyabendoezdemir siyabendoezdemir commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Lead follow-ups after PRs #6 and #7: one sidebar fix, one Favorites limit, and a race in the e2e harness that loses test changes.

What

  • SV-25: a full split's row is no drop target (9b51615, src/renderer/src/shell/sidebar/drag.ts).

    • Before: a tab resting on the row of a 4-pane split lit up a half, and the drop was then refused with the "split is full" toast.
    • Now: the row shows no target and reorders like any other row, as the page area already does.
    • The new e2e test fails without the fix (Expected: 0, Received: 1 highlighted halves).
  • SV-26 test can't race or hang (9b51615, test only).

    • The grow-in sampler now starts before the pane is added, times samples from when the card enters the page, and stops by itself.
    • CI had seen a 120 s hang and a first sample already 94% grown.
  • FV-02: a Favorite split never comes apart past 12 Favorites (8edc3e5, lead review F1).

    • A Favorite split counts as one tile (D19). Separate makes one tile per pane, and Move Out makes two.
    • Both are now refused with the "Favorites are full (12 max)" toast when they would pass the limit. A split elsewhere is never limited.
    • Unit test for the count; an e2e test fills Favorites, checks both refusals change nothing, then frees a tile and moves a pane out.
  • E2E harness: each main-process evaluate runs in a task of its own (f755593, tests/e2e/helpers.ts, src/main/test-hooks.ts).

    • Playwright runs main-process evaluates through the inspector, which can run them in the middle of other main-process code, even inside a store update.
    • A tab a test created there was overwritten when that update finished, so it vanished. This happened in about 1 run in 12 of the new Favorites test.
    • A stack trace put the test's tabs.create inside immer's patch generation for a favicon update.
    • launchOrbit now wraps app.evaluate so the function runs after a setImmediate. The hooks' run and action defer too, for the perf and capture scripts.
    • Production is unchanged: without an inspector, nothing interrupts main-process code.
    • The SP-11 flake (core.spec.ts:195: a profile change reached listeners, then reverted in the store) fits the same cause.
    • So does SV-06's Linux CI failure at f65f537 (split.spec.ts:1110). The context menu for a tab the test had just created came back empty, which tabMenu returns only for a tab missing from the store. Each test launches its own app, so the empty menu wasn't left over from an earlier test.
  • Every e2e test server takes a free port within 3300–3399 (6d73442, f8a1988).

    • The favicon tests (tabs-review.spec.ts) bound fixed ports 3390 and 3392, so two suites running at once could collide.
    • 6d73442 moved them to port 0, but the OS then picks a port outside the project's range.
    • listenInRange (tests/e2e/helpers.ts) takes the first free port from a base up to 3399, as startFixtures already did. The fixtures, the Peek fixtures and both favicon servers use it.
  • E2E tests stay offline (0a63ed6, tests/e2e/helpers.ts).

    • Three command bar tests opened real DuckDuckGo and YouTube searches, and a Peek test opened meet.google.com. They check only URLs, but the pages loaded from CI and from dev machines.
    • launchOrbit now starts Orbit with --proxy-server pointing at a closed loopback port. Loopback, where the fixtures are served, bypasses it.
    • It then waits until every profile's session resolves through that proxy. A session picks up the command line's proxy about 50 ms after the sidebar shows; before that, resolveProxy says DIRECT.
    • Checked by a scratch test, not committed: a DuckDuckGo search fails with ERR_PROXY_CONNECTION_FAILED while a fixture page loads.

Checks

  • npm run build, npm run typecheck, npm run lint: exit 0. npx vitest run: 216/216.

  • Full e2e at 1440×900, 1 worker: 177/177, exit 0. After merging main with PR Peek (link preview) and Mini Window #8 (5335293): 217/217, exit 0, Peek and Mini Window tests included.

  • With 0a63ed6: the three search tests, the Peek meeting test and SP-11, 5/5. The full suite is running.

  • The Favorites test: 60 of 60 after the harness fix.

  • split.spec.ts at 1024×768 (the macOS CI window size): 40/40.

  • Failing first:

    • SV-25: the new test fails without the fix.
    • FV-02: the e2e test fails on the old split/index.ts, because Separate goes through and no toast shows.
  • docs/ARCHITECTURE.md (Testing) says why evaluates are deferred (1c14d54).

Review

  • Independent review (reviews/lead-polish2.md in the Orca context, at f8a1988): REQUEST CHANGES, 2 must-fixes and 7 follow-ups. The reviewer confirmed the harness race and its fix, SV-25, SV-26 and the offline proxy. Across all 217 tests, nothing connected off the machine.
  • Lead fixes (D18), each with a test that fails without it:
    • M1, 3942167: a Favorite split could still make a 13th Favorite four ways: Duplicate; Open in Split View on one of its panes and a Today tab; and ⌘⇧T or ⌘Z on a pane closed from it after the split filled up again. I found a fifth while fixing them: ⌘⇧T on a removed Favorite split after Favorites filled up.
      • Duplicate and Open in Split View are now refused with "Favorites are full (12 max)". Open in Split View tries the change on a throwaway copy of the state and refuses it when a Favorites grid would grow past 12.
      • A tab or split coming back to a full Favorites grid lands in Today.
      • Three unit tests and one e2e test fail without the fix: 13 tiles, or a split id instead of null.
    • M2, d2e4b8d (test only): SP-21 pressed the new row in the frame or two after it finished growing in. In that window the slot is back to content-visibility: auto and hit testing skips the row. The test now waits until the row takes presses: 15/15 passed, where the review saw 4 of 15 fail. Users can lose a click the same way; that goes to the feel lane.
  • Checks at d2e4b8d:
    • typecheck and lint exit 0; unit tests 255/255;
    • the split, tabs and spaces e2e files at 1440×900, 1 worker: 88/88, exit 0.
    • The full local check, the merge gate, is in its own section below.
  • The follow-ups F1–F7 are tracked in the lead's STATUS.md.

Local check (merge gate, D42)

GitHub Actions is off for cost, so this local check is the merge gate. On d2e4b8d, in this PR's worktree (Linux, Xvfb, one worker):

npm run build; npm run typecheck; npm run lint; npx vitest run
xvfb-run -a -s "-screen 0 1440x900x24" ./node_modules/.bin/playwright test --workers 1 --retries 0

🤖 Generated with Claude Code


Note

Cursor Bugbot is generating a summary for commit d2e4b8d. Configure here.

siyabendoezdemir and others added 3 commits October 9, 2026 22:12
- A tab resting on a full, 4-pane split row no longer gets a half
  highlighted: the row reorders like any other, as the page drop already
  shows no indicator for a full split (SV-25, split review follow-up).
  New e2e test fails without the fix (the half is highlighted).
- SV-26 grow-in test: the frame sampler is installed before the pane is
  added, times frames from when the card enters the page, checks the
  spring's shape only on frames that came in time, and stops by itself.
  CI hung on it for 120 s and, on retry, saw a first sample at 94 %.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…02, lead review F1)

A Favorite split counts as one tile (D19). Separating it makes one tile per
pane, and moving a pane out makes two, so both could take a profile past
the 12-Favorite limit. Both are now refused with the "Favorites are full"
toast when they would; a split anywhere else is never limited. The toast
text is one constant, shared with the tabs code.

Unit test for the count, and an e2e test that fills Favorites, checks both
refusals leave everything as it was, then frees a tile and moves a pane
out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Playwright runs main-process evaluates through the inspector, which can
run them in the middle of other main-process code, even inside a store
update. A tab a test created there was overwritten when that update
finished, so it vanished: about 1 run in 12 of the new Favorites test.
A stack trace placed the test's tabs.create inside immer's patch
generation for a favicon update.

launchOrbit now wraps app.evaluate so the test's function runs after a
setImmediate. The test hooks' run and action defer too, which covers the
perf and capture scripts. The Favorites test then passed 60 of 60, and
the full suite passes. The SP-11 flake (a profile change that reached
listeners, then reverted in the store) fits the same cause.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cursor

cursor Bot commented Oct 9, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: d63f690d-d7ab-40d7-97a5-258a85a723ac)

They bound 127.0.0.1:3390 and 3392, so two full suites running at once
on one machine (several agents do) could collide. Now the OS picks a free
port.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cursor

cursor Bot commented Oct 9, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: f3eaeebe-4ec9-4327-9347-fb723e10355b)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cursor

cursor Bot commented Oct 9, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: 1a962ca5-1d62-471f-8bcf-2ca677ab9c98)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cursor

cursor Bot commented Oct 9, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: f710692d-de8f-4a23-97f2-e8fa580ec11d)

Three command bar tests opened real DuckDuckGo and YouTube searches and a Peek test opened
meet.google.com. They only check URLs, but the pages loaded from CI and dev machines. launchOrbit
now starts Orbit with --proxy-server pointing at a closed loopback port (loopback, where the
fixtures are served, bypasses it), and waits until every profile's session resolves through it:
a session picks the command line's proxy up about 50 ms after the sidebar shows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cursor

cursor Bot commented Oct 9, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: eec68383-ea2d-4f27-ad17-8738dce8794d)

The favicon tests' servers moved to port 0 in 6d73442, which the OS picks from outside the
project's port range. listenInRange takes the first free port from a base up to 3399, as the
fixture servers already did; startFixtures, the Peek fixtures and both favicon servers use it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cursor

cursor Bot commented Oct 9, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: 96f47697-cc7c-4276-9a38-a6824681c6b6)

siyabendoezdemir and others added 2 commits October 10, 2026 01:19
…make a 13th Favorite (PR #10 review M1)

A Favorite split could still take Favorites past 12 four ways (FV-02):
- Duplicate put a copy beside it as a new tile;
- Open in Split View on one of its panes and a Today tab left that pane's
  split in place and added the new split as a tile;
- ⌘⇧T or ⌘Z on a pane closed from it put the pane back in its Favorites
  spot when the split was full again;
- ⌘⇧T on a whole Favorite split removed from the sidebar put it back after
  Favorites had filled up.

Duplicate and Open in Split View are now refused with the "Favorites are
full" toast. Open in Split View tries the change on a throwaway copy of the
state and refuses it when a Favorites grid would grow past 12. A tab or
split coming back to a full Favorites grid lands in Today instead.

Tests (each fails without the fix: 13 tiles, or a split id instead of null):
- split-tabs.test.ts: a closed pane reopened, and one undone, while its
  Favorite split is full; a removed Favorite split reopened once Favorites
  filled up.
- split.spec.ts: Duplicate and Open in Split View at 12 tiles are refused,
  and both work once there is room.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…iew M2)

A row that has just finished growing in drops `.is-growing`, and its slot
goes back to `content-visibility: auto`. For a frame or two after that,
hit testing skips the row, so the test's press landed on the slot and no
drag started. The reviewer saw 4 failures in 15 runs at f8a1988. The test
now waits until `elementFromPoint` at the row's centre is the row. With
the wait, SP-21 passed 15 of 15 runs. Users can lose a click the same way:
that follow-up (F1) goes to the feel lane.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cursor

cursor Bot commented Oct 10, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: 1a7b9099-ab76-4c34-9981-113c845d63c2)

@siyabendoezdemir
siyabendoezdemir merged commit 9a6d536 into main Oct 10, 2026
1 of 4 checks passed
siyabendoezdemir added a commit that referenced this pull request Oct 10, 2026
Conflicts:
- Sidebar.tsx: the update banner and media's tray both sit above the Space switcher, the banner first.
- rpc.ts: RendererView takes both 'pip' and 'onboarding'.
- FEATURES.md: regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
siyabendoezdemir added a commit that referenced this pull request Oct 10, 2026
docs/ARCHITECTURE.md §9: main's E2E bullet (dead proxy, deferred evaluates,
the quit check) with this branch's merge-gate bullet in place of the CI one.
FEATURES.md regenerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
siyabendoezdemir added a commit that referenced this pull request Oct 10, 2026
test: harness follow-ups from PR #10's review (no DNS lookups, deferred evaluateHandle, SV-25/SV-26, perf)
siyabendoezdemir added a commit that referenced this pull request Oct 10, 2026
…osed row takes its gap (FL-04, FL-05, FL-09)

- FL-05: the pressed row shows as selected in the frame of the press, ahead of
  main's answer, and any hover fade on it stops so the highlight is not held back.
- PR #10 review F1: a row stays drawn (content-visibility: visible) from the
  moment it grows in until it first leaves the screen, and a press on its slot
  goes to the row, so a press just after the growth ends selects it.
- FL-04: a hover fade that is turned round starts from the colour it shows
  rather than from full, and starts in the frame it is made.
- FL-09: a single close collapses at once, with no stagger delay, and the
  1 px list gap goes with the row as it collapses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

1 participant