@piwitests/reporter 0.12.0 → 0.13.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.
Files changed (77) hide show
  1. package/dist/global-setup-module.d.ts +2 -1
  2. package/dist/global-setup-module.js +432 -3
  3. package/dist/index.d.ts +204 -8
  4. package/dist/index.js +4724 -23
  5. package/dist/internal/capture/attachments.d.ts +8 -3
  6. package/dist/internal/capture/attachments.js +46 -21
  7. package/dist/internal/capture/capture-fixtures.d.ts +16 -14
  8. package/dist/internal/capture/capture-fixtures.js +2211 -971
  9. package/dist/internal/capture/inspect-on-failure.d.ts +50 -0
  10. package/dist/internal/capture/inspect-on-failure.js +66 -0
  11. package/dist/internal/capture/locator-healing.d.ts +33 -190
  12. package/dist/internal/capture/locator-healing.js +599 -815
  13. package/dist/internal/capture/pick-on-failure.d.ts +198 -0
  14. package/dist/internal/capture/pick-on-failure.js +1203 -0
  15. package/package.json +9 -4
  16. package/dist/internal/collect/error-text.d.ts +0 -18
  17. package/dist/internal/collect/error-text.js +0 -79
  18. package/dist/internal/collect/metadata-collector.d.ts +0 -32
  19. package/dist/internal/collect/metadata-collector.js +0 -246
  20. package/dist/internal/collect/skip-classify.d.ts +0 -27
  21. package/dist/internal/collect/skip-classify.js +0 -40
  22. package/dist/internal/collect/step-analyzer.d.ts +0 -103
  23. package/dist/internal/collect/step-analyzer.js +0 -221
  24. package/dist/internal/config/env.d.ts +0 -46
  25. package/dist/internal/config/env.js +0 -162
  26. package/dist/internal/files/compression.d.ts +0 -5
  27. package/dist/internal/files/compression.js +0 -69
  28. package/dist/internal/files/file-handler.d.ts +0 -38
  29. package/dist/internal/files/file-handler.js +0 -207
  30. package/dist/internal/streaming/crash-recovery.d.ts +0 -23
  31. package/dist/internal/streaming/crash-recovery.js +0 -106
  32. package/dist/internal/streaming/stream-buffer.d.ts +0 -17
  33. package/dist/internal/streaming/stream-buffer.js +0 -102
  34. package/dist/internal/streaming/stream-manager.d.ts +0 -88
  35. package/dist/internal/streaming/stream-manager.js +0 -395
  36. package/dist/internal/submit/run-submitter.d.ts +0 -67
  37. package/dist/internal/submit/run-submitter.js +0 -190
  38. package/dist/internal/submit/serializer.d.ts +0 -45
  39. package/dist/internal/submit/serializer.js +0 -108
  40. package/dist/internal/submit/uploader.d.ts +0 -89
  41. package/dist/internal/submit/uploader.js +0 -226
  42. package/dist/internal/support/ci.d.ts +0 -2
  43. package/dist/internal/support/ci.js +0 -32
  44. package/dist/internal/support/cli-filters.d.ts +0 -1
  45. package/dist/internal/support/cli-filters.js +0 -51
  46. package/dist/internal/support/errors.d.ts +0 -8
  47. package/dist/internal/support/errors.js +0 -15
  48. package/dist/internal/support/instance-id.d.ts +0 -4
  49. package/dist/internal/support/instance-id.js +0 -48
  50. package/dist/internal/support/limiter.d.ts +0 -2
  51. package/dist/internal/support/limiter.js +0 -27
  52. package/dist/internal/support/logger.d.ts +0 -26
  53. package/dist/internal/support/logger.js +0 -43
  54. package/dist/internal/support/reporter-version.d.ts +0 -2
  55. package/dist/internal/support/reporter-version.js +0 -54
  56. package/dist/internal/support/setup-file.d.ts +0 -13
  57. package/dist/internal/support/setup-file.js +0 -61
  58. package/dist/internal/support/source-snippet.d.ts +0 -12
  59. package/dist/internal/support/source-snippet.js +0 -97
  60. package/dist/internal/support/worker-index.d.ts +0 -7
  61. package/dist/internal/support/worker-index.js +0 -14
  62. package/dist/internal/transport/http-client.d.ts +0 -52
  63. package/dist/internal/transport/http-client.js +0 -201
  64. package/dist/public/config-wrapper.d.ts +0 -21
  65. package/dist/public/config-wrapper.js +0 -64
  66. package/dist/public/global-setup.d.ts +0 -13
  67. package/dist/public/global-setup.js +0 -146
  68. package/dist/public/options.d.ts +0 -86
  69. package/dist/public/options.js +0 -2
  70. package/dist/public/reporter.d.ts +0 -68
  71. package/dist/public/reporter.js +0 -376
  72. package/dist/types/collected.d.ts +0 -97
  73. package/dist/types/collected.js +0 -10
  74. package/dist/types/wire.d.ts +0 -176
  75. package/dist/types/wire.js +0 -14
  76. package/dist/types.d.ts +0 -11
  77. package/dist/types.js +0 -27
@@ -0,0 +1,198 @@
1
+ import { TestInfo, Page } from '@playwright/test';
2
+ import { FailedLocatorInfo } from './locator-healing.js';
3
+ import { SelectorCounts, RolePosition, AncestorAnchor, RankedLocator, LocatorSnapshot } from '@piwitests/core/locator-healing-types';
4
+ import '@piwitests/core/locator-generation';
5
+
6
+ /**
7
+ * Failure-time locator picker: when enabled (opt-in via the
8
+ * `pickLocatorOnFailure` reporter option / `PIWI_PICK_LOCATOR_ON_FAIL`), a
9
+ * test whose locator action failed gets a picker overlay injected into the
10
+ * still-open page. The flow is guided:
11
+ *
12
+ * 1. **Element** — hover highlights, a click picks. The pick snaps to the
13
+ * nearest actionable ancestor (a click on the `<span>` inside a button
14
+ * picks the button), and ↑/↓ walk the DOM tree before the click commits.
15
+ * 2. **Anchors** — the element's ancestors are listed; the human can bless
16
+ * one or more *stable parents* to scope the locator to, with a live
17
+ * "matches N" count for the current selection against the failing page.
18
+ * 3. **Confirm** — ranked replacement locators (standard generation merged
19
+ * with the anchor-scoped candidates) are listed; the human confirms one.
20
+ *
21
+ * The confirmed pick is folded into the failing call site's locator snapshot
22
+ * (so it rides the normal `piwi-locators` wire into the dashboard's healing
23
+ * panel) and attached as `piwi-user-pick` plus a report annotation.
24
+ *
25
+ * Gated exactly like failure-time inspection (`inspect-on-failure.ts`):
26
+ * headed browser, never CI, final attempt only.
27
+ */
28
+ /** Element shape the in-page probe returns — structural view of what the picker needs. */
29
+ interface ProbedAttrs {
30
+ tagName: string;
31
+ attributes: Record<string, string | null>;
32
+ textContent: string | null;
33
+ center: {
34
+ x: number;
35
+ y: number;
36
+ } | null;
37
+ hasLabel?: boolean;
38
+ selectorCounts?: SelectorCounts;
39
+ rolePosition?: RolePosition | null;
40
+ ancestors?: AncestorAnchor[];
41
+ }
42
+ /**
43
+ * The probe dependency, passed in by the capture fixture to avoid an import
44
+ * cycle. `fn` is the fixture's in-page element probe (`probeElementAttrs`);
45
+ * `el` is a browser-side element, hence `any` (no DOM lib in this package).
46
+ * `arg` is the fixture's `CAPTURED_ATTRS_ARG` — its role maps also drive the
47
+ * anchor step's in-page role resolution.
48
+ */
49
+ interface PickerProbe {
50
+ fn: (el: any, arg: any) => ProbedAttrs;
51
+ arg: unknown;
52
+ }
53
+ /** An ancestor the human blessed as an anchor, with its in-page uniqueness counts. */
54
+ interface PickedAnchorInfo {
55
+ tag: string;
56
+ /** Hops from the picked element (1 = direct parent). */
57
+ depth: number;
58
+ testId: string | null;
59
+ id: string | null;
60
+ ariaLabel: string | null;
61
+ /** Resolved anchor role (explicit attribute or tag-implied). */
62
+ role: string | null;
63
+ /** Document-wide match count for the anchor's own data-testid. */
64
+ testIdCount?: number;
65
+ /** Document-wide match count for the anchor's own id. */
66
+ idCount?: number;
67
+ /** Document-wide count of same-role elements carrying the same aria-label. */
68
+ labeledRoleCount?: number;
69
+ /** Document-wide count of elements resolving to the anchor's role. */
70
+ roleCount?: number;
71
+ /** Leaf matches (picked element's identity) within this anchor's subtree. */
72
+ scopedLeafCount?: number;
73
+ }
74
+ /** The picked element's identity used for anchor-scoped candidates. */
75
+ interface PickedLeafInfo {
76
+ role: string | null;
77
+ level: number | null;
78
+ }
79
+ /** A confirmed pick — everything the fixture records about the human's choice. */
80
+ interface UserPickResult {
81
+ /**
82
+ * The locator this pick replaces. Null when the overlay was opened purely to
83
+ * inspect (`inspectOnFailure` with no identifiable failing locator) — the
84
+ * pick still yields alternatives, but there is nothing to write back to.
85
+ */
86
+ failing: {
87
+ method: string;
88
+ args: unknown[];
89
+ /** The failed locator rendered as source, e.g. `getByText('Pay now')`. */
90
+ rendered: string;
91
+ /** Test call site (`file:line:col`) of the failed action, when captured. */
92
+ location: string | null;
93
+ } | null;
94
+ /** The alternative the human confirmed (also first in `alternatives`). */
95
+ picked: RankedLocator;
96
+ /** Full ranked list for the picked element, the confirmed pick first. */
97
+ alternatives: RankedLocator[];
98
+ /** Wire-shaped element snapshot of the picked element. */
99
+ element: NonNullable<LocatorSnapshot['element']>;
100
+ /** Stable parents the human blessed in the anchor step, when any. */
101
+ anchors?: PickedAnchorInfo[];
102
+ }
103
+ /** Parse a Playwright locator expression into `{ method, args }` (leaf of any chain). Exported for tests. */
104
+ declare function parseLeafLocatorExpression(rawExpr: string): {
105
+ method: string;
106
+ args: unknown[];
107
+ } | null;
108
+ /**
109
+ * Derive the failing locator + call site from a test's error(s) when no locator
110
+ * action was captured (an `expect(...)` assertion failure). Reads the
111
+ * `Locator: …` line Playwright prints and the error's own call location,
112
+ * normalized cwd-relative to match captured snapshot locations. Returns null
113
+ * when no locator can be identified. Exported for tests.
114
+ */
115
+ declare function deriveFailedLocator(testInfo: TestInfo): FailedLocatorInfo | null;
116
+ /**
117
+ * Build anchor-scoped candidates from the human-blessed parents. Shapes stay
118
+ * consistent with the heuristic chains in `generateAlternatives` — leaf method
119
+ * `getByRole` with flat anchor args, no leaf `name` key. Single-anchor
120
+ * candidates require the leaf to be unique inside that anchor; with two or
121
+ * more anchors a combined chain is added when the whole chain resolves to
122
+ * exactly one element (`chainLeafCount`). Pure — exported for tests.
123
+ */
124
+ declare function generateAnchoredAlternatives(leaf: PickedLeafInfo, anchors: PickedAnchorInfo[], chainLeafCount?: number): RankedLocator[];
125
+ /** Merge candidate lists, first list winning duplicates, sorted by score. Exported for tests. */
126
+ declare function mergeCandidates(base: RankedLocator[], extra: RankedLocator[]): RankedLocator[];
127
+ /**
128
+ * Runs inside the browser via `evaluate()` — installs the element-picking
129
+ * overlay: a hover highlight, an instruction banner, and capture-phase
130
+ * listeners that suppress the app's own handlers while picking. The hover
131
+ * target snaps to the nearest actionable ancestor (button/link/field/role/
132
+ * testid) and ↑/↓ walk the DOM chain before the click commits. Resolves
133
+ * through `__piwiPickState` ('picked' | 'skipped') polled from Node; the
134
+ * picked element is parked in `__piwiPickedElement` for an `evaluateHandle`
135
+ * read. Must stay fully self-contained (no module-closure references).
136
+ */
137
+ declare function installPickerOverlay(arg: {
138
+ failing: string | null;
139
+ }): void;
140
+ /**
141
+ * Runs inside the browser via `evaluate()` — the anchor step: lists the picked
142
+ * element's ancestors so the human can bless one or more stable parents to
143
+ * scope the locator to. Each row shows the ancestor's strongest hook and how
144
+ * many leaf matches it contains; the footer shows a live "matches N" count for
145
+ * the combined selection, recomputed against the real failing page on every
146
+ * toggle (exactly 1 = green). Hovering a row outlines that ancestor in the
147
+ * page. Resolves through `__piwiAnchorState` ('done' | 'skipped'); selected
148
+ * anchors land in `__piwiPickAnchors` (+ `__piwiPickChainCount`). Role
149
+ * resolution reuses the maps passed in `arg` (single source of truth in
150
+ * locator-healing.ts). Must stay fully self-contained.
151
+ */
152
+ declare function showAnchorPicker(arg: {
153
+ tagRoles: Record<string, string>;
154
+ inputRoles: Record<string, string>;
155
+ roleSources: string;
156
+ leafRole: string;
157
+ leafLevel: number | null;
158
+ leafTestId: string | null;
159
+ }): void;
160
+ /**
161
+ * Runs inside the browser via `evaluate()` — replaces the pick overlay with a
162
+ * confirmation panel listing the ranked replacement locators. The chosen index
163
+ * lands in `__piwiPickChoice` (-1 = skipped), polled from Node. Must stay
164
+ * fully self-contained.
165
+ */
166
+ declare function showPickerChoices(arg: {
167
+ failing: string | null;
168
+ choices: Array<{
169
+ locator: string;
170
+ score: number;
171
+ }>;
172
+ }): void;
173
+ /**
174
+ * Drive the full pick flow on the failing page: element pick (snap +
175
+ * tree-walk), optional stable-parent anchoring with live match counts, ranked
176
+ * candidates (standard generation merged with anchor-scoped chains), and a
177
+ * final confirmation. The test timeout is lifted while waiting. Returns null
178
+ * when skipped or when anything breaks — the picker must never mask the
179
+ * test's own failure.
180
+ */
181
+ declare function runLocatorPicker(page: Page, testInfo: TestInfo, failed: FailedLocatorInfo | null, probe: PickerProbe): Promise<UserPickResult | null>;
182
+ /**
183
+ * Fold a confirmed pick into the captured snapshots: the failed action's
184
+ * placeholder (same call site, no element — capture never probes an action
185
+ * that threw) is filled with the picked element and the confirmed-first
186
+ * alternative list, so the pick rides the normal `piwi-locators` attachment
187
+ * into the dashboard's `locator_snapshots` and healing panel.
188
+ *
189
+ * A failed locator *action* left a placeholder at its call site (same location,
190
+ * no element) — that placeholder is filled in place. An assertion failure left
191
+ * no placeholder (no action ran), so a fresh snapshot is appended under the
192
+ * failing locator's location and signature instead, so the pick still reaches
193
+ * `locator_snapshots`. No-op only when the failing locator has no location.
194
+ * Exported for tests.
195
+ */
196
+ declare function applyPickToSnapshots(snapshots: LocatorSnapshot[], pick: UserPickResult): boolean;
197
+
198
+ export { type PickedAnchorInfo, type PickedLeafInfo, type PickerProbe, type UserPickResult, applyPickToSnapshots, deriveFailedLocator, generateAnchoredAlternatives, installPickerOverlay, mergeCandidates, parseLeafLocatorExpression, runLocatorPicker, showAnchorPicker, showPickerChoices };