fix(player): the YouTube player keeps its size on a short window and when maximised
Two layout bugs since the player grew a side panel, both reported from prod. Maximised (F) on a wide window, the video was a thin line across the screen: the side-panel layout aligns the stage `self-start`, and Chrome applies a flex item's self-alignment to an absolutely positioned box too, so the fixed stage took its content's height — 0 px. The maximised stage now stretches between its insets whatever the layout asks of it. On a short window under 1280 px (a laptop at 100%, a 1080p screen at 175%) only the side strips were left: the card narrows so the chrome under the video fits, but that chrome grows as the card narrows (its text wraps), and the loop ran the card down to 2 px. The video now never goes narrower than 36rem to make room; past that the card scrolls. Measured before/after (localdev, real YouTube iframe): 1097×520 open 0×0 → 610×343; 1920×911 maximised 1920×0 → 1920×911; 1440×760 and 1366×650 maximised fill the window; leaving maximise restores the card. Held by an e2e test at both sizes (red on the old code: 0 px wide, and 911 ≠ 0), green on Chrome, WebKit and iPad.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { test, expect } from "@playwright/test";
|
||||
import { test, expect, type Page } from "@playwright/test";
|
||||
import { openApp, openFirstVideo } from "./helpers";
|
||||
|
||||
// Locks the in-app player's open/close contract. The player is a portaled overlay whose
|
||||
@@ -26,3 +26,41 @@ test.describe("player modal", () => {
|
||||
await expect(page.getByTestId("player-modal")).toHaveCount(0);
|
||||
});
|
||||
});
|
||||
|
||||
// The video's size, in the windows the owner meets: layout bugs no DOM test can see. Each viewport
|
||||
// is a real one — 1920×911 is a 1080p screen at 100% (the side-panel layout), 1097×520 the same
|
||||
// screen at 175% or a small laptop at 100% (the stacked layout, on a short window).
|
||||
test.describe("player modal sizing", () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await page.route(/youtube\.com/, (route) => route.abort());
|
||||
});
|
||||
|
||||
const box = async (page: Page, selector: string) =>
|
||||
(await page.locator(selector).first().boundingBox())!;
|
||||
|
||||
for (const [w, h] of [
|
||||
[1920, 911],
|
||||
[1097, 520],
|
||||
] as const) {
|
||||
test(`the video keeps a real size at ${w}×${h}, and maximised fills the window`, async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.setViewportSize({ width: w, height: h });
|
||||
await openApp(page);
|
||||
await openFirstVideo(page);
|
||||
|
||||
// A short window narrows the card so the chrome under the video fits — but the chrome grows
|
||||
// as the card narrows (its text wraps), and that loop once ran the card down to 2 px.
|
||||
const stage = await box(page, ".player-stage");
|
||||
expect(stage.width).toBeGreaterThanOrEqual(Math.min(w * 0.5, 560));
|
||||
expect(stage.height).toBeGreaterThan(stage.width * 0.5);
|
||||
|
||||
// Maximise (F): the stage is fixed to the viewport. In the side-panel layout its `self-start`
|
||||
// once aligned the fixed box too, and it shrank to its content's height — 0 px, a thin line.
|
||||
await page.getByTestId("player-modal").press("f");
|
||||
await expect(page.locator(".player-stage--max")).toHaveCount(1);
|
||||
const max = await box(page, ".player-stage--max");
|
||||
expect([Math.round(max.width), Math.round(max.height)]).toEqual([w, h]);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user