From a47febdbfe54cf16609b0908fb81367ff3c03417 Mon Sep 17 00:00:00 2001 From: Miguel Angel Simon Sierra Date: Sat, 19 Sep 2026 17:03:04 -0400 Subject: [PATCH] fix(studio): rename Timeline's aria-label so it does not collide with its dock panel wrapper Every dock panel wrapper now carries aria-label=, matching the "Timeline" title for the timeline panel. Timeline.tsx also set aria-label="Timeline" on its own content div, so `document.querySelector('[aria-label=\"Timeline\"]')` found the dock wrapper first and the timeline viewport gate CI check timed out waiting for an attribute the real content div actually carried. Renamed to "Timeline track view" and updated every consumer: the production diagnostics selector, its tests, and the e2e viewport-gate script. --- packages/studio/src/player/components/Timeline.tsx | 2 +- .../player/lib/timelinePerformanceDiagnostics.test.ts | 5 +++-- .../src/player/lib/timelinePerformanceDiagnostics.ts | 2 +- packages/studio/tests/e2e/timeline-virtualization.mjs | 10 ++++++---- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/studio/src/player/components/Timeline.tsx b/packages/studio/src/player/components/Timeline.tsx index 2af548aca4..c50e8d362a 100644 --- a/packages/studio/src/player/components/Timeline.tsx +++ b/packages/studio/src/player/components/Timeline.tsx @@ -448,7 +448,7 @@ export const Timeline = memo(function Timeline({ return ( <div ref={setContainerRef} - aria-label="Timeline" + aria-label="Timeline track view" data-timeline-element-count={expandedElements.length} className={`relative border-t select-none h-full overflow-hidden ${assetDrop.isDragOver ? "ring-1 ring-inset ring-studio-accent/60" : ""} ${activeTool === "razor" ? "cursor-crosshair" : shiftHeld ? "cursor-crosshair" : "cursor-default"}`} onMouseMove={updateRazorGuide} diff --git a/packages/studio/src/player/lib/timelinePerformanceDiagnostics.test.ts b/packages/studio/src/player/lib/timelinePerformanceDiagnostics.test.ts index 30557fc85d..93eaff8cba 100644 --- a/packages/studio/src/player/lib/timelinePerformanceDiagnostics.test.ts +++ b/packages/studio/src/player/lib/timelinePerformanceDiagnostics.test.ts @@ -14,7 +14,7 @@ describe("timeline performance diagnostics", () => { it("reads mounted resources without mutating the timeline", () => { document.body.innerHTML = ` - <div aria-label="Timeline" data-timeline-scheduler-queued="3" + <div aria-label="Timeline track view" data-timeline-scheduler-queued="3" data-timeline-scheduler-active="2" data-timeline-cache-bytes="4096"> <div data-timeline-row><div data-clip="true"></div><div data-clip="true"></div></div> <div data-timeline-row><div data-clip="true"></div></div> @@ -41,7 +41,8 @@ describe("timeline performance diagnostics", () => { }); it("returns the zero baseline after unmount or reset removes the DOM", () => { - document.body.innerHTML = '<div aria-label="Timeline"><div data-clip="true"></div></div>'; + document.body.innerHTML = + '<div aria-label="Timeline track view"><div data-clip="true"></div></div>'; expect(readTimelinePerformanceDiagnostics().mountedClipRoots).toBe(1); document.body.replaceChildren(); diff --git a/packages/studio/src/player/lib/timelinePerformanceDiagnostics.ts b/packages/studio/src/player/lib/timelinePerformanceDiagnostics.ts index 2b30e615d4..6747477618 100644 --- a/packages/studio/src/player/lib/timelinePerformanceDiagnostics.ts +++ b/packages/studio/src/player/lib/timelinePerformanceDiagnostics.ts @@ -69,7 +69,7 @@ function sumDataAttribute(root: ParentNode, selector: string, dataKey: string): export function readTimelinePerformanceDiagnostics( root: ParentNode = document, ): Readonly<TimelinePerformanceDiagnostics> { - const timelineRoots = root.querySelectorAll<HTMLElement>('[aria-label="Timeline"]'); + const timelineRoots = root.querySelectorAll<HTMLElement>('[aria-label="Timeline track view"]'); let mountedTimelineDescendants = 0; for (const timelineRoot of timelineRoots) { mountedTimelineDescendants += timelineRoot.querySelectorAll("*").length; diff --git a/packages/studio/tests/e2e/timeline-virtualization.mjs b/packages/studio/tests/e2e/timeline-virtualization.mjs index 89e1ea803f..521da8ffee 100644 --- a/packages/studio/tests/e2e/timeline-virtualization.mjs +++ b/packages/studio/tests/e2e/timeline-virtualization.mjs @@ -103,7 +103,7 @@ async function collectRun(page, injectedLongTaskMs = 0) { } function findTimelineScroller() { - const root = document.querySelector('[aria-label="Timeline"]'); + const root = document.querySelector('[aria-label="Timeline track view"]'); if (!(root instanceof HTMLElement)) throw new Error("Timeline root not mounted"); const scroller = root.querySelector("[data-timeline-scroll-viewport]"); if (!(scroller instanceof HTMLElement)) throw new Error("Timeline scroller not mounted"); @@ -172,7 +172,7 @@ async function assertLongTaskCapture(browser, longTaskLimitMs, scrollSamplesPerR const injectedDurationMs = longTaskLimitMs + 25; try { await page.setContent(` - <div aria-label="Timeline"> + <div aria-label="Timeline track view"> <div data-timeline-scroll-viewport style="width:100px;height:100px;overflow:auto"> <div style="width:1000px;height:1000px"></div> </div> @@ -334,7 +334,9 @@ try { } await page.evaluate(() => window.__studioTest.resetTimelinePerformanceFixture()); - await page.waitForFunction(() => document.querySelector('[aria-label="Timeline"]') === null); + await page.waitForFunction( + () => document.querySelector('[aria-label="Timeline track view"]') === null, + ); await waitForStudioTestHookSettle(page); await loadFixtureAndWait(page, 1_000, PROFILE); await client.send("HeapProfiler.collectGarbage"); @@ -418,7 +420,7 @@ async function waitForFixtureRender(page, elementCount) { modelCount: window.__playerStore?.getState().elements.length ?? null, renderedCount: document - .querySelector('[aria-label="Timeline"]') + .querySelector('[aria-label="Timeline track view"]') ?.getAttribute("data-timeline-element-count") ?? null, })); if (observed.renderedCount === String(elementCount)) {