@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.
- package/dist/global-setup-module.d.ts +2 -1
- package/dist/global-setup-module.js +432 -3
- package/dist/index.d.ts +204 -8
- package/dist/index.js +4724 -23
- package/dist/internal/capture/attachments.d.ts +8 -3
- package/dist/internal/capture/attachments.js +46 -21
- package/dist/internal/capture/capture-fixtures.d.ts +16 -14
- package/dist/internal/capture/capture-fixtures.js +2211 -971
- package/dist/internal/capture/inspect-on-failure.d.ts +50 -0
- package/dist/internal/capture/inspect-on-failure.js +66 -0
- package/dist/internal/capture/locator-healing.d.ts +33 -190
- package/dist/internal/capture/locator-healing.js +599 -815
- package/dist/internal/capture/pick-on-failure.d.ts +198 -0
- package/dist/internal/capture/pick-on-failure.js +1203 -0
- package/package.json +9 -4
- package/dist/internal/collect/error-text.d.ts +0 -18
- package/dist/internal/collect/error-text.js +0 -79
- package/dist/internal/collect/metadata-collector.d.ts +0 -32
- package/dist/internal/collect/metadata-collector.js +0 -246
- package/dist/internal/collect/skip-classify.d.ts +0 -27
- package/dist/internal/collect/skip-classify.js +0 -40
- package/dist/internal/collect/step-analyzer.d.ts +0 -103
- package/dist/internal/collect/step-analyzer.js +0 -221
- package/dist/internal/config/env.d.ts +0 -46
- package/dist/internal/config/env.js +0 -162
- package/dist/internal/files/compression.d.ts +0 -5
- package/dist/internal/files/compression.js +0 -69
- package/dist/internal/files/file-handler.d.ts +0 -38
- package/dist/internal/files/file-handler.js +0 -207
- package/dist/internal/streaming/crash-recovery.d.ts +0 -23
- package/dist/internal/streaming/crash-recovery.js +0 -106
- package/dist/internal/streaming/stream-buffer.d.ts +0 -17
- package/dist/internal/streaming/stream-buffer.js +0 -102
- package/dist/internal/streaming/stream-manager.d.ts +0 -88
- package/dist/internal/streaming/stream-manager.js +0 -395
- package/dist/internal/submit/run-submitter.d.ts +0 -67
- package/dist/internal/submit/run-submitter.js +0 -190
- package/dist/internal/submit/serializer.d.ts +0 -45
- package/dist/internal/submit/serializer.js +0 -108
- package/dist/internal/submit/uploader.d.ts +0 -89
- package/dist/internal/submit/uploader.js +0 -226
- package/dist/internal/support/ci.d.ts +0 -2
- package/dist/internal/support/ci.js +0 -32
- package/dist/internal/support/cli-filters.d.ts +0 -1
- package/dist/internal/support/cli-filters.js +0 -51
- package/dist/internal/support/errors.d.ts +0 -8
- package/dist/internal/support/errors.js +0 -15
- package/dist/internal/support/instance-id.d.ts +0 -4
- package/dist/internal/support/instance-id.js +0 -48
- package/dist/internal/support/limiter.d.ts +0 -2
- package/dist/internal/support/limiter.js +0 -27
- package/dist/internal/support/logger.d.ts +0 -26
- package/dist/internal/support/logger.js +0 -43
- package/dist/internal/support/reporter-version.d.ts +0 -2
- package/dist/internal/support/reporter-version.js +0 -54
- package/dist/internal/support/setup-file.d.ts +0 -13
- package/dist/internal/support/setup-file.js +0 -61
- package/dist/internal/support/source-snippet.d.ts +0 -12
- package/dist/internal/support/source-snippet.js +0 -97
- package/dist/internal/support/worker-index.d.ts +0 -7
- package/dist/internal/support/worker-index.js +0 -14
- package/dist/internal/transport/http-client.d.ts +0 -52
- package/dist/internal/transport/http-client.js +0 -201
- package/dist/public/config-wrapper.d.ts +0 -21
- package/dist/public/config-wrapper.js +0 -64
- package/dist/public/global-setup.d.ts +0 -13
- package/dist/public/global-setup.js +0 -146
- package/dist/public/options.d.ts +0 -86
- package/dist/public/options.js +0 -2
- package/dist/public/reporter.d.ts +0 -68
- package/dist/public/reporter.js +0 -376
- package/dist/types/collected.d.ts +0 -97
- package/dist/types/collected.js +0 -10
- package/dist/types/wire.d.ts +0 -176
- package/dist/types/wire.js +0 -14
- package/dist/types.d.ts +0 -11
- package/dist/types.js +0 -27
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { TestInfo } from '@playwright/test';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shared gate for Piwi's failure-time overlay. Both `inspectOnFailure`
|
|
5
|
+
* (`PIWI_INSPECT_ON_FAIL`) and `pickLocatorOnFailure` (`PIWI_PICK_LOCATOR_ON_FAIL`)
|
|
6
|
+
* open Piwi's own in-page overlay (see `pick-on-failure.ts`) — never
|
|
7
|
+
* Playwright's native inspector — so the experience is fully ours and a
|
|
8
|
+
* confirmed pick flows back into the dashboard.
|
|
9
|
+
*
|
|
10
|
+
* Local-only by design: the overlay needs a human and a visible browser, so the
|
|
11
|
+
* gate requires a headed browser and refuses to run under CI regardless of the
|
|
12
|
+
* flag. It also waits for the final attempt when retries are configured — an
|
|
13
|
+
* attempt that is about to be retried closes without opening the overlay.
|
|
14
|
+
*/
|
|
15
|
+
/** Everything the gate reads, as plain values so it stays unit-testable. */
|
|
16
|
+
interface InspectionGate {
|
|
17
|
+
/** Raw `PIWI_INSPECT_ON_FAIL` env value — only the string `'true'` enables. */
|
|
18
|
+
enabled: string | undefined;
|
|
19
|
+
/** Raw `CI` env value. Anything except unset/empty/`'false'` counts as CI. */
|
|
20
|
+
ci: string | undefined;
|
|
21
|
+
/** `testInfo.status` at teardown. */
|
|
22
|
+
status: string | undefined;
|
|
23
|
+
/** `testInfo.expectedStatus` — an expected failure (test.fail()) never pauses. */
|
|
24
|
+
expectedStatus: string | undefined;
|
|
25
|
+
/** `testInfo.project.use.headless` — must be explicitly `false` (headed). */
|
|
26
|
+
headless: unknown;
|
|
27
|
+
/** Zero-based attempt index (`testInfo.retry`). */
|
|
28
|
+
retry: number;
|
|
29
|
+
/** Configured retry count for the project (`testInfo.project.retries`). */
|
|
30
|
+
retries: number;
|
|
31
|
+
}
|
|
32
|
+
/** Decide whether the failing page should be handed to the Inspector. */
|
|
33
|
+
declare function shouldInspectOnFailure(gate: InspectionGate): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* When a failure-time feature is *enabled* on a *real* failure but the gate
|
|
36
|
+
* still refused for an environmental reason (headless / CI), return a
|
|
37
|
+
* one-line human explanation so "nothing happened" is never a silent mystery.
|
|
38
|
+
* Returns null when the feature is off, the test didn't really fail, or the
|
|
39
|
+
* gate would actually pass (the feature ran, so there is nothing to explain).
|
|
40
|
+
*/
|
|
41
|
+
declare function environmentalSkipReason(gate: InspectionGate): string | null;
|
|
42
|
+
/**
|
|
43
|
+
* Project the live TestInfo + process env into the plain gate shape. The gate
|
|
44
|
+
* conditions are shared by every failure-time affordance that needs a live
|
|
45
|
+
* headed page; `enabled` selects which opt-in flag arms this one (defaults to
|
|
46
|
+
* the Inspector's `PIWI_INSPECT_ON_FAIL`).
|
|
47
|
+
*/
|
|
48
|
+
declare function inspectionGateFromTestInfo(testInfo: TestInfo, enabled?: string | undefined): InspectionGate;
|
|
49
|
+
|
|
50
|
+
export { type InspectionGate, environmentalSkipReason, inspectionGateFromTestInfo, shouldInspectOnFailure };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/internal/capture/inspect-on-failure.ts
|
|
21
|
+
var inspect_on_failure_exports = {};
|
|
22
|
+
__export(inspect_on_failure_exports, {
|
|
23
|
+
environmentalSkipReason: () => environmentalSkipReason,
|
|
24
|
+
inspectionGateFromTestInfo: () => inspectionGateFromTestInfo,
|
|
25
|
+
shouldInspectOnFailure: () => shouldInspectOnFailure
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(inspect_on_failure_exports);
|
|
28
|
+
function isCi(ci) {
|
|
29
|
+
return ci !== void 0 && ci !== "" && ci !== "false";
|
|
30
|
+
}
|
|
31
|
+
function shouldInspectOnFailure(gate) {
|
|
32
|
+
if (gate.enabled !== "true") return false;
|
|
33
|
+
if (isCi(gate.ci)) return false;
|
|
34
|
+
if (gate.headless !== false) return false;
|
|
35
|
+
if (gate.status !== "failed" && gate.status !== "timedOut") return false;
|
|
36
|
+
if (gate.status === gate.expectedStatus) return false;
|
|
37
|
+
return gate.retry >= gate.retries;
|
|
38
|
+
}
|
|
39
|
+
function environmentalSkipReason(gate) {
|
|
40
|
+
if (gate.enabled !== "true") return null;
|
|
41
|
+
if (gate.status !== "failed" && gate.status !== "timedOut") return null;
|
|
42
|
+
if (gate.status === gate.expectedStatus) return null;
|
|
43
|
+
if (isCi(gate.ci)) return "running under CI \u2014 this is a headed, local-only feature";
|
|
44
|
+
if (gate.headless !== false) {
|
|
45
|
+
return "the browser is headless \u2014 re-run with --headed (or set use: { headless: false })";
|
|
46
|
+
}
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
function inspectionGateFromTestInfo(testInfo, enabled = process.env.PIWI_INSPECT_ON_FAIL) {
|
|
50
|
+
const use = testInfo.project?.use ?? {};
|
|
51
|
+
return {
|
|
52
|
+
enabled,
|
|
53
|
+
ci: process.env.CI,
|
|
54
|
+
status: testInfo.status,
|
|
55
|
+
expectedStatus: testInfo.expectedStatus,
|
|
56
|
+
headless: use.headless,
|
|
57
|
+
retry: testInfo.retry,
|
|
58
|
+
retries: testInfo.project?.retries ?? 0
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
62
|
+
0 && (module.exports = {
|
|
63
|
+
environmentalSkipReason,
|
|
64
|
+
inspectionGateFromTestInfo,
|
|
65
|
+
shouldInspectOnFailure
|
|
66
|
+
});
|
|
@@ -1,108 +1,22 @@
|
|
|
1
|
+
export { CAPTURED_ATTRIBUTES, INPUT_TYPE_TO_ROLE, TAG_TO_ROLE, approximateAccessibleName, classifyCssStability, generateAlternatives, headingLevel, isAutoGenerated, resolveAriaRole } from '@piwitests/core/locator-generation';
|
|
2
|
+
import { LocatorSnapshot } from '@piwitests/core/locator-healing-types';
|
|
3
|
+
export { AncestorAnchor, ElementAttributes, LocatorSnapshot, RankedLocator, RolePosition, SelectorCounts } from '@piwitests/core/locator-healing-types';
|
|
4
|
+
|
|
1
5
|
/**
|
|
2
|
-
* Reporter-local locator healing
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Match counts for candidate selectors, probed with `querySelectorAll` against
|
|
16
|
-
* the live page at capture time. A count > 1 means the selector is ambiguous
|
|
17
|
-
* (would be a strict-mode violation) and the alternative is suppressed; a
|
|
18
|
-
* missing count means the probe didn't run and the alternative is kept.
|
|
19
|
-
*/
|
|
20
|
-
export interface SelectorCounts {
|
|
21
|
-
testId?: number;
|
|
22
|
-
id?: number;
|
|
23
|
-
name?: number;
|
|
24
|
-
classes?: Record<string, number>;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* The element's position among same-role elements in the document at capture
|
|
28
|
-
* time — a name-independent structural identity. `levelCount` additionally
|
|
29
|
-
* counts same-role elements sharing this element's heading level, so a lone
|
|
30
|
-
* `h1` among many `h2`s still gets a name-free `getByRole('heading', { level: 1 })`.
|
|
31
|
-
*/
|
|
32
|
-
export interface RolePosition {
|
|
33
|
-
role: string;
|
|
34
|
-
count: number;
|
|
35
|
-
index: number;
|
|
36
|
-
levelCount?: number;
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* An anchor-worthy ancestor — one carrying a stable hook (test id, id,
|
|
40
|
-
* explicit role, aria-label, or a landmark tag) that a scoped alternative can
|
|
41
|
-
* chain from. Nearest ancestors first.
|
|
6
|
+
* Reporter-local locator healing.
|
|
7
|
+
*
|
|
8
|
+
* The pure surface — alternative generation, stability scoring, ARIA-role
|
|
9
|
+
* resolution, the role maps and the captured-attribute whitelist — lives in
|
|
10
|
+
* `@piwitests/core` (bundled into `dist/` at build time, so nothing
|
|
11
|
+
* monorepo-relative leaks into the published package). It is re-exported from
|
|
12
|
+
* here so existing importers (`capture-fixtures.ts`, `pick-on-failure.ts`, the
|
|
13
|
+
* unit tests) keep importing it from this module.
|
|
14
|
+
*
|
|
15
|
+
* This module keeps only the reporter-only runtime: call-site capture (needs the
|
|
16
|
+
* Node stack), snapshot dedupe, the fixture-proxy method surface, and the
|
|
17
|
+
* failure-time locator suggestion + rendering.
|
|
42
18
|
*/
|
|
43
|
-
|
|
44
|
-
tag: string;
|
|
45
|
-
/** Hops from the element (1 = direct parent). */
|
|
46
|
-
depth: number;
|
|
47
|
-
testId: string | null;
|
|
48
|
-
id: string | null;
|
|
49
|
-
role: string | null;
|
|
50
|
-
ariaLabel: string | null;
|
|
51
|
-
/** Same-role matches for the captured element within this ancestor. */
|
|
52
|
-
scopedRoleCount?: number;
|
|
53
|
-
/** Document-wide match count for this ancestor's own data-testid. */
|
|
54
|
-
testIdCount?: number;
|
|
55
|
-
/** Document-wide match count for this ancestor's own id. */
|
|
56
|
-
idCount?: number;
|
|
57
|
-
/** Document-wide count of elements resolving to this ancestor's landmark/explicit role. */
|
|
58
|
-
roleCount?: number;
|
|
59
|
-
}
|
|
60
|
-
export interface ElementAttributes {
|
|
61
|
-
tagName: string;
|
|
62
|
-
attributes: Record<string, string | null>;
|
|
63
|
-
textContent: string | null;
|
|
64
|
-
accessibleName: string | null;
|
|
65
|
-
center: {
|
|
66
|
-
x: number;
|
|
67
|
-
y: number;
|
|
68
|
-
} | null;
|
|
69
|
-
/**
|
|
70
|
-
* True when the element has an associated `<label>` (`el.labels`). Gates the
|
|
71
|
-
* `getByLabel` alternative — an accessible name approximated from
|
|
72
|
-
* placeholder/title would produce a `getByLabel` that matches nothing.
|
|
73
|
-
* Undefined on payloads from older capture probes (legacy behavior applies).
|
|
74
|
-
*/
|
|
75
|
-
hasLabel?: boolean;
|
|
76
|
-
/** Live-page uniqueness probe results for candidate selectors. */
|
|
77
|
-
selectorCounts?: SelectorCounts;
|
|
78
|
-
/** Position among same-role elements — powers name-free and renamed-element healing. */
|
|
79
|
-
rolePosition?: RolePosition | null;
|
|
80
|
-
/** Anchor-worthy ancestors, nearest first — power ancestor-scoped alternatives. */
|
|
81
|
-
ancestors?: AncestorAnchor[];
|
|
82
|
-
}
|
|
83
|
-
export interface LocatorSnapshot {
|
|
84
|
-
location: string | null;
|
|
85
|
-
used: {
|
|
86
|
-
method: string;
|
|
87
|
-
args: unknown[];
|
|
88
|
-
raw: string;
|
|
89
|
-
};
|
|
90
|
-
element: {
|
|
91
|
-
tagName: string;
|
|
92
|
-
attributes: Record<string, string | null>;
|
|
93
|
-
textContent: string | null;
|
|
94
|
-
accessibleName: string | null;
|
|
95
|
-
center: {
|
|
96
|
-
x: number;
|
|
97
|
-
y: number;
|
|
98
|
-
} | null;
|
|
99
|
-
/** Position among same-role elements at capture time. */
|
|
100
|
-
rolePosition?: RolePosition | null;
|
|
101
|
-
/** Anchor-worthy ancestors, nearest first. */
|
|
102
|
-
ancestors?: AncestorAnchor[];
|
|
103
|
-
} | null;
|
|
104
|
-
alternatives: RankedLocator[];
|
|
105
|
-
}
|
|
19
|
+
|
|
106
20
|
/**
|
|
107
21
|
* Drop repeated captures of the same call site before attaching: a loop (or a
|
|
108
22
|
* page-object method called repeatedly) produces one snapshot per action, but
|
|
@@ -111,78 +25,24 @@ export interface LocatorSnapshot {
|
|
|
111
25
|
* when no capture resolved, so the location still counts as "seen this run"
|
|
112
26
|
* for the server's stale-location purge. Entries with no location pass through.
|
|
113
27
|
*/
|
|
114
|
-
|
|
28
|
+
declare function dedupeSnapshotsByLocation(snaps: LocatorSnapshot[]): LocatorSnapshot[];
|
|
115
29
|
/**
|
|
116
30
|
* Page-level locator-building methods wrapped by the capture proxy. Imported by
|
|
117
31
|
* both the capture fixtures (`capture-fixtures.ts`) and the dogfooding
|
|
118
32
|
* `application/tests/fixtures.ts` so the two stay in sync (a prior drift missed
|
|
119
33
|
* `scrollIntoViewIfNeeded`).
|
|
120
34
|
*/
|
|
121
|
-
|
|
35
|
+
declare const LOCATOR_METHODS: string[];
|
|
122
36
|
/**
|
|
123
37
|
* Methods that can be chained onto a wrapped locator. Locator-creating chains
|
|
124
38
|
* (those also in `LOCATOR_METHODS`) update the origin; positional/filter chains
|
|
125
39
|
* (`first`, `nth`, `filter`, …) narrow without changing locator identity.
|
|
126
40
|
*/
|
|
127
|
-
|
|
41
|
+
declare const CHAIN_METHODS: string[];
|
|
128
42
|
/** Locator action methods that trigger element capture. */
|
|
129
|
-
|
|
43
|
+
declare const ACTION_METHODS: string[];
|
|
130
44
|
/** Chain methods that create a new locator scope (origin tracks the chain call). */
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Element attributes to capture after a successful action, passed into the
|
|
134
|
-
* in-page `evaluate`. Shared so the reporter and dogfooding fixtures capture
|
|
135
|
-
* the same attribute set.
|
|
136
|
-
*/
|
|
137
|
-
export declare const CAPTURED_ATTRIBUTES: string[];
|
|
138
|
-
/**
|
|
139
|
-
* Implicit ARIA role for an HTML tag (when no explicit `role` is set). Exported
|
|
140
|
-
* so the in-page probe (`capture-fixtures.ts#probeElementAttrs`) can receive
|
|
141
|
-
* this same map as an `evaluate` argument instead of re-declaring it — the
|
|
142
|
-
* probe is serialized into the browser and can't reference this module's
|
|
143
|
-
* closure, but the map is pure data and rides in as an argument.
|
|
144
|
-
*/
|
|
145
|
-
export declare const TAG_TO_ROLE: Record<string, string>;
|
|
146
|
-
/** Implicit ARIA role for an `<input>` keyed by its `type` attribute. Exported for the probe (see {@link TAG_TO_ROLE}). */
|
|
147
|
-
export declare const INPUT_TYPE_TO_ROLE: Record<string, string>;
|
|
148
|
-
/**
|
|
149
|
-
* Resolve the ARIA role for an element. An explicit `role` attribute wins;
|
|
150
|
-
* otherwise the implicit role is derived from the tag name (and `type` for
|
|
151
|
-
* `<input>`). Returns null when the element has no ARIA role (e.g. `<div>`,
|
|
152
|
-
* `<span>`, `<a>` without `href`) — `getByRole` is not a valid locator for
|
|
153
|
-
* such elements and other alternatives take over.
|
|
154
|
-
*/
|
|
155
|
-
export declare function resolveAriaRole(attrs: ElementAttributes): string | null;
|
|
156
|
-
/**
|
|
157
|
-
* Heading level for a `heading`-role element: h1-h6 from the tag, else an
|
|
158
|
-
* explicit `aria-level` attribute. Null when unknown (don't guess the ARIA
|
|
159
|
-
* default) or when the element isn't a heading.
|
|
160
|
-
*/
|
|
161
|
-
export declare function headingLevel(attrs: ElementAttributes, role: string | null): number | null;
|
|
162
|
-
/**
|
|
163
|
-
* Build a ranked list of alternative locators from the captured element
|
|
164
|
-
* attributes. The list is sorted descending by stability score.
|
|
165
|
-
*
|
|
166
|
-
* Only generates alternatives that differ from each other — no duplicates
|
|
167
|
-
* of the same locator expression.
|
|
168
|
-
*/
|
|
169
|
-
export declare function generateAlternatives(attrs: ElementAttributes): RankedLocator[];
|
|
170
|
-
/**
|
|
171
|
-
* Score a CSS class name on a 0-40 stability scale.
|
|
172
|
-
*
|
|
173
|
-
* Heuristics (inherited from common CSS-naming conventions):
|
|
174
|
-
* - Hash-like suffixes (≥4 hex chars) → 10 — auto-generated, fragile
|
|
175
|
-
* - CSS-in-JS patterns (css-, sc-, emotion-, styled-, _) → 15
|
|
176
|
-
* - Tailwind/utility classes → 25
|
|
177
|
-
* - BEM-style semantic → 35
|
|
178
|
-
* - Plain semantic → 40
|
|
179
|
-
*/
|
|
180
|
-
export declare function classifyCssStability(className: string): number;
|
|
181
|
-
/**
|
|
182
|
-
* Detects GUID-like, auto-incremented, or hash-suffixed IDs that are
|
|
183
|
-
* likely regenerated on each render and unstable for testing.
|
|
184
|
-
*/
|
|
185
|
-
export declare function isAutoGenerated(value: string): boolean;
|
|
45
|
+
declare const LOCATOR_CREATING_CHAINS: ReadonlySet<string>;
|
|
186
46
|
/**
|
|
187
47
|
* Extract the accessible name from a YAML-like ariaSnapshot() output.
|
|
188
48
|
*
|
|
@@ -194,41 +54,22 @@ export declare function isAutoGenerated(value: string): boolean;
|
|
|
194
54
|
*
|
|
195
55
|
* Returns the first quoted string after the role, or null if none found.
|
|
196
56
|
*/
|
|
197
|
-
|
|
198
|
-
/**
|
|
199
|
-
* Approximate the accessible name from HTML attributes when ariaSnapshot()
|
|
200
|
-
* is unavailable. Priority: aria-label > text content > title > placeholder.
|
|
201
|
-
*/
|
|
202
|
-
export declare function approximateAccessibleName(attrs: ElementAttributes): string | null;
|
|
57
|
+
declare function extractAccessibleName(ariaSnapshot: string | null): string | null;
|
|
203
58
|
/** A failed locator action, used to suggest a fresh locator from the live page. */
|
|
204
|
-
|
|
59
|
+
interface FailedLocatorInfo {
|
|
205
60
|
method: string;
|
|
206
61
|
args: unknown[];
|
|
62
|
+
/** Test call site (`file:line:col`) of the failed action, when captured. */
|
|
63
|
+
location?: string | null;
|
|
207
64
|
}
|
|
208
|
-
|
|
65
|
+
interface LocatorSuggestion {
|
|
209
66
|
/** The failed locator rendered as source, e.g. `getByText('Go to page')`. */
|
|
210
67
|
failing: string;
|
|
211
68
|
/** Fresh locator suggestions for the element's current identity, best first. */
|
|
212
69
|
suggestions: string[];
|
|
213
70
|
}
|
|
214
|
-
/**
|
|
215
|
-
|
|
216
|
-
* `parseAriaCandidates` in application/shared/locator-fingerprint.ts).
|
|
217
|
-
* Exported so the dashboard's drift-guard unit test can compare the two.
|
|
218
|
-
*/
|
|
219
|
-
export declare function parseAriaRoleName(ariaSnapshot: string): Array<{
|
|
220
|
-
role: string;
|
|
221
|
-
name: string | null;
|
|
222
|
-
level: number | null;
|
|
223
|
-
}>;
|
|
224
|
-
/**
|
|
225
|
-
* Token-set (Dice) similarity, 0-1, case- and punctuation-insensitive.
|
|
226
|
-
* Duplicated from `textSimilarity` in application/shared/locator-fingerprint.ts —
|
|
227
|
-
* this package publishes standalone to npm and can't import monorepo-relative
|
|
228
|
-
* shared/ code, so keep the two implementations in sync by hand. Exported so
|
|
229
|
-
* the dashboard's drift-guard unit test can compare the two.
|
|
230
|
-
*/
|
|
231
|
-
export declare function nameSimilarity(a: string | null, b: string | null): number;
|
|
71
|
+
/** Render the failed locator back to source for annotation/picker messages. */
|
|
72
|
+
declare function renderFailing(failed: FailedLocatorInfo): string;
|
|
232
73
|
/**
|
|
233
74
|
* Best-effort runtime suggestion for a locator that matched nothing: find the
|
|
234
75
|
* element on the *current* page that the failed locator most likely targeted
|
|
@@ -240,7 +81,7 @@ export declare function nameSimilarity(a: string | null, b: string | null): numb
|
|
|
240
81
|
* for non-name-based locators (testid/CSS), when the targeted name is still
|
|
241
82
|
* present (so the failure wasn't a rename), or when no candidate is confident.
|
|
242
83
|
*/
|
|
243
|
-
|
|
84
|
+
declare function suggestLocatorsFromAria(failed: FailedLocatorInfo, ariaSnapshot: string | null): LocatorSuggestion | null;
|
|
244
85
|
/**
|
|
245
86
|
* Capture the calling test's source location (`file:line:col`) from the current
|
|
246
87
|
* stack, for stamping onto a locator snapshot. The path is made cwd-relative so
|
|
@@ -255,4 +96,6 @@ export declare function suggestLocatorsFromAria(failed: FailedLocatorInfo, ariaS
|
|
|
255
96
|
* Returns null when no user frame can be identified — the snapshot keeps
|
|
256
97
|
* `location: null` and the server falls back to fingerprint / ARIA lookup.
|
|
257
98
|
*/
|
|
258
|
-
|
|
99
|
+
declare function captureCallerLocation(stack?: string): string | null;
|
|
100
|
+
|
|
101
|
+
export { ACTION_METHODS, CHAIN_METHODS, type FailedLocatorInfo, LOCATOR_CREATING_CHAINS, LOCATOR_METHODS, type LocatorSuggestion, captureCallerLocation, dedupeSnapshotsByLocation, extractAccessibleName, renderFailing, suggestLocatorsFromAria };
|