@piwitests/reporter 0.62.0 → 0.64.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.
@@ -0,0 +1,87 @@
1
+ /** Arguments for `probeElementAttrs` — the role maps mirror the single source of truth in `@piwitests/core`. */
2
+ interface ProbeArg {
3
+ /** Attribute whitelist to read off the element (the shared `CAPTURED_ATTRIBUTES`). */
4
+ keep: string[];
5
+ /** Required when `includeStructural` is true — role resolution needs the tag/input-type role maps. */
6
+ tagRoles?: Record<string, string>;
7
+ inputRoles?: Record<string, string>;
8
+ /** CSS selector matching every element role resolution can reach (also structural-only). */
9
+ roleSources?: string;
10
+ /** Compute `rolePosition` and ancestor-anchor candidates. The live picker always wants these; the snapshot picker never does (no anchors step there). */
11
+ includeStructural: boolean;
12
+ /**
13
+ * Count how many elements each candidate matches: `selectorCounts`,
14
+ * `rolePosition` and every anchor's counts, each a walk of the document or
15
+ * of an ancestor's subtree. True unless set: a caller that counts with an
16
+ * index of its own turns it off, and the anchors then carry what identifies
17
+ * them and no count, whatever the size of the page.
18
+ */
19
+ countMatches?: boolean;
20
+ /**
21
+ * The attribute `getByTestId` reads in the project (Playwright's
22
+ * `testIdAttribute`); `data-testid` when null or absent. It is read with
23
+ * `keep`, counted for `selectorCounts.testId`, read off each ancestor for its
24
+ * `testId` and `testIdCount`, and never taken as an ancestor's `dataAttr`;
25
+ * any other `data-*`, `data-testid` included, is an ordinary one.
26
+ */
27
+ testIdAttribute?: string | null;
28
+ }
29
+ /** Element shape the in-page probe returns — structural view of what the picker overlays need. */
30
+ interface ProbedAttrs {
31
+ tagName: string;
32
+ attributes: Record<string, string | null>;
33
+ textContent: string;
34
+ center: {
35
+ x: number;
36
+ y: number;
37
+ };
38
+ hasLabel: boolean;
39
+ /** Text of the elements `aria-labelledby` points at, else of the first associated `<label>`. */
40
+ labelText: string | null;
41
+ selectorCounts: {
42
+ testId?: number;
43
+ id?: number;
44
+ name?: number;
45
+ classes?: Record<string, number>;
46
+ /** How many elements share this element's role *and* exact accessible name (`getByRole(role, { name })` without `exact` also matches names that contain it). */
47
+ roleName?: number;
48
+ /** Of the `roleName` matches, how many are laid out (a box, or an `offsetParent`) — what `getByRole(role, { name }).visible()` would match. */
49
+ visibleRoleName?: number;
50
+ /** How many elements `getByText` would match on this element's text, counted no further than 2 — every consumer only asks whether that is exactly one. Undefined when the element has no text, or the subtree was too large to scan. */
51
+ text?: number;
52
+ /** How many elements share this element's `placeholder` — what `getByPlaceholder` would really match. */
53
+ placeholder?: number;
54
+ /** How many elements share this element's `alt` — what `getByAltText` would really match. */
55
+ alt?: number;
56
+ /** How many elements share this element's `title` — what `getByTitle` would really match. */
57
+ title?: number;
58
+ };
59
+ rolePosition?: {
60
+ role: string;
61
+ count: number;
62
+ index: number;
63
+ levelCount?: number;
64
+ } | null;
65
+ ancestors?: Array<{
66
+ tag: string;
67
+ depth: number;
68
+ testId: string | null;
69
+ id: string | null;
70
+ role: string | null;
71
+ ariaLabel: string | null;
72
+ scopedRoleCount?: number;
73
+ scopedTextCount?: number;
74
+ testIdCount?: number;
75
+ idCount?: number;
76
+ roleCount?: number;
77
+ dataAttr?: {
78
+ name: string;
79
+ value: string;
80
+ };
81
+ dataAttrCount?: number;
82
+ filterText?: string;
83
+ filterRoleCount?: number;
84
+ }>;
85
+ }
86
+
87
+ export type { ProbeArg as P, ProbedAttrs as a };
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Wire leaf shapes — the small, identical building blocks of the JSON contract
3
+ * exchanged between the reporter and the server. The single source of truth
4
+ * shared by the app (`#shared/types`) and the reporter (`types/wire.ts`).
5
+ *
6
+ * The per-case *payloads* are intentionally NOT here: the reporter produces a
7
+ * loose `WireTestCase` superset while the server receives the stricter
8
+ * `TestCasePayload` / `StreamEventPayload`. Those live on each side and are kept
9
+ * field-compatible by `apps/application/tests/unit/wire-shared-drift.test.ts`.
10
+ */
11
+
12
+ /**
13
+ * One locator call and the page it ran on, as the capture fixtures record it
14
+ * in the `piwi-locator-pages` attachment: a test's calls, deduped by call
15
+ * site, chain and page. The dashboard joins it to the locator index, so a use
16
+ * of a chain knows the pages it was made on.
17
+ */
18
+ interface LocatorPageUse {
19
+ /** `file:line:col` of the call, as a step location reports it (absolute; the server makes it project-relative). */
20
+ location: string;
21
+ /** The chain as Playwright prints it (`Locator.toString()`). */
22
+ locator: string;
23
+ /** The page's origin (`https://shop.test`), to tell the application's pages from third-party ones. */
24
+ origin: string;
25
+ /** The page key: the path with ids and tokens collapsed, no query, no hash (`/orders/:id`). */
26
+ page: string;
27
+ /** No locator interaction happened on the page since it was navigated to: the element was there as it loaded. */
28
+ arrival: boolean;
29
+ }
30
+ /** What a process is for the run, from its command line. */
31
+ type ProcessRole = 'runner' | 'worker' | 'browser' | 'renderer' | 'gpu' | 'utility' | 'ffmpeg' | 'webServer' | 'other';
32
+ /**
33
+ * Name of the PNG the capture fixtures attach to a failed test: the page the
34
+ * test last acted on. The reporter uploads it with the execution's files, and
35
+ * the dashboard shows it as the page at the failure.
36
+ */
37
+ declare const FAILURE_SCREENSHOT_ATTACHMENT = "piwi-failure-screenshot";
38
+ /** What the processes of one role used during a test. */
39
+ interface RoleCost {
40
+ cpuMs: number;
41
+ /** Time runnable but waiting for a CPU. */
42
+ runWaitMs: number | null;
43
+ /** The largest process of the role during the test (its peak RSS). */
44
+ peakRssMb: number | null;
45
+ processes: number;
46
+ }
47
+
48
+ export { FAILURE_SCREENSHOT_ATTACHMENT as F, type LocatorPageUse as L, type ProcessRole as P, type RoleCost as R };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@piwitests/reporter",
3
- "version": "0.62.0",
3
+ "version": "0.64.0",
4
4
  "description": "Playwright reporter that streams results, traces and HTML reports to a Piwi Dashboard instance",
5
5
  "url": "https://github.com/PiwiTests/piwi",
6
6
  "homepage": "https://piwitests.dev",
@@ -66,7 +66,7 @@
66
66
  "node": ">=20"
67
67
  },
68
68
  "peerDependencies": {
69
- "@playwright/test": "^1.64.1"
69
+ "@playwright/test": ">=1.59.0 <2"
70
70
  },
71
71
  "dependencies": {
72
72
  "form-data": "^4.0.0"
@@ -87,10 +87,12 @@ view, and work from what it shows plus the repo.
87
87
 
88
88
  8. **Report back to Piwi.** Tell Piwi what you decided about the gap with
89
89
  `triage_gap` (Maintainer role or above on the project): `verb: "accept"` for the gap you
90
- wrote the test for, `covered-by` with the covering test's id when a test you
91
- found already covers it, or `dismiss` with the reason (`not-worth-testing`,
92
- `covered-elsewhere`, `wrong`) when the evidence did not hold. Each verdict counts toward the precision of the
93
- detector that raised the gap, so a detector that keeps being wrong is muted.
90
+ wrote the test for, `covered-by` with the test's id once a test written for the gap
91
+ has run, or `dismiss` when the gap needed no new test: `covered-elsewhere` with the id
92
+ of a test that already covered it, `not-worth-testing`, or `wrong` when the evidence did
93
+ not hold. Each verdict counts toward the precision of the detector that raised the gap
94
+ (`accept` and `covered-by` for it, `wrong` and `covered-elsewhere` against it), so a
95
+ detector that keeps being wrong is muted.
94
96
 
95
97
  ## Guardrails
96
98