Files
zemion 6c763fcb5a
Verify / verify (push) Canceled after 0s
Release Helper Tools 0.2.0
2026-09-02 01:01:56 +02:00

132 lines
4.7 KiB
TypeScript

import { expect, test, type Page } from "@playwright/test";
const APP_ORIGIN = "http://127.0.0.1:4173";
async function keepNetworkLocal(page: Page): Promise<string[]> {
const externalRequests: string[] = [];
await page.route("**/*", async (route) => {
const requestUrl = new URL(route.request().url());
if (requestUrl.origin !== APP_ORIGIN) {
externalRequests.push(requestUrl.href);
await route.abort();
return;
}
await route.continue();
});
return externalRequests;
}
function recordRuntimeErrors(page: Page): string[] {
const errors: string[] = [];
page.on("pageerror", (error) => errors.push(error.message));
page.on("console", (message) => {
if (message.type() === "error") errors.push(message.text());
});
return errors;
}
test("encodes text and navigates the local workspaces", async ({ page }) => {
const runtimeErrors = recordRuntimeErrors(page);
const externalRequests = await keepNetworkLocal(page);
await page.goto("/deep/nested/helpers/");
await expect(
page.getByRole("heading", { name: "Useful values, without a round trip" }),
).toBeVisible();
await page.getByLabel("Text", { exact: true }).fill("local ✓");
const encodeCard = page
.getByRole("heading", { name: "Encode text" })
.locator("..");
await expect(encodeCard).toContainText("bG9jYWwg4pyT");
await page.getByLabel("URL component", { exact: true }).fill("a b/✓");
await expect(page.getByText("a%20b%2F%E2%9C%93")).toBeVisible();
await page.getByRole("tab", { name: /^Text & Unicode/u }).click();
await expect(page).toHaveURL(/#text$/u);
await expect(
page.getByRole("heading", { name: "Text & Unicode" }),
).toBeVisible();
expect(externalRequests).toEqual([]);
expect(runtimeErrors).toEqual([]);
});
test("calculates network, structured data and seeded values", async ({
page,
}) => {
const runtimeErrors = recordRuntimeErrors(page);
const externalRequests = await keepNetworkLocal(page);
await page.goto("/deep/nested/helpers/#network");
await expect(page.getByText("2001:db8::/64")).toBeVisible();
await page.getByLabel("IPv4 or IPv6 CIDR").fill("192.0.2.99/24");
await page.getByLabel("Address to test").fill("192.0.3.1");
await expect(page.getByText("192.0.2.0/24")).toBeVisible();
await expect(page.getByText("No", { exact: true })).toBeVisible();
await page.getByRole("tab", { name: /^Structured/u }).click();
await page.getByLabel("JSON input").fill('{"z":1,"a":2}');
await expect(page.getByText(/"a": 2/u)).toBeVisible();
await page.getByLabel("CSV input").fill('name,note\nalpha,"a,b"');
await expect(
page.getByText("Rows", { exact: true }).locator(".."),
).toContainText("2");
await page.getByRole("tab", { name: /^Random/u }).click();
await page.getByLabel("Byte count (maximum 4096 here)").fill("8");
const generate = page.getByRole("button", { name: "Generate seeded bytes" });
await generate.click();
const output = page.locator("output").filter({ hasText: /^[0-9a-f]{16}$/u });
const first = await output.textContent();
await generate.click();
await expect(output).toHaveText(first ?? "");
expect(externalRequests).toEqual([]);
expect(runtimeErrors).toEqual([]);
});
test("produces browser digests without clearing the previous result", async ({
page,
}) => {
const runtimeErrors = recordRuntimeErrors(page);
const externalRequests = await keepNetworkLocal(page);
await page.goto("/deep/nested/helpers/#checksums");
await expect(page.getByText("cbf43926")).toBeVisible();
await expect(
page.getByText(
"15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225",
),
).toBeVisible();
await page.getByLabel("UTF-8 input").fill("abc");
await expect(
page.getByText(
"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad",
),
).toBeVisible();
expect(externalRequests).toEqual([]);
expect(runtimeErrors).toEqual([]);
});
test("serves a relocatable production artifact with hardened headers", async ({
request,
}) => {
const index = await request.get("/deep/nested/helpers/");
expect(index.ok()).toBe(true);
expect(index.headers()["content-security-policy"]).toContain(
"default-src 'self'",
);
expect(index.headers()["permissions-policy"]).toContain("geolocation=()");
expect(index.headers()["x-content-type-options"]).toBe("nosniff");
expect(await index.text()).not.toMatch(/\b(?:src|href)=["']\//u);
const manifest = await request.get("/deep/nested/helpers/toolbox-app.json");
expect(manifest.headers()["content-type"]).toContain("application/json");
await expect(manifest.json()).resolves.toMatchObject({
id: "de.add-ideas.helper-tools",
version: "0.2.0",
entry: "./",
icon: "./favicon.svg",
});
});