import { expect, test, type Download, type Page } from "@playwright/test"; import { createMinimalOdp, createMinimalOds, createMinimalOdt, type OdfFixture, } from "../fixtures/odf"; const entry = "/deep/nested/office/"; async function openFixture(page: Page, fixture: OdfFixture) { await page.goto(entry); await page.getByTestId("office-file-input").setInputFiles(fixture); await expect(page.getByText("Rendered locally", { exact: true })).toBeVisible( { timeout: 30_000, }, ); } async function find(page: Page, value: string) { const search = page.getByRole("search"); await search.getByPlaceholder("Find in file").fill(value); await search.getByRole("button", { name: "Find" }).click(); await expect(search.getByText("1 of 1", { exact: true })).toBeVisible(); } async function downloadedBytes(download: Download): Promise { const stream = await download.createReadStream(); const chunks: Uint8Array[] = []; let total = 0; for await (const chunk of stream) { const bytes = typeof chunk === "string" ? new TextEncoder().encode(chunk) : new Uint8Array(chunk as ArrayBufferLike); chunks.push(bytes); total += bytes.byteLength; } const result = new Uint8Array(total); let offset = 0; for (const chunk of chunks) { result.set(chunk, offset); offset += chunk.byteLength; } return result; } test("renders and searches a project-authored ODT in an isolated worker", async ({ page, }) => { const fixture = createMinimalOdt(); const externalHosts = new Set(); const errors: string[] = []; const workerScripts: URL[] = []; page.on("request", (request) => { const url = new URL(request.url()); if ( (url.protocol === "http:" || url.protocol === "https:") && url.hostname !== "127.0.0.1" ) externalHosts.add(url.hostname); if (url.pathname.includes("odf.worker")) workerScripts.push(url); }); page.on("console", (message) => { if (message.type() === "error") errors.push(message.text()); }); page.on("pageerror", (error) => errors.push(error.message)); await openFixture(page, fixture); await expect( page.getByRole("heading", { name: "OpenDocument Text Fixture" }), ).toBeVisible(); await expect( page.getByRole("table", { name: "Fixture table" }), ).toBeVisible(); await expect( page.getByRole("img", { name: "Project-authored fixture image" }), ).toBeVisible(); await find(page, "ODT Search Marker"); await page.getByRole("button", { name: "Zoom in" }).click(); await expect(page.getByText("110%", { exact: true })).toBeVisible(); const exactCopy = page.waitForEvent("download"); await page.getByRole("button", { name: "Save exact copy" }).click(); const exactBytes = await downloadedBytes(await exactCopy); expect([...exactBytes]).toEqual([...fixture.buffer]); expect(externalHosts).toEqual(new Set()); expect(errors).toEqual([]); expect(workerScripts.length).toBeGreaterThan(0); expect( workerScripts.every( (url) => url.origin === "http://127.0.0.1:4173" && url.pathname.startsWith("/deep/nested/office/assets/"), ), ).toBe(true); }); test("renders, searches and switches sheets in a project-authored ODS", async ({ page, }) => { await openFixture(page, createMinimalOds()); await expect(page.getByText("sheet 1 of 2", { exact: true })).toBeVisible(); await expect(page.getByRole("grid")).toContainText("Office Tools Workbook"); await find(page, "ODS Search Marker"); await page.getByRole("button", { name: "Next sheet" }).click(); await expect(page.getByText("sheet 2 of 2", { exact: true })).toBeVisible(); await expect(page.getByRole("grid")).toContainText("Second sheet content"); const csvDownload = page.waitForEvent("download"); await page.getByRole("button", { name: "Export sheet CSV" }).click(); const csv = new TextDecoder().decode( await downloadedBytes(await csvDownload), ); expect(csv).toContain("Second sheet content"); }); test("renders, searches and navigates a project-authored ODP", async ({ page, }) => { await openFixture(page, createMinimalOdp()); await expect(page.getByText("slide 1 of 2", { exact: true })).toBeVisible(); await expect( page.getByRole("heading", { name: "OpenDocument Presentation Fixture" }), ).toBeVisible(); await find(page, "ODP Search Marker"); await expect(page.getByText("slide 2 of 2", { exact: true })).toBeVisible(); await expect( page.getByRole("heading", { name: "ODP Search Marker" }), ).toBeVisible(); await expect( page.getByRole("complementary", { name: "Speaker notes" }), ).toContainText("Second speaker note"); });