commit a3c5706ddb9a2fe46c5ff85663f71585b7d8114e
parent e6310a8c1230604409f5b2df88151203e4e360dd
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Mon, 28 Sep 2026 12:46:59 -0400
e2e: transcript-source's diagnostics test regenerates the report of the swapped tree
The release-11 full-suite flake (1 failure, 9/9 alone): resetData's
invalidate-cache clears the snapshot scheduler's timer, but a regeneration
already in flight runs on and writes snapshot.json from the tree it read,
before the spec's swap. generateReport returns as soon as any snapshot.json
exists, so the page rendered that stale report. Now the spec deletes
snapshot.json after the swap and clicks Refresh report until the report
shows the nonStandardVtt bucket with one video (chat-only's refreshReport
pattern). Spec-only: the race is the harness reset's, not product code's.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Diffstat:
1 file changed, 33 insertions(+), 4 deletions(-)
diff --git a/editor/e2e/transcript-source.spec.ts b/editor/e2e/transcript-source.spec.ts
@@ -2,15 +2,16 @@ import { rm, writeFile } from "node:fs/promises";
import { test, expect } from "@playwright/test";
import {
channelStage,
- generateReport,
pathExists,
+ readJson,
resetData,
resolvePath,
} from "./helpers";
const CHANNEL = "test-youtube";
const VIDEO_DIR = "20240101_test1234567";
-const DATA = `test-transcripts/channels/${CHANNEL}/data/${VIDEO_DIR}`;
+const ROOT = `test-transcripts/channels/${CHANNEL}`;
+const DATA = `${ROOT}/data/${VIDEO_DIR}`;
const VIDEO_URL = `/channels/${CHANNEL}/videos/${VIDEO_DIR}`;
const VTT = "WEBVTT\n\n00:00:00.000 --> 00:00:05.000\nhello\n";
@@ -80,8 +81,36 @@ test("diagnostics list a video with only transcript.en-US.vtt", async ({
await rm(resolvePath(`${DATA}/transcript.en.vtt`), { force: true });
await writeFile(resolvePath(`${DATA}/transcript.en-US.vtt`), VTT);
- // First channel-page load generates a fresh snapshot including the bucket.
- await generateReport(page, CHANNEL);
+ // A REPORT OF THE SWAPPED TREE, NOT JUST A REPORT. resetData's
+ // invalidate-cache clears the snapshot scheduler's TIMER, but a regeneration
+ // already in flight (armed by the previous spec's action) runs to the end
+ // and writes snapshot.json from the tree it read — before the swap above.
+ // generateReport returns as soon as any snapshot.json exists, so this test
+ // used to render that stale report: 1 failure in release 11's full suite,
+ // 9/9 alone. So: drop whatever is there, then regenerate until the report
+ // shows the bucket (chat-only.spec's refreshReport does the same).
+ await rm(resolvePath(`${ROOT}/snapshot.json`), { force: true });
+ await page.goto(`/channels/${CHANNEL}`);
+ const refresh = page.getByRole("button", { name: /refresh report/i });
+ await refresh.waitFor({ state: "visible" });
+ await expect
+ .poll(
+ async () => {
+ // Retried: a click before hydration fires nothing, and a stale write
+ // landing after a good one is answered by the next click.
+ await refresh.click({ timeout: 5_000 }).catch(() => {});
+ for (let i = 0; i < 20; i++) {
+ const snap = await readJson<{
+ buckets?: { nonStandardVtt?: string[] };
+ }>(`${ROOT}/snapshot.json`).catch(() => null);
+ if (snap?.buckets?.nonStandardVtt?.length === 1) return true;
+ await new Promise((r) => setTimeout(r, 250));
+ }
+ return false;
+ },
+ { timeout: 60_000, intervals: [1000] },
+ )
+ .toBe(true);
await page.goto(channelStage(CHANNEL, "diagnostics"));
await expect(