@ingcreators/annot-playwright 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +42 -0
- package/README.md +9 -8
- package/dist/fixture.d.ts +26 -9
- package/dist/helpers.d.ts +1 -43
- package/dist/index.d.ts +4 -2
- package/dist/index.js +38 -53
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,47 @@
|
|
|
1
1
|
# @ingcreators/annot-playwright
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 35e3ad7: `annotateScreenshot()` now accepts the annotation DSL added in `@ingcreators/annot-annotator@0.2.0`:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
import {
|
|
11
|
+
test,
|
|
12
|
+
expect,
|
|
13
|
+
type BboxAnnotation,
|
|
14
|
+
} from "@ingcreators/annot-playwright";
|
|
15
|
+
|
|
16
|
+
test("login form", async ({ page, annotator }, testInfo) => {
|
|
17
|
+
const submit = page.getByRole("button", { name: "Sign in" });
|
|
18
|
+
const box = (await submit.boundingBox())!;
|
|
19
|
+
const annotated = await annotator.annotateScreenshot(page, {
|
|
20
|
+
annotations: [
|
|
21
|
+
{ type: "rect", bbox: box, intent: "error" },
|
|
22
|
+
{
|
|
23
|
+
type: "callout",
|
|
24
|
+
at: { x: 50, y: 50 },
|
|
25
|
+
targetBbox: box,
|
|
26
|
+
content: "Failing",
|
|
27
|
+
},
|
|
28
|
+
] satisfies BboxAnnotation[],
|
|
29
|
+
});
|
|
30
|
+
await testInfo.attach("failure.png", { body: annotated });
|
|
31
|
+
});
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The existing `annotationsSvg: string` shape still works; the new `annotations: BboxAnnotation[]` is an additive overload. `intent` shorthand (`"info"` / `"warning"` / `"error"` / `"success"` / `"neutral"`) maps to the Annot design system's semantic colours so callers no longer think in raw hex values, and `callout` composes the rect + arrow + caption in a single entry.
|
|
35
|
+
|
|
36
|
+
`rectForBoundingBox` / `arrowBetween` / `textAt` are now thin re-exports from `@ingcreators/annot-annotator` rather than local helpers. Cosmetic delta: `arrowBetween`'s marker id prefix changed from `annot-pw-arrow-N` to `annot-arrow-N`; snapshot-on-SVG tests should expect this.
|
|
37
|
+
|
|
38
|
+
Also re-exports the bbox-flavour DSL types (`BboxAnnotation`, `BBox`, `Point`, `Intent`, `AnnotationStyle`, `BboxRedactRegion`, `RedactStyle`, …) from `@ingcreators/annot-annotator` so callers keep a single import line.
|
|
39
|
+
|
|
40
|
+
### Patch Changes
|
|
41
|
+
|
|
42
|
+
- Updated dependencies [92378f9]
|
|
43
|
+
- @ingcreators/annot-annotator@0.2.0
|
|
44
|
+
|
|
3
45
|
## 0.1.0
|
|
4
46
|
|
|
5
47
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
# `@ingcreators/annot-playwright`
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@ingcreators/annot-playwright)
|
|
4
|
+
[](https://github.com/ingcreators/annot/blob/main/LICENSE)
|
|
5
|
+
|
|
6
|
+
Playwright fixture for [`@ingcreators/annot-annotator`](https://www.npmjs.com/package/@ingcreators/annot-annotator).
|
|
4
7
|
Emit annotated screenshots from test failures without leaving the
|
|
5
8
|
test file.
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
> installable in Phase 3 of the headless-annotator track (gated on
|
|
9
|
-
> Changesets). The Phase 1 annotator it depends on is also
|
|
10
|
-
> workspace-only until then.
|
|
11
|
-
|
|
12
|
-
## Install (post-publish)
|
|
10
|
+
## Install
|
|
13
11
|
|
|
14
12
|
```sh
|
|
15
13
|
pnpm add -D @playwright/test @ingcreators/annot-playwright
|
|
14
|
+
# or
|
|
15
|
+
npm install --save-dev @playwright/test @ingcreators/annot-playwright
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
`@playwright/test` is a peer dependency — bring your own pinned
|
|
19
|
+
version.
|
|
19
20
|
|
|
20
21
|
## Usage
|
|
21
22
|
|
package/dist/fixture.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Annotator } from '@ingcreators/annot-annotator';
|
|
1
|
+
import { Annotator, BboxAnnotation } from '@ingcreators/annot-annotator';
|
|
2
2
|
/**
|
|
3
3
|
* Minimal Playwright `Page` surface the fixture relies on. The full
|
|
4
4
|
* `@playwright/test` `Page` type is much wider, but importing it
|
|
@@ -22,12 +22,29 @@ export interface PageLike {
|
|
|
22
22
|
* Playwright `Page`, captures a screenshot, and overlays the
|
|
23
23
|
* caller-supplied annotation SVG.
|
|
24
24
|
*/
|
|
25
|
+
/**
|
|
26
|
+
* Annotation input for `annotateScreenshot`. Either flavour works:
|
|
27
|
+
*
|
|
28
|
+
* - `annotationsSvg: string` — raw SVG fragment, useful for the
|
|
29
|
+
* `rectForBoundingBox` / `arrowBetween` / `textAt` primitives
|
|
30
|
+
* and any custom SVG you compose yourself.
|
|
31
|
+
* - `annotations: BboxAnnotation[]` — the DSL flavour added in
|
|
32
|
+
* 0.2.0. Each entry is a typed shape (`rect` / `circle` /
|
|
33
|
+
* `arrow` / `text` / `callout` / `raw`) with an optional
|
|
34
|
+
* `intent` shorthand mapping to design-system colours.
|
|
35
|
+
*/
|
|
36
|
+
export type AnnotateScreenshotOptions = {
|
|
37
|
+
annotationsSvg: string;
|
|
38
|
+
annotations?: never;
|
|
39
|
+
fullPage?: boolean;
|
|
40
|
+
} | {
|
|
41
|
+
annotations: readonly BboxAnnotation[];
|
|
42
|
+
annotationsSvg?: never;
|
|
43
|
+
fullPage?: boolean;
|
|
44
|
+
};
|
|
25
45
|
export interface PlaywrightAnnotator {
|
|
26
46
|
raw: Annotator;
|
|
27
|
-
annotateScreenshot(page: PageLike, opts:
|
|
28
|
-
annotationsSvg: string;
|
|
29
|
-
fullPage?: boolean;
|
|
30
|
-
}): Promise<Uint8Array>;
|
|
47
|
+
annotateScreenshot(page: PageLike, opts: AnnotateScreenshotOptions): Promise<Uint8Array>;
|
|
31
48
|
}
|
|
32
49
|
/**
|
|
33
50
|
* `test = base.extend({ annotator })` — drop-in replacement for
|
|
@@ -42,8 +59,8 @@ export declare const test: import('@playwright/test').TestType<import('@playwrig
|
|
|
42
59
|
* — exported so callers who build their own Playwright fixture
|
|
43
60
|
* (e.g. with extra fixtures composed on top) can still use the
|
|
44
61
|
* one-call screenshot+annotate flow.
|
|
62
|
+
*
|
|
63
|
+
* Accepts either an `annotationsSvg: string` (raw SVG path) or an
|
|
64
|
+
* `annotations: BboxAnnotation[]` (DSL path added in 0.2.0).
|
|
45
65
|
*/
|
|
46
|
-
export declare function annotateScreenshot(annotator: Annotator, page: PageLike, opts:
|
|
47
|
-
annotationsSvg: string;
|
|
48
|
-
fullPage?: boolean;
|
|
49
|
-
}): Promise<Uint8Array>;
|
|
66
|
+
export declare function annotateScreenshot(annotator: Annotator, page: PageLike, opts: AnnotateScreenshotOptions): Promise<Uint8Array>;
|
package/dist/helpers.d.ts
CHANGED
|
@@ -1,43 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
x: number;
|
|
3
|
-
y: number;
|
|
4
|
-
width: number;
|
|
5
|
-
height: number;
|
|
6
|
-
}
|
|
7
|
-
export interface Point {
|
|
8
|
-
x: number;
|
|
9
|
-
y: number;
|
|
10
|
-
}
|
|
11
|
-
export interface RectOptions {
|
|
12
|
-
stroke?: string;
|
|
13
|
-
strokeWidth?: number;
|
|
14
|
-
fill?: string;
|
|
15
|
-
}
|
|
16
|
-
export interface ArrowOptions {
|
|
17
|
-
color?: string;
|
|
18
|
-
strokeWidth?: number;
|
|
19
|
-
}
|
|
20
|
-
export interface TextOptions {
|
|
21
|
-
color?: string;
|
|
22
|
-
fontSize?: number;
|
|
23
|
-
anchor?: "start" | "middle" | "end";
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Outline a bounding box (e.g. from `locator.boundingBox()`) with
|
|
27
|
-
* an SVG `<rect>`. Defaults: red stroke, 2px width, no fill.
|
|
28
|
-
*/
|
|
29
|
-
export declare function rectForBoundingBox(bbox: BoundingBox, opts?: RectOptions): string;
|
|
30
|
-
/**
|
|
31
|
-
* Draw an arrow from `from` to `to`. Inlines a unique-id `<marker>`
|
|
32
|
-
* definition so the helper is self-contained — call it twice and
|
|
33
|
-
* each call produces a distinct arrowhead marker (no collision
|
|
34
|
-
* across uses on the same SVG).
|
|
35
|
-
*
|
|
36
|
-
* Defaults: red color, 2px stroke.
|
|
37
|
-
*/
|
|
38
|
-
export declare function arrowBetween(from: Point, to: Point, opts?: ArrowOptions): string;
|
|
39
|
-
/**
|
|
40
|
-
* Drop a text label at a position. Defaults: red, 14px,
|
|
41
|
-
* start-anchored.
|
|
42
|
-
*/
|
|
43
|
-
export declare function textAt(at: Point, content: string, opts?: TextOptions): string;
|
|
1
|
+
export { type ArrowOptions, arrowBetween, type BoundingBox, type RectOptions, rectForBoundingBox, type TextOptions, textAt, } from '@ingcreators/annot-annotator';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export type { AnnotationStyle, BBox, BboxAnnotation, BboxArrowAnnotation, BboxCalloutAnnotation, BboxCircleAnnotation, BboxRectAnnotation, BboxRedactRegion, BboxTextAnnotation, Intent, Point, RawAnnotation, RedactStyle, } from '@ingcreators/annot-annotator';
|
|
2
|
+
export { bboxAnnotationsToSvg } from '@ingcreators/annot-annotator';
|
|
1
3
|
export { expect } from '@playwright/test';
|
|
2
|
-
export { annotateScreenshot, type PageLike, type PlaywrightAnnotator, test, } from './fixture.js';
|
|
3
|
-
export { type ArrowOptions, arrowBetween, type BoundingBox, type
|
|
4
|
+
export { type AnnotateScreenshotOptions, annotateScreenshot, type PageLike, type PlaywrightAnnotator, test, } from './fixture.js';
|
|
5
|
+
export { type ArrowOptions, arrowBetween, type BoundingBox, type RectOptions, rectForBoundingBox, type TextOptions, textAt, } from './helpers.js';
|
package/dist/index.js
CHANGED
|
@@ -1,53 +1,38 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
let r = n.color ?? "red", i = n.fontSize ?? 14, a = n.anchor ?? "start";
|
|
40
|
-
return `<text x="${e.x}" y="${e.y}" fill="${d(r)}" font-size="${i}" text-anchor="${a}">` + f(t) + "</text>";
|
|
41
|
-
}
|
|
42
|
-
var l = 0;
|
|
43
|
-
function u() {
|
|
44
|
-
return l = l + 1 | 0, l;
|
|
45
|
-
}
|
|
46
|
-
function d(e) {
|
|
47
|
-
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
48
|
-
}
|
|
49
|
-
function f(e) {
|
|
50
|
-
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
51
|
-
}
|
|
52
|
-
//#endregion
|
|
53
|
-
export { i as annotateScreenshot, s as arrowBetween, e as expect, o as rectForBoundingBox, r as test, c as textAt };
|
|
1
|
+
import { createAnnotator as c, bboxAnnotationsToSvg as g } from "@ingcreators/annot-annotator";
|
|
2
|
+
import { arrowBetween as m, bboxAnnotationsToSvg as S, rectForBoundingBox as v, textAt as P } from "@ingcreators/annot-annotator";
|
|
3
|
+
import { test as f } from "@playwright/test";
|
|
4
|
+
import { expect as A } from "@playwright/test";
|
|
5
|
+
const u = f.extend({
|
|
6
|
+
// biome-ignore lint/correctness/noEmptyPattern: Playwright fixture signature requires the empty destructure.
|
|
7
|
+
annotator: async ({}, n) => {
|
|
8
|
+
const o = c();
|
|
9
|
+
await n({
|
|
10
|
+
raw: o,
|
|
11
|
+
annotateScreenshot: (t, e) => h(o, t, e)
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
});
|
|
15
|
+
async function h(n, o, t) {
|
|
16
|
+
const e = await o.screenshot({ fullPage: t.fullPage }), { width: a, height: r } = w(e), i = `data:image/png;base64,${e.toString("base64")}`, s = "annotations" in t && t.annotations !== void 0 ? g(t.annotations) : t.annotationsSvg ?? "";
|
|
17
|
+
return n.toPng({
|
|
18
|
+
originalDataUrl: i,
|
|
19
|
+
annotationsSvg: s,
|
|
20
|
+
width: a,
|
|
21
|
+
height: r
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function w(n) {
|
|
25
|
+
if (n.length < 24)
|
|
26
|
+
throw new Error("PNG too short to contain IHDR chunk");
|
|
27
|
+
const o = new DataView(n.buffer, n.byteOffset, n.byteLength), t = o.getUint32(16, !1), e = o.getUint32(20, !1);
|
|
28
|
+
return { width: t, height: e };
|
|
29
|
+
}
|
|
30
|
+
export {
|
|
31
|
+
h as annotateScreenshot,
|
|
32
|
+
m as arrowBetween,
|
|
33
|
+
S as bboxAnnotationsToSvg,
|
|
34
|
+
A as expect,
|
|
35
|
+
v as rectForBoundingBox,
|
|
36
|
+
u as test,
|
|
37
|
+
P as textAt
|
|
38
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ingcreators/annot-playwright",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Playwright fixture for annotated screenshots — emit annotated PNGs from failing tests without leaving the test file. Pairs `test.extend({ annotator })` with the headless renderer from @ingcreators/annot-annotator.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "ingcreators",
|
|
@@ -44,11 +44,11 @@
|
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@playwright/test": "^1.50.0",
|
|
46
46
|
"typescript": "^6.0.3",
|
|
47
|
-
"vite": "^
|
|
47
|
+
"vite": "^6.4.2",
|
|
48
48
|
"vite-plugin-dts": "^5.0.0"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@ingcreators/annot-annotator": "0.
|
|
51
|
+
"@ingcreators/annot-annotator": "0.2.0"
|
|
52
52
|
},
|
|
53
53
|
"peerDependencies": {
|
|
54
54
|
"@playwright/test": "^1.40.0"
|