In a table cell WebKit resolved the picture's h-full against the aspect-video box as the poster's own height, so the box showed a native-size sliver of it. The box now has a fixed 16:9 height, as the other pictures in tables do; an e2e check runs in the WebKit and iPad projects.
89 lines
3.7 KiB
TypeScript
89 lines
3.7 KiB
TypeScript
import { test, expect } from "@playwright/test";
|
|
import { gotoPage, openApp } from "./helpers";
|
|
|
|
// The Files library end to end, against the real app: the page opens on the whole library, and a
|
|
// link — typed into its box, or pasted onto any page — opens the one download dialog on it. Nothing
|
|
// is downloaded: the dialog is closed, so the run leaves the E2E account's library as it found it.
|
|
test.describe("Files", () => {
|
|
const LINK = "https://www.youtube.com/watch?v=jNQXAC9IVRw";
|
|
const dialog = (page: import("@playwright/test").Page) =>
|
|
page.getByRole("dialog", { name: "Download video" });
|
|
|
|
test("opens on the whole library, and its link box hands a link to the download dialog", async ({
|
|
page,
|
|
}) => {
|
|
await openApp(page);
|
|
await gotoPage(page, "files");
|
|
await expect(page.getByRole("heading", { name: "All files" })).toBeVisible();
|
|
const box = page.getByRole("textbox", { name: "A link to download" });
|
|
await box.fill(LINK);
|
|
await box.press("Enter");
|
|
await expect(dialog(page)).toBeVisible();
|
|
await expect(dialog(page)).toContainText("jNQXAC9IVRw");
|
|
await page.keyboard.press("Escape");
|
|
await expect(dialog(page)).toBeHidden();
|
|
});
|
|
|
|
// WebKit (every iPad browser) cannot resolve a percentage height against a box whose height comes
|
|
// from aspect-ratio inside a table cell: the picture took its own full height and the 16:9 box
|
|
// showed a native-size sliver of it, a blur of colour. The library is stubbed with one file whose
|
|
// poster is a tall picture, the case that shows it most.
|
|
test("a row's picture fits its box", async ({ page }) => {
|
|
const file = {
|
|
id: 990001,
|
|
status: "done",
|
|
progress: 100,
|
|
created_at: "2026-11-14T10:00:00+00:00",
|
|
source_kind: "youtube",
|
|
source_ref: "e2e-thumb",
|
|
source_url: null,
|
|
poster_url: "/api/downloads/990001/poster.jpg",
|
|
display_name: "A tall poster",
|
|
display_uploader: null,
|
|
extra_links: [],
|
|
can_download: true,
|
|
job_kind: "download",
|
|
folder_id: null,
|
|
kept: false,
|
|
expires_at: null,
|
|
shared: false,
|
|
source_key: "youtube",
|
|
asset: { media_kind: "video", duration_s: 60, size_bytes: 2048 },
|
|
};
|
|
await page.route(/\/api\/files(\?|$)/, (route) => route.fulfill({ json: [file] }));
|
|
await page.route(/\/api\/downloads\/990001\/poster\.jpg/, (route) =>
|
|
route.fulfill({
|
|
contentType: "image/svg+xml",
|
|
body: '<svg xmlns="http://www.w3.org/2000/svg" width="1080" height="1920"><rect width="1080" height="1920" fill="#3a6"/></svg>',
|
|
}),
|
|
);
|
|
// Wide enough that the picture column shows beside a pinned rail (an iPad Pro in landscape).
|
|
await page.setViewportSize({ width: 1366, height: 1024 });
|
|
await openApp(page);
|
|
await gotoPage(page, "files");
|
|
const picture = page.getByRole("row", { name: /A tall poster/ }).locator("img");
|
|
await expect(picture).toBeVisible();
|
|
const fit = await picture.evaluate((img) => {
|
|
const box = img.parentElement!.getBoundingClientRect();
|
|
return { img: img.getBoundingClientRect().height, box: box.height };
|
|
});
|
|
expect(fit.img).toBeLessThanOrEqual(fit.box);
|
|
});
|
|
|
|
test("a link pasted onto a page (not into a field) opens the download dialog", async ({
|
|
page,
|
|
}) => {
|
|
await openApp(page);
|
|
await page.evaluate((text) => {
|
|
const e = new Event("paste", { bubbles: true, cancelable: true });
|
|
Object.defineProperty(e, "clipboardData", {
|
|
value: { getData: (type: string) => (type === "text/plain" ? text : "") },
|
|
});
|
|
document.body.dispatchEvent(e);
|
|
}, LINK);
|
|
await expect(dialog(page)).toBeVisible();
|
|
await page.keyboard.press("Escape");
|
|
await expect(dialog(page)).toBeHidden();
|
|
});
|
|
});
|