Skip to content

Add a browser test suite, and fix the two faults it found - #29

Merged
ibrahimweng merged 2 commits into
mainfrom
claude/browser-tests
Aug 30, 2026
Merged

Add a browser test suite, and fix the two faults it found#29
ibrahimweng merged 2 commits into
mainfrom
claude/browser-tests

Conversation

@ibrahimweng

Copy link
Copy Markdown
Owner

The 199 tests we had all measure pure functions under Node. That is the right shape for what a curve means or what a WAV header says, and the wrong shape for the interface — which is where the faults have actually been:

  • a tool cursor set on the timeline viewport, which every surface inside it overrode, so picking up the blade changed nothing you could see
  • a cursor drawn from a data URI the browser accepted, reported back intact, and silently failed to decode
  • the blade looking for .tl__cue, a class that has never existed
  • a panel dropped into the empty column landing nowhere, because tearing down the drag collapsed that column before the drop was worked out
  • six panel tabs overflowing their column into a scrollbar that had been switched off, so two panels could not be opened at all

Every one of those shipped. Every one was found by driving a browser by hand and then forgotten, because the script that found it lived in a temporary folder.

What is here

41 Playwright tests in test/browser/, run against the built site rather than the dev server — the dock tab fault was found by comparing what shipped to the design and would not have shown up any other way.

Spec What it pins
tools.spec.ts (8) the letter keys change tool; each tool's cursor over a sound, where the fault was; drawn cursors decode as real images; alt flips zoom; the hand pans without moving anything; the blade cuts; the range tool draws and Delete clears
layout.spec.ts (12) at 1440 and 1280: every tab inside its column and clickable, nothing past the end of the app bar, no strip hiding its end, no sideways page scroll
docking.spec.ts (6) drag into the empty column, drag back, survives a reload, the Window menu closes and reopens a panel, reset
menus.spec.ts (7) right-click gives a menu about that thing and acts on it; Escape and click-away close it; the browser's own menu stays away; a menu at the edge stays on screen
project.spec.ts (8) length as timecode or bare seconds; bad input says so; a longer piece is a longer ruler; the playhead scrubs and plays past the end of the clip

Each test names the fault it is for. The clip they need is a few seconds of canvas recorded through MediaRecorder in the page — about ninety kilobytes, made in under a second, and no binary in the repository that somebody has to take on trust. test/browser/app.ts holds what they all share.

Two faults found while writing them, both fixed here

The transport was hiding its last three controls. overflow-x: auto with scrollbar-width: none: at 1440 the help dot and part of the reference switch sat past the edge, and at 1280 the video window toggle, the reference switch and help were off it entirely, with nothing on screen saying they existed or that the strip could be dragged. The same trap the panel tabs were in. It wraps now, which costs a row of height only at the widths where it was otherwise swallowing controls.

Pressing play just after loading a clip was undone. The frame rate is measured by running the picture muted for half a second and putting it back to the start — and the clip is announced as ready before that begins, so the transport is live. A play inside that window was answered by the measurement finishing, stopping the clip and dropping you at zero, with nothing said about why. Whoever is driving wins now.

Checking

Every test was checked by putting its fault back into the code and watching it fail — the tool cursor override, the .tl__cue blade, the empty-column drop, both hidden scrollbars, and both new fixes. Three repeat runs, no flakes. The 199 existing tests and the build still pass.

CI gets its own job: Chromium once rather than per Node version, since what it checks is what the browser does with the built site and that does not vary with the Node that built it. Traces and screenshots are kept as an artifact when something fails.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Ux1kydvUkLRoMbHp82ofDi


Generated by Claude Code

The 199 tests we had all measure pure functions under Node. That is the
right shape for what a curve means or what a WAV header says, and the
wrong shape for the interface — which is where the faults have actually
been. A tool cursor set on the timeline viewport that every surface
inside it overrode. A cursor drawn from a data URI the browser accepted,
reported back intact, and silently failed to decode. The blade looking
for `.tl__cue`, a class that has never existed. A panel dropped into the
empty column landing nowhere. Six panel tabs overflowing their column
into a scrollbar that had been switched off. Every one of those shipped,
and every one was found by driving a browser by hand and then forgotten,
because the script that found it lived in a temporary folder.

So: 41 Playwright tests in `test/browser/`, run against the built site
rather than the dev server, since the dock tab fault was found by
comparing what shipped to the design and would not have shown up any
other way. Each test names the fault it is for. The clip they need is a
few seconds of canvas recorded through MediaRecorder in the page — about
ninety kilobytes, made in under a second, and no binary in the repo that
somebody has to take on trust.

Writing them turned up two more faults, both fixed here:

- The transport hid its last three controls. It scrolled sideways with
  its scrollbar disabled, so at 1440 the help dot and half the reference
  switch sat past the edge, and at 1280 the video window toggle, the
  reference switch and help were off it entirely, with nothing saying
  they existed. It wraps now, which costs a row of height only at the
  widths where it would otherwise be swallowing controls.

- Pressing play just after loading a clip was undone. The frame rate is
  measured by running the picture muted for half a second and putting it
  back to the start, and the transport comes alive before that starts —
  so a play inside that window was answered by a silent jump to zero.
  Whoever is driving wins now.

Every test was checked by putting its fault back into the code and
watching it fail.

CI runs the suite once on Chromium rather than per Node version: what it
checks is what the browser does with the built site, which does not vary
with the Node that built it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ux1kydvUkLRoMbHp82ofDi
@vercel

vercel Bot commented Aug 30, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
beat-studio Ready Ready Preview Aug 30, 2026 9:51am

The browser job timed out after two minutes without starting a test.
Nothing had gone wrong with the suite: the server it waits for was
listening somewhere else.

Vite asks Node not to reorder what a name resolves to, so `localhost`
binds to whichever address the machine's hosts file lists first. This
container has only `127.0.0.1 localhost`, so it bound to IPv4 and every
local run passed. Ubuntu also carries `::1 localhost`, so on CI it bound
to IPv6 alone and the `http://127.0.0.1:4173` we were polling was never
going to answer.

Name the interface rather than leaving it to be worked out, and pass the
server's output through: the timeout said only that nothing came up, and
threw away whatever the build or the server had said about why.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ux1kydvUkLRoMbHp82ofDi
@ibrahimweng
ibrahimweng merged commit 205c295 into main Aug 30, 2026
5 checks passed
@ibrahimweng
ibrahimweng deleted the claude/browser-tests branch August 30, 2026 10:07
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