fix(files): review round 1, the page — honest states, the keyboard, the tray's words
- A library past the list's cap is searched and sorted on the server; the count says "the newest". - Each folder and each search opens on its first page (DataTable pageScope, useCardPager scope). - A file dropped where the page takes none never reaches the browser (which would unload the app). - The viewer's arrows wait while a layer opened from it is on top, and scroll a wide text line; a text shows its first 5000 lines and says where the rest is. - Confirms name the file (no more "your downloads"); the asking menu rows end in "…". - The tray names a running step beside its bar, shows a pause mark for paused work, polls slowly while only paused work waits, and forgets a finished file that was deleted. - An unchanged rename sends nothing; a paste opens the download dialog only with nothing on top; the link box never replaces what was typed. - Honest states: folders that failed to load, a file no longer there, the storage figure; the rail says "nothing downloaded" only when there is nothing. - Focus after deleting the open folder and when the format form opens; the format name's label. - ui/Meter (one danger line for both quota bars) and ui/RenameField in the platform layer. - Copy fixes, stale comments and the speculative hub key; a contract test for the list's parameters; e2e: the Files page and the paste intake.
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
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();
|
||||
});
|
||||
|
||||
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();
|
||||
});
|
||||
});
|
||||
@@ -10,7 +10,7 @@ test.describe("page switching", () => {
|
||||
// `nav-admin`) that opens a panel of them — the spec still listed them as rail rows of their own,
|
||||
// and it failed on every run for a while without anyone seeing it, because e2e was in no
|
||||
// required gate (it is now part of `release`).
|
||||
const RAIL = ["channels", "playlists", "stats", "settings", "feed"];
|
||||
const RAIL = ["channels", "playlists", "files", "stats", "settings", "feed"];
|
||||
const ADMIN = ["scheduler", "config", "users", "audit"];
|
||||
|
||||
test("each rail item activates its page", async ({ page }) => {
|
||||
|
||||
Reference in New Issue
Block a user