Skip to content

The ruler gradation test is flaky under parallel load: the mock clip is recorded in real time #55

Description

@CodyCBakerPhD

selection.spec.ts's "the ruler lays out time gradations, and stays put in frame mode" asserts an exact gradation count:

await expect(page.locator("#selruler .sel-tick")).toHaveCount(5);

That count is derived from the loaded video's measured duration and frame rate, and the video it loads is ?test&mock_video's synthesized clip. synthesizeVideoFile captures through MediaRecorder in real time — 30 frames with await new Promise((r) => setTimeout(r, 33)) between them — so the clip's actual duration is whatever the machine took to record it. Under CPU contention it runs long, the fps MediaBunnyVideoBackend derives from the packet span shifts, and rulerStep lands on the next gradation down: 6 ticks instead of 5.

Reproduced on unmodified origin/main (5143eea), no changes applied:

npx playwright test selection.spec.ts -g "the ruler lays out time gradations" --repeat-each=12 --workers=4
  3 failed
  9 passed

Run on its own it passes every time; it only fails when something else is competing for the CPU, which is exactly what the full suite at fullyParallel: true does — and what a loaded CI runner does.

Two directions, either of which would settle it:

  • Assert a range rather than an exact count, or assert the ruler is built from the video at all (that there is more than one gradation and the first is labelled 0:00) rather than pinning the number. The test's own comment says the point is "that the ruler is built from the loaded video rather than hard-coded", which a range still shows.
  • Give the test a clip whose duration does not depend on wall-clock time. synthesizeLongVideoFile already writes samples at explicit timestamps through mediabunny's Output/CanvasSource, decoupled from real time entirely; a short fixed-duration mock built the same way would make this count deterministic.

Found while running the suite for #53, which does not touch rulerMarks, the mock's frame count, or its timing — the flake is left alone there rather than papered over.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions