import { content, expect, test, written } from "./room"; import type { WebSocketRoute } from "@playwright/test"; const TABS = "01K0N4TR8K7JGM4R1J7PW4R8YA"; const FIRST = "01K0N4V4E7Y6P4MJ5WD8XZF3BA"; const SECOND = "01K0N4V4E7Y6P4MJ5WD8XZF3BB"; const SOURCE = `Before the tabs. Queue in memory only. After the tabs. `; test("tabs are renamed, added and removed in place, and the document keeps them", async ({ join, room, seed }) => { await seed(SOURCE); let page = await join("ana", { viewport: { width: 1440, height: 900 } }); let strip = content(page).getByRole("tablist"); let tabs = strip.getByRole("tab"); await expect(tabs).toHaveText(["Mobile", "Desktop"]); // Rename by double-click. Typing in the field never reaches the document. await strip.getByRole("tab", { name: "Desktop", exact: true }).dblclick(); let field = content(page).getByRole("textbox", { name: "Tab name", exact: true }); await expect(field).toBeFocused(); await page.keyboard.type("Wide screens"); await page.keyboard.press("Enter"); await expect(field).toHaveCount(0); await expect(tabs).toHaveText(["Mobile", "Wide screens"]); await expect(strip.getByRole("tab", { name: "Wide screens" })).toBeFocused(); await written(page, room, /\s* (await content(page).textContent()) ?? "").not.toContain( "Queue in memory only.", ); // The last tab cannot be removed. await expect(content(page).getByRole("button", { name: /^Remove / })).toHaveCount(0); await strip.getByRole("tab", { name: "Wide screens" }).press("Delete"); await expect(tabs).toHaveText(["Wide screens"]); await page.reload(); await expect(content(page).getByRole("tablist").getByRole("tab")).toHaveText(["Wide screens"]); }); test("undo restores a removed tab with its content", async ({ join, room, seed }) => { await seed(SOURCE); let page = await join("ana"); let strip = content(page).getByRole("tablist"); let tabs = strip.getByRole("tab"); await strip.getByRole("tab", { name: "Mobile", exact: true }).press("Delete"); await expect(tabs).toHaveText(["Desktop"]); await written(page, room, /[\s\S]*Queue in memory only\./); await page.reload(); await expect(content(page).getByRole("tablist").getByRole("tab")).toHaveText([ "Mobile", "Desktop", ]); await expect(content(page).getByText("Queue in memory only.")).toBeVisible(); }); test("touch removes the selected tab with one tap", async ({ join, seed }) => { await seed(SOURCE); let page = await join("ana", { viewport: { width: 390, height: 844 }, hasTouch: true, isMobile: true, }); let strip = content(page).getByRole("tablist"); let remove = content(page).getByRole("button", { name: "Remove Mobile", exact: true }); await expect(remove).toHaveCSS("opacity", "1"); await remove.tap(); await expect(strip.getByRole("tab")).toHaveText(["Desktop"]); }); test("a locked document offers no tab authoring", async ({ join, page, seed }) => { let sockets: WebSocketRoute[] = []; let offline = false; await page.routeWebSocket("**/ws?**", route => { if (offline) return route.close(); route.connectToServer(); sockets.push(route); }); await seed(SOURCE); await join("ana"); let strip = content(page).getByRole("tablist"); await strip.getByRole("tab", { name: "Desktop" }).hover(); await expect(content(page).getByRole("button", { name: "Remove Desktop" })).toBeAttached(); offline = true; await sockets.at(-1)!.close(); await expect(content(page)).toHaveAttribute("contenteditable", "false"); await expect(content(page).getByRole("button", { name: "Add tab" })).toHaveCount(0); await expect(content(page).getByRole("button", { name: /^Remove / })).toHaveCount(0); await strip.getByRole("tab", { name: "Desktop" }).dblclick(); await expect(content(page).getByRole("textbox", { name: "Tab name" })).toHaveCount(0); await expect(strip.getByRole("tab", { name: "Desktop" })).toHaveAttribute( "aria-selected", "true", ); });