Release Office Tools 0.2.0
Verify / verify (push) Canceled after 0s

This commit is contained in:
2026-09-02 07:32:31 +02:00
parent a5524e27e3
commit 08b8f84f7b
50 changed files with 2196 additions and 165 deletions
+35 -2
View File
@@ -1,4 +1,4 @@
import { expect, test, type Page } from "@playwright/test";
import { expect, test, type Download, type Page } from "@playwright/test";
import {
createMinimalOdp,
createMinimalOds,
@@ -25,9 +25,31 @@ async function find(page: Page, value: string) {
await expect(search.getByText("1 of 1", { exact: true })).toBeVisible();
}
async function downloadedBytes(download: Download): Promise<Uint8Array> {
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<string>();
const errors: string[] = [];
const workerScripts: URL[] = [];
@@ -45,7 +67,7 @@ test("renders and searches a project-authored ODT in an isolated worker", async
});
page.on("pageerror", (error) => errors.push(error.message));
await openFixture(page, createMinimalOdt());
await openFixture(page, fixture);
await expect(
page.getByRole("heading", { name: "OpenDocument Text Fixture" }),
).toBeVisible();
@@ -59,6 +81,11 @@ test("renders and searches a project-authored ODT in an isolated worker", async
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);
@@ -81,6 +108,12 @@ test("renders, searches and switches sheets in a project-authored ODS", async ({
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 ({
+2 -2
View File
@@ -24,10 +24,10 @@ test("publishes valid relocatable metadata", async ({ request }) => {
await expect(manifestResponse.json()).resolves.toMatchObject({
schemaVersion: 1,
id: "de.add-ideas.office-tools",
version: "0.1.0",
version: "0.2.0",
entry: "./",
icon: "./favicon.svg",
privacy: { processing: "local", fileUploads: false, telemetry: false },
privacy: { processing: "local", fileUploads: true, telemetry: false },
});
const webManifest = await request.get(`${entry}manifest.webmanifest`);
+2 -1
View File
@@ -139,8 +139,9 @@ test("fails closed with an inline error for a malformed OOXML package", async ({
const alert = page.getByRole("alert");
await expect(alert).toBeVisible({ timeout: 90_000 });
await expect(alert).not.toBeEmpty();
await expect(page.locator(".file-heading")).toHaveCount(0);
await expect(
page.locator(".file-heading__state .state-dot--error"),
page.getByRole("heading", { name: "Choose or drop a file" }),
).toBeVisible();
});
+18
View File
@@ -0,0 +1,18 @@
import { expect, test } from "@playwright/test";
test("keeps the primary workspace inside a narrow viewport", async ({
page,
}) => {
await page.goto("/deep/nested/office/");
await expect(page.locator("main").first()).toBeVisible();
await expect(
page.locator("main .loading, main .workbench-loading"),
).toHaveCount(0);
const widths = await page.evaluate(() => ({
content: document.documentElement.scrollWidth,
viewport: document.documentElement.clientWidth,
}));
expect(widths.viewport).toBeLessThanOrEqual(430);
expect(widths.content).toBeLessThanOrEqual(widths.viewport + 1);
});