test(imaging): broaden coverage across contract, transcode, routing and pixels
CI / check (push) Successful in 32s
CI / tests-imaging-browsers (push) Successful in 1m33s
CI / tests-integration (push) Successful in 2m5s
CI / tests-unit (push) Successful in 2m7s
CI / tests-ui (push) Successful in 2m47s
CI / preflight (push) Skipped
CI / deploy (push) Successful in 3m44s

Environment-independent contract tests (cache headers + source, CORS, OPTIONS
preflight, negative figure/badge tables, concurrency burst) run in both the
deploy gate and the cross-browser job.

CMS-only /imaging assertions (webp/avif transcode, animated-APNG passthrough,
s-maxage edge caching) live in cms-imaging.spec.ts and are skipped behind the
edge proxy; the public topology has its own public-routing.spec.ts smoke that
fails if the edge ever stops fronting the imager or starts shadowing the CMS
endpoints. A committed per-engine visual baseline pins the static render.

The cross-browser imaging job is now blocking (IMAGING_EDGE=1), so avatar
imaging on chromium/firefox/webkit is a required signal.
This commit is contained in:
openhands committed 2026-10-14 21:19:18 +02:00
1 parent 3fa643828d
commit 640e5a5dd0
12 files changed
+339 -44

No files matched your search

+19 -12
View File
@@ -1,15 +1,5 @@
import { expect, test } from "@playwright/test";
// Same production figure as the endpoint spec: includes the trailing `.0`
// segment the client sends and the renderer ignores.
const FIGURE =
"hr-11782-40-40.hd-180-7-14.ch-11592-66.lg-10726-79-1408.sh-11764-1408.ha-11958-70-1408.wa-2007-0.0";
const AVATAR_PATH = `/api/imaging/avatar?${new URLSearchParams({
figure: FIGURE,
img_format: "apng",
effect: "14",
})}`;
import { avatarPath } from "./imaging-target";
/**
* Cross-browser check that a real browser (chromium/firefox/webkit) can decode
@@ -25,8 +15,11 @@ const AVATAR_PATH = `/api/imaging/avatar?${new URLSearchParams({
*
* Run across engines via `pnpm test:imaging` (playwright.imaging.config.ts).
*/
const ANIMATED = avatarPath({ img_format: "apng", effect: "14" });
const STATIC = avatarPath({ img_format: "png" });
test("the avatar decodes and animates in the browser", async ({ page }) => {
const response = await page.goto(AVATAR_PATH);
const response = await page.goto(ANIMATED);
expect(response?.status()).toBe(200);
const image = page.locator("img");
@@ -48,3 +41,17 @@ test("the avatar decodes and animates in the browser", async ({ page }) => {
}
expect(frames.size).toBeGreaterThan(1);
});
test("the static render matches its committed visual baseline", async ({
page,
}) => {
// Pins the exact pixels of a non-animated render so a renderer/asset drift
// (wrong palette, missing part, changed sizing) is caught even when the
// image still decodes. Baselines are per engine and committed under
// e2e/imaging/__screenshots__/.
const response = await page.goto(STATIC);
expect(response?.status()).toBe(200);
await expect(page.locator("img")).toHaveScreenshot("static-avatar.png", {
animations: "disabled",
});
});