Files
easy-png-tools2/web/e2e/pipeline.spec.ts
T

177 lines
5.2 KiB
TypeScript

import { readFile } from "node:fs/promises";
import { unzipSync } from "fflate";
import { expect, test } from "playwright/test";
import {
corruptPng,
landscapePng,
largePng,
onePixelPng,
opaquePng,
} from "./helpers/fixtures";
import {
downloadResult,
downloadResultFile,
errorAlert,
expectNoErrorAlert,
expectNoErrors,
openTool,
rangeInput,
resultImage,
sourceImage,
trackErrors,
uploadImage,
useEnglish,
} from "./helpers/page";
test("resize-png uses the source dimensions by default", async ({ page }) => {
const sink = trackErrors(page);
await openTool(page, "resize-png");
await uploadImage(page, opaquePng);
await expect(page.getByRole("spinbutton", { name: "Width" })).toHaveValue(
"64",
);
await expect(page.getByRole("spinbutton", { name: "Height" })).toHaveValue(
"48",
);
await expect(resultImage(page)).toBeVisible();
await expectNoErrorAlert(page);
expectNoErrors(sink);
});
test("crop-png starts with the full source area", async ({ page }) => {
const sink = trackErrors(page);
await openTool(page, "crop-png");
await uploadImage(page, opaquePng);
await expect(page.getByRole("spinbutton", { name: "Width" })).toHaveValue(
"64",
);
await expect(page.getByRole("spinbutton", { name: "Height" })).toHaveValue(
"48",
);
await expect(resultImage(page)).toBeVisible();
await expectNoErrorAlert(page);
expectNoErrors(sink);
});
test("flip-png: full flow - upload, result, download", async ({ page }) => {
const sink = trackErrors(page);
await openTool(page, "flip-png");
await uploadImage(page, landscapePng);
await expect(resultImage(page)).toBeVisible();
expect(await downloadResult(page)).toBe("flip-png.png");
await expectNoErrorAlert(page);
expectNoErrors(sink);
});
test("convert-png-to-jpg: produces a downloadable jpg", async ({ page }) => {
const sink = trackErrors(page);
await openTool(page, "convert-png-to-jpg");
await uploadImage(page, opaquePng);
await expect(resultImage(page)).toBeVisible();
expect(await downloadResult(page)).toBe("convert-png-to-jpg.jpg");
await expectNoErrorAlert(page);
expectNoErrors(sink);
});
test("reset restores defaults and re-runs with the source", async ({
page,
}) => {
const sink = trackErrors(page);
await openTool(page, "blur-png");
await uploadImage(page, opaquePng);
await expect(resultImage(page)).toBeVisible();
const radius = rangeInput(page, /radius/i);
await radius.fill("20");
await expect(radius).toHaveValue("20");
await page.getByRole("button", { name: "Reset" }).click();
await expect(radius).toHaveValue("4");
await expect(sourceImage(page)).toBeVisible();
await expect(resultImage(page)).toBeVisible();
await expectNoErrorAlert(page);
expectNoErrors(sink);
});
test("split-into-parts-png downloads a zip with named PNG parts", async ({
page,
}) => {
const sink = trackErrors(page);
await openTool(page, "split-into-parts-png");
await uploadImage(page, landscapePng);
await rangeInput(page, "Columns").fill("3");
await rangeInput(page, "Rows").fill("2");
await expect(page.getByText("part-1-3.png")).toBeVisible();
const download = await downloadResultFile(page);
expect(download.suggestedFilename()).toBe("split-into-parts-png.zip");
const path = await download.path();
if (!path) throw new Error("download path is unavailable");
const entries = unzipSync(new Uint8Array(await readFile(path)));
expect(Object.keys(entries)).toEqual([
"part-1-1.png",
"part-1-2.png",
"part-1-3.png",
"part-2-1.png",
"part-2-2.png",
"part-2-3.png",
]);
for (const bytes of Object.values(entries)) {
expect(Array.from(bytes.subarray(0, 8))).toEqual([
137, 80, 78, 71, 13, 10, 26, 10,
]);
}
await expectNoErrorAlert(page);
expectNoErrors(sink);
});
test("blur: changing slider updates result image", async ({ page }) => {
await openTool(page, "blur-png");
await uploadImage(page, opaquePng);
await expect(resultImage(page)).toBeVisible();
const firstSource = await resultImage(page).getAttribute("src");
await rangeInput(page, /radius/i).fill("20");
await expect(resultImage(page)).not.toHaveAttribute("src", firstSource ?? "");
});
test("runs without Web Worker (fallback)", async ({ browser }) => {
const context = await browser.newContext();
try {
await context.addInitScript(() => {
Object.defineProperty(window, "Worker", {
value: undefined,
configurable: true,
});
});
const page = await context.newPage();
await useEnglish(page);
const sink = trackErrors(page);
await openTool(page, "flip-png");
await uploadImage(page, landscapePng);
await expect(resultImage(page)).toBeVisible();
await expectNoErrorAlert(page);
expectNoErrors(sink);
} finally {
await context.close();
}
});
test("invalid file upload shows error, no crash", async ({ page }) => {
const sink = trackErrors(page);
await openTool(page, "flip-png");
await uploadImage(page, corruptPng);
await expect(errorAlert(page)).toBeVisible();
await expect(resultImage(page)).toHaveCount(0);
expectNoErrors(sink);
});
for (const fixture of [onePixelPng, largePng]) {
test(`handles ${fixture.name} correctly`, async ({ page }) => {
const sink = trackErrors(page);
await openTool(page, "flip-png");
await uploadImage(page, fixture);
await expect(resultImage(page)).toBeVisible();
expectNoErrors(sink);
});
}