Skip to content

Attach to the HTML report

Playwright’s HTML reporter renders attachments inline next to the test step they’re attached from. Annotated screenshots land there with a testInfo.attach() call.

import {
test,
expect,
rectForBoundingBox,
} from "@ingcreators/annot-playwright";
test("highlight failing locator", async ({ page, annotator }, testInfo) => {
await page.goto("https://example.com");
const cta = page.getByRole("link", { name: "Get started" });
const box = (await cta.boundingBox())!;
const annotated = await annotator.annotateScreenshot(page, {
annotationsSvg: rectForBoundingBox(box, { stroke: "#7c9cff" }),
});
await testInfo.attach("get-started-cta.png", {
body: annotated,
contentType: "image/png",
});
await expect(cta).toBeVisible();
});

Open the HTML report (npx playwright show-report) and click the test. The attached PNG appears inline under the step that produced it, with the filename you passed as the first argument.

testInfo.attach() accepts as many calls as you want — one per step is typical:

await page.goto("/login");
await testInfo.attach("01-login.png", { body: await page.screenshot() });
// ...do something flaky...
const annotated = await annotator.annotateScreenshot(page, {
annotationsSvg: rectForBoundingBox(submitBox, { stroke: "#ff5252" }),
});
await testInfo.attach("02-after-submit.png", { body: annotated });

The trace: "on" Playwright setting also records attachments — your annotated PNG is visible alongside the network log, console log, and DOM snapshots when you replay the trace.