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",
);
});