fast-replay 0.4.2 → 0.5.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/README.md +31 -3
- package/dist/ir/schema.d.ts +3 -0
- package/dist/ir/schema.js +12 -0
- package/dist/ir/schema.js.map +1 -1
- package/dist/recorder/agent/selectors.d.ts +9 -0
- package/dist/recorder/agent/selectors.js +53 -8
- package/dist/recorder/agent/selectors.js.map +1 -1
- package/dist/recorder/agent/text.js +4 -0
- package/dist/recorder/agent/text.js.map +1 -1
- package/dist/recorder/agent-bundle.generated.d.ts +1 -1
- package/dist/recorder/agent-bundle.generated.js +1 -1
- package/dist/recorder/agent-bundle.generated.js.map +1 -1
- package/dist/recorder/types.d.ts +1 -0
- package/dist/replayer/resolve.d.ts +28 -0
- package/dist/replayer/resolve.js +49 -0
- package/dist/replayer/resolve.js.map +1 -1
- package/dist/replayer/run.js +38 -2
- package/dist/replayer/run.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,9 @@
|
|
|
3
3
|
[](https://github.com/mukhrr/fast-replay/actions/workflows/ci.yml)
|
|
4
4
|
[](https://www.npmjs.com/package/fast-replay)
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
Turn an expensive, unrepeatable setup into a cheap, repeatable question.
|
|
7
|
+
|
|
8
|
+
Some bugs live behind state you can only create once — a transferred workspace, a consumed invite, a migrated account. Getting there costs half an hour. Checking whether your fix worked should not cost it again. Record the observation once, and you own a few-second check you can run forever, with no model in the loop.
|
|
7
9
|
|
|
8
10
|
```
|
|
9
11
|
$ repro run sensor-delete-crash
|
|
@@ -123,6 +125,29 @@ Every step records where focus came to rest (`step.focusedAfter`). Nothing asser
|
|
|
123
125
|
|
|
124
126
|
Focus restoration (WCAG 2.4.3) leaves no console error, no failed request and no DOM difference, so it is invisible to every other signal — and a deterministic replayer settles it in one line.
|
|
125
127
|
|
|
128
|
+
## The technique that makes it work
|
|
129
|
+
|
|
130
|
+
**Do the irreversible part by hand. Record only the observation downstream of it.**
|
|
131
|
+
|
|
132
|
+
Almost every interesting bug sits behind state you cannot recreate on demand. Transfer the ownership, consume the invite, run the migration — once, manually. Then record the flow that *looks at* the result, which is cheap, deterministic and mutates nothing.
|
|
133
|
+
|
|
134
|
+
That split is what makes a repro replayable a hundred times, and it turns the single-shot limitation below from a disqualification into a normal part of authoring.
|
|
135
|
+
|
|
136
|
+
Recording programmatically is a first-class path, not a fallback:
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
import { record } from 'fast-replay';
|
|
140
|
+
|
|
141
|
+
await record({
|
|
142
|
+
name: 'transfer-owner-lockout',
|
|
143
|
+
baseUrl: 'https://staging.example.com',
|
|
144
|
+
drive: async (page) => {
|
|
145
|
+
// your setup already needs Playwright locators; reuse them here and
|
|
146
|
+
// you get a durable artifact for free
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
```
|
|
150
|
+
|
|
126
151
|
## Results
|
|
127
152
|
|
|
128
153
|
Measured on one machine, same flow both ways.
|
|
@@ -136,6 +161,8 @@ Measured on one machine, same flow both ways.
|
|
|
136
161
|
|
|
137
162
|
10-step flow: 20/20 consecutive replays, slowest 2.77 s.
|
|
138
163
|
|
|
164
|
+
Read that as the cost of *asking again*, not of the whole job — the setup behind a real bug dwarfs it. The point is that the setup is paid once and the question is paid every time.
|
|
165
|
+
|
|
139
166
|
The sharper claim is not speed. In a real app it caught a **736–779 ms** window where a total failed to render — a state that heals before a snapshot returns, so a model-in-the-loop tool structurally cannot see it. Two independent first passes with Playwright MCP concluded "no bug" and were wrong.
|
|
140
167
|
|
|
141
168
|
## Expectations
|
|
@@ -143,9 +170,10 @@ The sharper claim is not speed. In a real app it caught a **736–779 ms** windo
|
|
|
143
170
|
Honest limits, from six benchmark rounds against two production codebases (React Native Web; React + Vite + Radix):
|
|
144
171
|
|
|
145
172
|
- **If you already have a Playwright suite, keep using it.** Authoring a spec costs about what recording costs, and a spec is legible where an IR is not. This earns its keep for throwaway repros and agent loops, not as a test framework.
|
|
146
|
-
- **
|
|
173
|
+
- **You still have to get to the bug yourself.** Recording captures the observation; reaching the state it observes is your problem. `repro auto` from a bug description is not built.
|
|
147
174
|
- **A bug with no console error or failed request needs one hand-written line** — `assertion.expectedWhenFixed` — or `--expect-fixed` refuses to answer rather than return a green that checked nothing.
|
|
148
175
|
- **A flow that mutates server state is single-shot.** Use `--setup` to reset, or `{{random:name}}` placeholders to make inputs unique.
|
|
176
|
+
- **It refuses rather than guesses.** If a selector resolves to something that is not what was recorded — a list that gained a row, so a positional match landed on the wrong record — the run reports `COULD NOT VERIFY` instead of a verdict. A wrong answer you have no reason to doubt is worse than no answer.
|
|
149
177
|
- Top frame only. No iframes. Drag-and-drop and file upload are untested.
|
|
150
178
|
|
|
151
179
|
## Programmatic
|
|
@@ -162,7 +190,7 @@ The CLI and MCP server are both thin wrappers over these.
|
|
|
162
190
|
## Develop
|
|
163
191
|
|
|
164
192
|
```bash
|
|
165
|
-
npm test #
|
|
193
|
+
npm test # 141 tests, unit + real-browser integration
|
|
166
194
|
npm run stress # records once, replays 20x, fails on a single flake
|
|
167
195
|
npm run demo # examples/demo-app
|
|
168
196
|
```
|
package/dist/ir/schema.d.ts
CHANGED
|
@@ -25,6 +25,7 @@ export type Author = z.infer<typeof AuthorSchema>;
|
|
|
25
25
|
export declare const TargetSchema: z.ZodObject<{
|
|
26
26
|
candidates: z.ZodArray<z.ZodString>;
|
|
27
27
|
semantic: z.ZodString;
|
|
28
|
+
identity: z.ZodOptional<z.ZodString>;
|
|
28
29
|
}, z.core.$strip>;
|
|
29
30
|
export type Target = z.infer<typeof TargetSchema>;
|
|
30
31
|
export declare const NetworkWaitSchema: z.ZodObject<{
|
|
@@ -59,6 +60,7 @@ export declare const StepSchema: z.ZodObject<{
|
|
|
59
60
|
target: z.ZodOptional<z.ZodObject<{
|
|
60
61
|
candidates: z.ZodArray<z.ZodString>;
|
|
61
62
|
semantic: z.ZodString;
|
|
63
|
+
identity: z.ZodOptional<z.ZodString>;
|
|
62
64
|
}, z.core.$strip>>;
|
|
63
65
|
waitAfter: z.ZodObject<{
|
|
64
66
|
network: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -177,6 +179,7 @@ export declare const ReproSchema: z.ZodObject<{
|
|
|
177
179
|
target: z.ZodOptional<z.ZodObject<{
|
|
178
180
|
candidates: z.ZodArray<z.ZodString>;
|
|
179
181
|
semantic: z.ZodString;
|
|
182
|
+
identity: z.ZodOptional<z.ZodString>;
|
|
180
183
|
}, z.core.$strip>>;
|
|
181
184
|
waitAfter: z.ZodObject<{
|
|
182
185
|
network: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
package/dist/ir/schema.js
CHANGED
|
@@ -30,6 +30,18 @@ export const TargetSchema = z.object({
|
|
|
30
30
|
* failure messages, and as the re-grounding prompt for Phase 1 self-heal.
|
|
31
31
|
*/
|
|
32
32
|
semantic: z.string(),
|
|
33
|
+
/**
|
|
34
|
+
* The text that distinguishes this element from its siblings — an accessible
|
|
35
|
+
* name, its own label, or the row it sits in.
|
|
36
|
+
*
|
|
37
|
+
* `semantic` is prose for a human and is never checked, so nothing tied the
|
|
38
|
+
* action to what it meant. A positional selector that drifted one row matched
|
|
39
|
+
* a different person's row, the app opened a perfectly valid page for the
|
|
40
|
+
* wrong record, and the run reported a verdict on the bug. Confident and
|
|
41
|
+
* wrong is the one outcome this tool must not produce, so replay verifies
|
|
42
|
+
* this before acting and refuses rather than guesses.
|
|
43
|
+
*/
|
|
44
|
+
identity: z.string().optional(),
|
|
33
45
|
});
|
|
34
46
|
export const NetworkWaitSchema = z.object({
|
|
35
47
|
/** Recorded URL with volatile path/query IDs normalized to `*`. */
|
package/dist/ir/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/ir/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,mEAAmE;AACnE,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC;AAE5B,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,IAAI,CAAC;IACjC,OAAO;IACP,UAAU;IACV,MAAM;IACN,OAAO;IACP,QAAQ;IACR,MAAM;IACN,QAAQ;IACR,OAAO;CACR,CAAC,CAAC;AAGH;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;AAGvD,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,MAAM,CAAC;IACnC;;;;OAIG;IACH,UAAU,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7C;;;;OAIG;IACH,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/ir/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -29,5 +29,14 @@ export declare function buildCandidates(el: Element): string[];
|
|
|
29
29
|
* and is the re-grounding prompt for Phase 1 self-heal.
|
|
30
30
|
*/
|
|
31
31
|
export declare function semanticOf(el: Element): string;
|
|
32
|
+
/**
|
|
33
|
+
* The string that tells this element apart from its siblings.
|
|
34
|
+
*
|
|
35
|
+
* Checked at replay before acting, so a selector that drifts onto a different
|
|
36
|
+
* row is caught instead of being acted on. Prefers the element's own label,
|
|
37
|
+
* then falls back to the row it belongs to — which is what distinguishes one
|
|
38
|
+
* list entry from the next.
|
|
39
|
+
*/
|
|
40
|
+
export declare function identityOf(el: Element): string | undefined;
|
|
32
41
|
/** Null when the element has no addressable selector at all. */
|
|
33
42
|
export declare function describe(el: Element): CapturedTarget | null;
|
|
@@ -232,14 +232,17 @@ function interactiveHostSelectors(el) {
|
|
|
232
232
|
}
|
|
233
233
|
return out;
|
|
234
234
|
}
|
|
235
|
-
/**
|
|
235
|
+
/**
|
|
236
|
+
* Does this selector depend on sibling position to find its element?
|
|
237
|
+
*
|
|
238
|
+
* An anchor at the front does not redeem it. `[data-testid="ListRow"] > div >
|
|
239
|
+
* div:nth-of-type(2)` looks anchored, but the test id names the *list* and the
|
|
240
|
+
* index picks the row — so the whole selector turns on position, and one
|
|
241
|
+
* inserted row silently points it at somebody else. Any `:nth-of-type` at all
|
|
242
|
+
* means position is doing work that a text anchor would do by identity.
|
|
243
|
+
*/
|
|
236
244
|
function isPositionalOnly(selector) {
|
|
237
|
-
|
|
238
|
-
return false;
|
|
239
|
-
if (!selector.includes(':nth-of-type('))
|
|
240
|
-
return false;
|
|
241
|
-
// An attribute anchor or a surviving class name carries real identity.
|
|
242
|
-
return !selector.includes('[') && !selector.includes('.');
|
|
245
|
+
return Boolean(selector?.includes(':nth-of-type('));
|
|
243
246
|
}
|
|
244
247
|
/**
|
|
245
248
|
* The nearest identifiable ancestor, offered as a late fallback.
|
|
@@ -321,11 +324,53 @@ export function semanticOf(el) {
|
|
|
321
324
|
const head = name ? `${name} ${role}` : role;
|
|
322
325
|
return head + contextLabel(el);
|
|
323
326
|
}
|
|
327
|
+
/**
|
|
328
|
+
* The string that tells this element apart from its siblings.
|
|
329
|
+
*
|
|
330
|
+
* Checked at replay before acting, so a selector that drifts onto a different
|
|
331
|
+
* row is caught instead of being acted on. Prefers the element's own label,
|
|
332
|
+
* then falls back to the row it belongs to — which is what distinguishes one
|
|
333
|
+
* list entry from the next.
|
|
334
|
+
*/
|
|
335
|
+
export function identityOf(el) {
|
|
336
|
+
const own = accessibleName(el) || renderedText(el, 80);
|
|
337
|
+
// A label shared with other elements cannot tell one from another. "Remove"
|
|
338
|
+
// is the same on every row of a member list, so identity has to come from
|
|
339
|
+
// the row instead — which is precisely the case this check exists for.
|
|
340
|
+
if (own && countSharingLabel(own) <= 1)
|
|
341
|
+
return own;
|
|
342
|
+
const row = el.closest('tr, [role="row"], li, [role="listitem"], [data-testid*="row"], [data-testid*="Row"]');
|
|
343
|
+
if (row && row !== el) {
|
|
344
|
+
const rowText = renderedText(row, 80);
|
|
345
|
+
if (rowText)
|
|
346
|
+
return rowText;
|
|
347
|
+
}
|
|
348
|
+
return own || undefined;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* How many elements carry this same label.
|
|
352
|
+
*
|
|
353
|
+
* Compares `textContent` rather than `innerText`: this runs over every element
|
|
354
|
+
* on the page, and `innerText` forces layout on each one.
|
|
355
|
+
*/
|
|
356
|
+
function countSharingLabel(label) {
|
|
357
|
+
const wanted = label.replace(/\s+/g, ' ').trim();
|
|
358
|
+
let count = 0;
|
|
359
|
+
for (const el of allElements()) {
|
|
360
|
+
const text = (el.textContent ?? '').replace(/\s+/g, ' ').trim();
|
|
361
|
+
if (text === wanted && ++count > 1)
|
|
362
|
+
return count;
|
|
363
|
+
if (el.getAttribute('aria-label')?.trim() === wanted && ++count > 1)
|
|
364
|
+
return count;
|
|
365
|
+
}
|
|
366
|
+
return count;
|
|
367
|
+
}
|
|
324
368
|
/** Null when the element has no addressable selector at all. */
|
|
325
369
|
export function describe(el) {
|
|
326
370
|
const candidates = buildCandidates(el);
|
|
327
371
|
if (!candidates.length)
|
|
328
372
|
return null;
|
|
329
|
-
|
|
373
|
+
const identity = identityOf(el);
|
|
374
|
+
return { candidates, semantic: semanticOf(el), ...(identity ? { identity } : {}) };
|
|
330
375
|
}
|
|
331
376
|
//# sourceMappingURL=selectors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"selectors.js","sourceRoot":"","sources":["../../../src/recorder/agent/selectors.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"selectors.js","sourceRoot":"","sources":["../../../src/recorder/agent/selectors.ts"],"names":[],"mappings":"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"}
|
|
@@ -27,6 +27,10 @@ export function isStableToken(t) {
|
|
|
27
27
|
return false;
|
|
28
28
|
if (/^(css|sc|emotion|styled|jsx|glamor|makeStyles)-/i.test(t))
|
|
29
29
|
return false;
|
|
30
|
+
// React Native Web namespaces every generated atomic class under `r-`, and
|
|
31
|
+
// the readable middle of `r-backgroundColor-xmbkpo` hides a hash on the end.
|
|
32
|
+
if (/^r-/.test(t))
|
|
33
|
+
return false;
|
|
30
34
|
if (/[0-9a-f]{6,}/i.test(t))
|
|
31
35
|
return false; // embedded hash
|
|
32
36
|
if ((t.match(/\d/g) || []).length >= 3)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../../src/recorder/agent/text.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../../src/recorder/agent/text.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** The in-page capture agent, bundled as a standalone IIFE. */
|
|
2
|
-
export declare const AGENT_BUNDLE = "\"use strict\";\n(() => {\n // src/recorder/agent/config.ts\n var INSTALL_GLOBAL = \"__replayInstall\";\n var AGENT_READY_FLAG = \"__replayAgentReady\";\n var FLUSH_GLOBAL = \"__replayFlush\";\n\n // src/recorder/agent/text.ts\n function clean(s, max = 80) {\n if (!s) return \"\";\n const t = s.replace(/\\s+/g, \" \").trim();\n return t.length > max ? `${t.slice(0, max - 1)}\\u2026` : t;\n }\n function escAttr(v) {\n return v.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n }\n function escId(v) {\n return typeof window.CSS?.escape === \"function\" ? window.CSS.escape(v) : v.replace(/([^\\w-])/g, \"\\\\$1\");\n }\n function isStableToken(t) {\n if (!t || t.length > 40) return false;\n if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(t)) return false;\n if (/^(css|sc|emotion|styled|jsx|glamor|makeStyles)-/i.test(t)) return false;\n if (/[0-9a-f]{6,}/i.test(t)) return false;\n if ((t.match(/\\d/g) || []).length >= 3) return false;\n if (/[A-Z]/.test(t) && /\\d/.test(t)) return false;\n if (/^[a-z]{1,2}-[a-z0-9]{5,}$/i.test(t) && /\\d/.test(t)) return false;\n if (t.split(/[-_]/).some(looksGenerated)) return false;\n if (/-(aria|diff|live|announcer|portal)$/i.test(t)) return false;\n return true;\n }\n function looksGenerated(segment) {\n if (segment.length < 6) return false;\n if (!/^[a-z0-9]+$/i.test(segment)) return false;\n const vowels = (segment.match(/[aeiouy]/gi) || []).length;\n return /\\d/.test(segment) ? vowels <= 1 : vowels === 0;\n }\n function isStableClass(c) {\n return isStableToken(c) && !/^_/.test(c);\n }\n function renderedText(el, max = 80) {\n const inner = el.innerText;\n return clean(typeof inner === \"string\" ? inner : el.textContent, max);\n }\n\n // src/recorder/agent/roles.ts\n var TAG_ROLES = {\n button: \"button\",\n select: \"combobox\",\n textarea: \"textbox\",\n nav: \"navigation\",\n main: \"main\",\n header: \"banner\",\n footer: \"contentinfo\",\n aside: \"complementary\",\n form: \"form\",\n table: \"table\",\n tr: \"row\",\n td: \"cell\",\n th: \"columnheader\",\n ul: \"list\",\n ol: \"list\",\n li: \"listitem\",\n dialog: \"dialog\",\n option: \"option\",\n h1: \"heading\",\n h2: \"heading\",\n h3: \"heading\",\n h4: \"heading\",\n h5: \"heading\",\n h6: \"heading\"\n };\n var INPUT_ROLES = {\n button: \"button\",\n submit: \"button\",\n reset: \"button\",\n image: \"button\",\n checkbox: \"checkbox\",\n radio: \"radio\",\n range: \"slider\",\n number: \"spinbutton\",\n search: \"searchbox\",\n email: \"textbox\",\n tel: \"textbox\",\n text: \"textbox\",\n url: \"textbox\"\n };\n var NAME_FROM_CONTENT = [\n \"button\",\n \"link\",\n \"heading\",\n \"cell\",\n \"columnheader\",\n \"rowheader\",\n \"listitem\",\n \"option\",\n \"tab\",\n \"menuitem\",\n \"menuitemcheckbox\",\n \"menuitemradio\",\n \"treeitem\",\n \"switch\",\n \"checkbox\",\n \"radio\"\n ];\n var NON_EDITABLE_INPUTS = [\"checkbox\", \"radio\", \"button\", \"submit\", \"reset\", \"file\", \"image\"];\n function getRole(el) {\n const explicit = el.getAttribute(\"role\");\n if (explicit) return explicit.trim().split(/\\s+/)[0] || null;\n const tag = el.tagName.toLowerCase();\n if (tag === \"a\") return el.hasAttribute(\"href\") ? \"link\" : null;\n if (tag === \"img\") return el.getAttribute(\"alt\") === \"\" ? null : \"img\";\n if (tag === \"input\") {\n const type = (el.getAttribute(\"type\") || \"text\").toLowerCase();\n return INPUT_ROLES[type] ?? null;\n }\n return TAG_ROLES[tag] ?? null;\n }\n function isEditable(el) {\n if (!el || el.nodeType !== 1) return false;\n const tag = el.tagName.toLowerCase();\n if (tag === \"textarea\") return true;\n if (el.isContentEditable) return true;\n if (tag !== \"input\") return false;\n const type = (el.getAttribute(\"type\") || \"text\").toLowerCase();\n return !NON_EDITABLE_INPUTS.includes(type);\n }\n function accessibleName(el) {\n const aria = el.getAttribute(\"aria-label\");\n if (aria && aria.trim()) return clean(aria);\n const labelledby = el.getAttribute(\"aria-labelledby\");\n if (labelledby) {\n const parts = labelledby.split(/\\s+/).map((id) => document.getElementById(id)).filter((n) => !!n).map((n) => clean(n.textContent));\n const joined = clean(parts.filter(Boolean).join(\" \"));\n if (joined) return joined;\n }\n const tag = el.tagName.toLowerCase();\n if ([\"input\", \"select\", \"textarea\"].includes(tag)) {\n const id = el.getAttribute(\"id\");\n if (id) {\n const forLabel = document.querySelector(`label[for=\"${escAttr(id)}\"]`);\n if (forLabel) {\n const t = clean(forLabel.textContent);\n if (t) return t;\n }\n }\n const wrapping = el.closest(\"label\");\n if (wrapping) {\n const t = clean(wrapping.textContent);\n if (t) return t;\n }\n }\n for (const attr of [\"alt\", \"title\", \"placeholder\"]) {\n const v = el.getAttribute(attr);\n if (v && v.trim()) return clean(v);\n }\n const role = getRole(el);\n if (role && NAME_FROM_CONTENT.includes(role)) {\n const t = clean(el.textContent);\n if (t) return t;\n }\n return \"\";\n }\n function ownText(el) {\n return clean(el.textContent, 60);\n }\n\n // src/recorder/agent/selectors.ts\n var TEST_ID_ATTRS = [\n \"data-testid\",\n \"data-test\",\n \"data-test-id\",\n \"data-cy\",\n \"data-sentry-label\",\n \"data-testid-label\"\n ];\n var MAX_CANDIDATES = 6;\n var INTERACTIVE = 'button, a[href], [role=\"button\"], [role=\"link\"], [role=\"menuitem\"], [role=\"menuitemradio\"], [role=\"option\"], [role=\"tab\"], [role=\"checkbox\"], [role=\"radio\"], [role=\"switch\"], [tabindex], [data-focusable=\"true\"], [onclick]';\n var MAX_CSS_PATH_DEPTH = 6;\n function testIdSelector(el) {\n for (const attr of TEST_ID_ATTRS) {\n const v = el.getAttribute(attr);\n if (v) return `[${attr}=\"${escAttr(v)}\"]`;\n }\n return null;\n }\n function idSelector(el) {\n const id = el.getAttribute(\"id\");\n return id && isStableToken(id) ? `#${escId(id)}` : null;\n }\n function roleNameSelector(el) {\n const role = getRole(el);\n if (!role) return null;\n const name = accessibleName(el);\n if (!name) return null;\n return `role=${role}[name=\"${escAttr(name)}\"]`;\n }\n function appearedSelector(el) {\n return testIdSelector(el) ?? idSelector(el) ?? roleNameSelector(el);\n }\n function goneSelector(el) {\n return testIdSelector(el) ?? idSelector(el);\n }\n function cssSelectorFor(el) {\n return testIdSelector(el) ?? idSelector(el) ?? buildCssPath(el);\n }\n function allElements() {\n return Array.from(document.querySelectorAll(\"*\"));\n }\n function withNth(base, el, matches) {\n if (matches.length <= 1) return base;\n const idx = matches.indexOf(el);\n return idx < 0 ? base : `${base} >> nth=${idx}`;\n }\n function buildCssPath(el) {\n const segs = [];\n let cur = el;\n let depth = 0;\n while (cur && cur.nodeType === 1 && cur !== document.documentElement && depth < MAX_CSS_PATH_DEPTH) {\n const node = cur;\n if (depth > 0) {\n const anchor = testIdSelector(node) ?? idSelector(node);\n if (anchor) {\n segs.unshift(anchor);\n break;\n }\n }\n let seg = node.tagName.toLowerCase();\n const classes = Array.from(node.classList).filter(isStableClass).slice(0, 2);\n if (classes.length) seg += `.${classes.map(escId).join(\".\")}`;\n const parent = node.parentElement;\n if (parent) {\n const sameTag = Array.from(parent.children).filter((c) => c.tagName === node.tagName);\n if (sameTag.length > 1) seg += `:nth-of-type(${sameTag.indexOf(node) + 1})`;\n }\n segs.unshift(seg);\n const partial = segs.join(\" > \");\n try {\n if (document.querySelectorAll(partial).length === 1) return partial;\n } catch {\n return null;\n }\n cur = parent;\n depth++;\n }\n if (!segs.length) return null;\n const sel = segs.join(\" > \");\n try {\n return document.querySelectorAll(sel).length ? sel : null;\n } catch {\n return null;\n }\n }\n function buildCandidates(el) {\n const out = [];\n const push = (s) => {\n if (s && out.indexOf(s) === -1) out.push(s);\n };\n push(testIdSelector(el));\n push(idSelector(el));\n const nameAttr = el.getAttribute(\"name\");\n if (nameAttr && isStableToken(nameAttr)) {\n push(`${el.tagName.toLowerCase()}[name=\"${escAttr(nameAttr)}\"]`);\n }\n const roleName = roleNameSelector(el);\n if (roleName) {\n const role = getRole(el);\n const name = accessibleName(el);\n const matches = allElements().filter((c) => getRole(c) === role && accessibleName(c) === name);\n push(withNth(roleName, el, matches));\n }\n for (const selector of interactiveHostSelectors(el)) push(selector);\n push(labelledAncestorSelector(el));\n const cssPath = buildCssPath(el);\n const text = ownText(el);\n const textSelector = text && isSmallestWithText(el, text) ? withNth(`text=\"${escAttr(text)}\"`, el, allElements().filter((c) => isSmallestWithText(c, text))) : null;\n if (isPositionalOnly(cssPath)) {\n push(textSelector);\n push(cssPath);\n } else {\n push(cssPath);\n push(textSelector);\n }\n return out.slice(0, MAX_CANDIDATES);\n }\n function interactiveHostSelectors(el) {\n let host = null;\n try {\n const found = el.closest(INTERACTIVE);\n host = found && found !== el ? found : null;\n } catch {\n host = null;\n }\n if (!host) return [];\n const out = [];\n const push = (s) => {\n if (s && out.indexOf(s) === -1) out.push(s);\n };\n push(testIdSelector(host));\n push(idSelector(host));\n push(roleNameSelector(host));\n const label = renderedText(host, 60);\n if (label) {\n const tag = host.tagName.toLowerCase();\n const role = host.getAttribute(\"role\");\n const qualifier = host.getAttribute(\"data-focusable\") ? '[data-focusable=\"true\"]' : role ? `[role=\"${escAttr(role)}\"]` : host.hasAttribute(\"tabindex\") ? `[tabindex=\"${escAttr(host.getAttribute(\"tabindex\") ?? \"0\")}\"]` : \"\";\n if (qualifier) push(`${tag}${qualifier}:has-text(\"${escAttr(label)}\")`);\n }\n return out;\n }\n function isPositionalOnly(selector) {\n if (!selector) return false;\n if (!selector.includes(\":nth-of-type(\")) return false;\n return !selector.includes(\"[\") && !selector.includes(\".\");\n }\n function labelledAncestorSelector(el) {\n if (testIdSelector(el) ?? idSelector(el)) return null;\n let cur = el.parentElement;\n for (let depth = 0; cur && depth < MAX_CSS_PATH_DEPTH; depth++) {\n const anchor = testIdSelector(cur);\n if (anchor) {\n try {\n return document.querySelectorAll(anchor).length === 1 ? anchor : null;\n } catch {\n return null;\n }\n }\n cur = cur.parentElement;\n }\n return null;\n }\n function isSmallestWithText(el, text) {\n if (ownText(el) !== text) return false;\n return !Array.from(el.children).some((child) => ownText(child) === text);\n }\n function contextLabel(el) {\n const row = el.closest('tr, [role=\"row\"], li, [role=\"listitem\"], [data-testid*=\"row\"]');\n if (row && row !== el) {\n const own = renderedText(el, 60);\n const full = renderedText(row, 120);\n const t = clean(own ? full.split(own).join(\" \") : full, 60);\n if (t) return ` in the row containing \"${t}\"`;\n }\n const section = el.closest('form, section, dialog, [role=\"dialog\"], nav, main, aside');\n if (section && section !== el) {\n const label = section.getAttribute(\"aria-label\") || clean(section.querySelector(\"h1, h2, h3, h4, legend\")?.textContent) || \"\";\n if (label) return ` in the ${section.tagName.toLowerCase()} labelled \"${clean(label, 40)}\"`;\n }\n return \"\";\n }\n function semanticOf(el) {\n const role = getRole(el) || el.tagName.toLowerCase();\n const name = accessibleName(el) || ownText(el);\n const head = name ? `${name} ${role}` : role;\n return head + contextLabel(el);\n }\n function describe(el) {\n const candidates = buildCandidates(el);\n if (!candidates.length) return null;\n return { candidates, semantic: semanticOf(el) };\n }\n\n // src/recorder/agent/capture.ts\n var ECHO_WINDOW_MS = 30;\n var GESTURE_WINDOW_MS = 1e3;\n var FOCUS_SETTLE_MS = 120;\n var MEANINGFUL_KEYS = [\n \"Enter\",\n \"Escape\",\n \"Tab\",\n \"ArrowUp\",\n \"ArrowDown\",\n \"ArrowLeft\",\n \"ArrowRight\",\n \"Backspace\",\n \"Delete\",\n \"Home\",\n \"End\",\n \"PageUp\",\n \"PageDown\",\n \" \"\n ];\n function targetOf(e) {\n const t = e.target;\n return t && t.nodeType === 1 ? t : null;\n }\n function playwrightKey(e) {\n const mods = [];\n if (e.ctrlKey) mods.push(\"Control\");\n if (e.altKey) mods.push(\"Alt\");\n if (e.metaKey) mods.push(\"Meta\");\n if (e.shiftKey && e.key.length > 1) mods.push(\"Shift\");\n const key = e.key === \" \" ? \"Space\" : e.key;\n return [...mods, key].join(\"+\");\n }\n function isStopHotkey(e) {\n return (e.ctrlKey || e.metaKey) && e.shiftKey && e.key.toLowerCase() === \"x\";\n }\n function installCapture(ctx) {\n const { config, transport, reveals } = ctx;\n const focusValue = /* @__PURE__ */ new WeakMap();\n const committed = /* @__PURE__ */ new WeakMap();\n let lastRecorded = null;\n let lastPointerDown = null;\n function resolveGestureTarget(clicked) {\n const pd = lastPointerDown;\n if (!pd || pd.el === clicked) return clicked;\n if (Date.now() - pd.t > GESTURE_WINDOW_MS) return clicked;\n const retargeted = clicked === document.documentElement || clicked === document.body;\n if (retargeted && pd.el.isConnected && describe(pd.el)) return pd.el;\n if (!describe(clicked) && pd.el.isConnected && describe(pd.el)) return pd.el;\n return clicked;\n }\n function isEchoOfRecordedClick(el) {\n const prev = lastRecorded;\n if (!prev) return false;\n if (Date.now() - prev.t > ECHO_WINDOW_MS) return false;\n if (prev.el === el) return true;\n if (prev.el.contains(el) || el.contains(prev.el)) return true;\n const label = el.closest(\"label\");\n return Boolean(label && label === prev.el.closest(\"label\"));\n }\n function emitAction(action, el, value) {\n ctx.beforeAction?.();\n const target = el ? describe(el) : null;\n if (el && !target) return false;\n const t = Date.now();\n reveals.noteAction(t);\n const ev = { kind: \"action\", action, value, target, t, author: \"human\" };\n transport.emit(ev);\n return true;\n }\n let focusTimer = null;\n let lastFocus = null;\n function noteFocusChange() {\n if (focusTimer) clearTimeout(focusTimer);\n focusTimer = setTimeout(() => {\n const el = document.activeElement;\n const selector = el ? cssSelectorFor(el) : null;\n if (!selector || selector === lastFocus) return;\n lastFocus = selector;\n transport.emit({ kind: \"focus\", selector, t: Date.now() });\n }, FOCUS_SETTLE_MS);\n }\n function flushRevealingHover(actionTarget) {\n const hovered = reveals.takeLoadBearingHover(actionTarget);\n if (hovered) emitAction(\"hover\", hovered, null);\n }\n function valueOf(el) {\n if (el.isContentEditable) return clean(el.innerText, 500);\n return el.value ?? \"\";\n }\n function commitFill(el) {\n if (!isEditable(el)) return;\n const value = valueOf(el);\n if (committed.get(el) === value) return;\n if (focusValue.get(el) === value && committed.get(el) === void 0) return;\n committed.set(el, value);\n flushRevealingHover(el);\n emitAction(\"fill\", el, value);\n }\n function flushPendingFill() {\n const active = document.activeElement;\n if (active && isEditable(active)) commitFill(active);\n }\n const on = (type, handler) => {\n document.addEventListener(type, handler, true);\n };\n on(\"focusin\", (e) => {\n const el = targetOf(e);\n if (el && isEditable(el)) focusValue.set(el, valueOf(el));\n noteFocusChange();\n });\n on(\"focusout\", () => noteFocusChange());\n on(\"mouseover\", (e) => {\n const el = targetOf(e);\n if (el) reveals.noteHover(el);\n });\n on(\"pointerdown\", (e) => {\n const el = targetOf(e);\n if (el) lastPointerDown = { el, t: Date.now() };\n });\n on(\"click\", (e) => {\n const clicked = targetOf(e);\n if (!clicked) return;\n const el = resolveGestureTarget(clicked);\n if (isEchoOfRecordedClick(el)) return;\n flushPendingFill();\n flushRevealingHover(el);\n if (emitAction(\"click\", el, null)) lastRecorded = { el, t: Date.now() };\n });\n on(\"dblclick\", (e) => {\n const el = targetOf(e);\n if (!el) return;\n flushPendingFill();\n emitAction(\"dblclick\", el, null);\n });\n on(\"change\", (e) => {\n const el = targetOf(e);\n if (!el) return;\n if (el.tagName.toLowerCase() === \"select\") {\n const sel = el;\n const opt = sel.selectedOptions[0];\n flushPendingFill();\n flushRevealingHover(el);\n emitAction(\"select\", el, opt ? opt.value || clean(opt.textContent) : sel.value);\n return;\n }\n if (isEditable(el)) commitFill(el);\n });\n on(\"blur\", (e) => {\n const el = targetOf(e);\n if (el && isEditable(el)) commitFill(el);\n });\n on(\"keydown\", (e) => {\n if (isStopHotkey(e)) {\n e.preventDefault();\n e.stopPropagation();\n transport.binding(config.stopBinding)?.({ reason: \"hotkey\" });\n return;\n }\n const el = targetOf(e);\n if (isEditable(el)) {\n if (e.key !== \"Enter\" && e.key !== \"Escape\") return;\n commitFill(el);\n } else if (!MEANINGFUL_KEYS.includes(e.key) && !(e.ctrlKey || e.metaKey || e.altKey)) {\n return;\n } else {\n flushPendingFill();\n }\n emitAction(\"press\", el, playwrightKey(e));\n });\n installScrollCapture(ctx, emitAction);\n }\n var RESIZE_PROBE = [\n \".erd_scroll_detection_container\",\n \".resize-sensor\",\n \".resize-triggers\",\n \"[data-resize-sensor]\"\n ];\n function isResizeProbe(el) {\n if (!el) return false;\n return RESIZE_PROBE.some((sel) => {\n try {\n return el.matches(sel) || el.closest(sel) !== null;\n } catch {\n return false;\n }\n });\n }\n function installScrollCapture(ctx, emitAction) {\n const { config } = ctx;\n const lastPosition = /* @__PURE__ */ new WeakMap();\n const timers = /* @__PURE__ */ new WeakMap();\n document.addEventListener(\n \"scroll\",\n (e) => {\n const raw = e.target;\n if (raw && raw.nodeType === 1 && isResizeProbe(raw)) return;\n const isDocument = !raw || raw === document || raw === document.documentElement || raw === document.body;\n const key = isDocument ? document : raw;\n const el = isDocument ? null : raw;\n const x = el ? el.scrollLeft : window.scrollX;\n const y = el ? el.scrollTop : window.scrollY;\n const existing = timers.get(key);\n if (existing) clearTimeout(existing);\n timers.set(\n key,\n setTimeout(() => {\n const last = lastPosition.get(key) ?? { x: 0, y: 0 };\n const moved = Math.abs(x - last.x) >= config.scrollMinDeltaPx || Math.abs(y - last.y) >= config.scrollMinDeltaPx;\n if (!moved) return;\n lastPosition.set(key, { x, y });\n emitAction(\"scroll\", el, JSON.stringify({ x, y }));\n }, config.scrollDebounceMs)\n );\n },\n true\n );\n }\n\n // src/noise.ts\n var TRANSIENT_NAME = /\\b(loading|spinner|progress|skeleton|please wait|submitting|saving)\\b/i;\n function isTransientIndicator(role, name) {\n if (role === \"progressbar\") return true;\n return TRANSIENT_NAME.test(name);\n }\n\n // src/recorder/agent/visibility.ts\n function isVisible(el) {\n if (!el.isConnected) return false;\n const he = el;\n if (he.hidden || el.getAttribute(\"aria-hidden\") === \"true\") return false;\n const rect = he.getBoundingClientRect();\n if (rect.width === 0 && rect.height === 0) return false;\n const cs = window.getComputedStyle(he);\n return cs.visibility !== \"hidden\" && cs.display !== \"none\" && cs.opacity !== \"0\";\n }\n\n // src/recorder/agent/dom-reaction.ts\n var INTERESTING = \"[data-testid], [data-test], [data-test-id], [data-cy], [id], [role], button, a[href]\";\n var OBSERVED_ATTRS = [\"class\", \"style\", \"hidden\", \"aria-hidden\"];\n var APPEAR_CONFIRM_MS = 600;\n function toCssSelector(selector) {\n if (selector.startsWith(\"role=\") || selector.startsWith(\"text=\")) {\n throw new Error(\"not a CSS selector\");\n }\n return selector;\n }\n function harvest(nodes, into, pick, revealed, max) {\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n if (!node || node.nodeType !== 1) continue;\n const el = node;\n revealed.push(el);\n const own = pick(el);\n if (own && into.size < max) into.add(own);\n const descendants = el.querySelectorAll(INTERESTING);\n for (let j = 0; j < descendants.length && into.size < max; j++) {\n const d = descendants[j];\n if (!d) continue;\n const sel = pick(d);\n if (sel) into.add(sel);\n }\n }\n }\n function observeDomReactions(ctx) {\n const { config, transport, reveals } = ctx;\n const visibility = /* @__PURE__ */ new WeakMap();\n let pending = [];\n const stillVisible = (sel) => {\n try {\n const el = document.querySelector(toCssSelector(sel));\n return el ? isVisible(el) : false;\n } catch {\n return true;\n }\n };\n const confirm = (entry) => {\n const survived = entry.selectors.filter(stillVisible);\n if (survived.length) {\n transport.emit({ kind: \"dom\", appeared: survived, gone: [], t: entry.at });\n }\n };\n const flushAppearances = () => {\n const due = pending;\n pending = [];\n for (const entry of due) {\n clearTimeout(entry.timer);\n confirm(entry);\n }\n };\n const visibleAppearedSelector = (el) => {\n if (!isVisible(el)) return null;\n if (isTransientIndicator(getRole(el), accessibleName(el))) return null;\n return appearedSelector(el);\n };\n const start = () => {\n const observer = new MutationObserver((records) => {\n const appeared = /* @__PURE__ */ new Set();\n const gone = /* @__PURE__ */ new Set();\n const revealed = [];\n for (const rec of records) {\n if (rec.type === \"childList\") {\n harvest(rec.addedNodes, appeared, visibleAppearedSelector, revealed, config.maxSelectorsPerMutation);\n harvest(rec.removedNodes, gone, goneSelector, [], config.maxSelectorsPerMutation);\n continue;\n }\n const el = rec.target;\n const sel = appearedSelector(el);\n if (!sel) continue;\n const now = isVisible(el);\n const was = visibility.get(el);\n visibility.set(el, now);\n if (was === void 0 || was === now) continue;\n if (now) {\n appeared.add(sel);\n revealed.push(el);\n } else {\n const g = goneSelector(el);\n if (g) gone.add(g);\n }\n }\n const at = Date.now();\n reveals.noteRevealed(revealed, at);\n if (gone.size) {\n transport.emit({ kind: \"dom\", appeared: [], gone: Array.from(gone), t: at });\n }\n if (appeared.size) {\n const entry = {\n selectors: Array.from(appeared),\n at,\n timer: setTimeout(() => {\n pending = pending.filter((e) => e !== entry);\n confirm(entry);\n }, APPEAR_CONFIRM_MS)\n };\n pending.push(entry);\n }\n });\n observer.observe(document.documentElement, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: OBSERVED_ATTRS\n });\n };\n if (document.documentElement) start();\n else document.addEventListener(\"DOMContentLoaded\", start, { once: true });\n return { flushAppearances };\n }\n\n // src/recorder/agent/reveal-tracker.ts\n var ACTION_COOLDOWN_MS = 600;\n function createRevealTracker(config) {\n let pending = null;\n let lastHovered = null;\n let lastActionAt = 0;\n return {\n noteHover(el) {\n lastHovered = el;\n },\n noteAction(at) {\n lastActionAt = at;\n },\n noteRevealed(nodes, at) {\n if (!nodes.length || !lastHovered) return;\n if (at - lastActionAt <= ACTION_COOLDOWN_MS) return;\n pending = { el: lastHovered, nodes, at };\n },\n takeLoadBearingHover(actionTarget) {\n const reveal = pending;\n pending = null;\n if (!reveal || !actionTarget) return null;\n if (Date.now() - reveal.at > config.hoverRevealWindowMs) return null;\n if (!reveal.el.isConnected) return null;\n const inside = reveal.nodes.some((n) => n === actionTarget || n.contains(actionTarget));\n return inside ? reveal.el : null;\n }\n };\n }\n\n // src/recorder/agent/transport.ts\n var DRAIN_INTERVAL_MS = 25;\n function createTransport(config) {\n const globals = window;\n const pending = [];\n let drainTimer = null;\n function binding(name) {\n const fn = globals[name];\n return typeof fn === \"function\" ? fn : null;\n }\n function drain() {\n const fn = binding(config.emitBinding);\n if (!fn) return;\n while (pending.length) {\n const ev = pending.shift();\n try {\n fn(ev);\n } catch {\n }\n }\n if (drainTimer) {\n clearInterval(drainTimer);\n drainTimer = null;\n }\n }\n function emit(ev) {\n pending.push(ev);\n if (binding(config.emitBinding)) drain();\n else if (!drainTimer) drainTimer = setInterval(drain, DRAIN_INTERVAL_MS);\n }\n return { emit, binding };\n }\n\n // src/recorder/agent/page-agent.ts\n var INSTALLED_FLAG = \"__replayAgentInstalled\";\n function pageAgent(config) {\n const globals = window;\n if (globals[INSTALLED_FLAG]) return;\n if (window.top !== window) return;\n globals[INSTALLED_FLAG] = true;\n const transport = createTransport(config);\n const reveals = createRevealTracker(config);\n const dom = observeDomReactions({ config, transport, reveals });\n installCapture({ config, transport, reveals, beforeAction: () => dom.flushAppearances() });\n globals[FLUSH_GLOBAL] = () => dom.flushAppearances();\n globals[AGENT_READY_FLAG] = true;\n }\n\n // src/recorder/agent/main.ts\n window[INSTALL_GLOBAL] = (config) => {\n pageAgent(config);\n };\n})();\n";
|
|
2
|
+
export declare const AGENT_BUNDLE = "\"use strict\";\n(() => {\n // src/recorder/agent/config.ts\n var INSTALL_GLOBAL = \"__replayInstall\";\n var AGENT_READY_FLAG = \"__replayAgentReady\";\n var FLUSH_GLOBAL = \"__replayFlush\";\n\n // src/recorder/agent/text.ts\n function clean(s, max = 80) {\n if (!s) return \"\";\n const t = s.replace(/\\s+/g, \" \").trim();\n return t.length > max ? `${t.slice(0, max - 1)}\\u2026` : t;\n }\n function escAttr(v) {\n return v.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n }\n function escId(v) {\n return typeof window.CSS?.escape === \"function\" ? window.CSS.escape(v) : v.replace(/([^\\w-])/g, \"\\\\$1\");\n }\n function isStableToken(t) {\n if (!t || t.length > 40) return false;\n if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(t)) return false;\n if (/^(css|sc|emotion|styled|jsx|glamor|makeStyles)-/i.test(t)) return false;\n if (/^r-/.test(t)) return false;\n if (/[0-9a-f]{6,}/i.test(t)) return false;\n if ((t.match(/\\d/g) || []).length >= 3) return false;\n if (/[A-Z]/.test(t) && /\\d/.test(t)) return false;\n if (/^[a-z]{1,2}-[a-z0-9]{5,}$/i.test(t) && /\\d/.test(t)) return false;\n if (t.split(/[-_]/).some(looksGenerated)) return false;\n if (/-(aria|diff|live|announcer|portal)$/i.test(t)) return false;\n return true;\n }\n function looksGenerated(segment) {\n if (segment.length < 6) return false;\n if (!/^[a-z0-9]+$/i.test(segment)) return false;\n const vowels = (segment.match(/[aeiouy]/gi) || []).length;\n return /\\d/.test(segment) ? vowels <= 1 : vowels === 0;\n }\n function isStableClass(c) {\n return isStableToken(c) && !/^_/.test(c);\n }\n function renderedText(el, max = 80) {\n const inner = el.innerText;\n return clean(typeof inner === \"string\" ? inner : el.textContent, max);\n }\n\n // src/recorder/agent/roles.ts\n var TAG_ROLES = {\n button: \"button\",\n select: \"combobox\",\n textarea: \"textbox\",\n nav: \"navigation\",\n main: \"main\",\n header: \"banner\",\n footer: \"contentinfo\",\n aside: \"complementary\",\n form: \"form\",\n table: \"table\",\n tr: \"row\",\n td: \"cell\",\n th: \"columnheader\",\n ul: \"list\",\n ol: \"list\",\n li: \"listitem\",\n dialog: \"dialog\",\n option: \"option\",\n h1: \"heading\",\n h2: \"heading\",\n h3: \"heading\",\n h4: \"heading\",\n h5: \"heading\",\n h6: \"heading\"\n };\n var INPUT_ROLES = {\n button: \"button\",\n submit: \"button\",\n reset: \"button\",\n image: \"button\",\n checkbox: \"checkbox\",\n radio: \"radio\",\n range: \"slider\",\n number: \"spinbutton\",\n search: \"searchbox\",\n email: \"textbox\",\n tel: \"textbox\",\n text: \"textbox\",\n url: \"textbox\"\n };\n var NAME_FROM_CONTENT = [\n \"button\",\n \"link\",\n \"heading\",\n \"cell\",\n \"columnheader\",\n \"rowheader\",\n \"listitem\",\n \"option\",\n \"tab\",\n \"menuitem\",\n \"menuitemcheckbox\",\n \"menuitemradio\",\n \"treeitem\",\n \"switch\",\n \"checkbox\",\n \"radio\"\n ];\n var NON_EDITABLE_INPUTS = [\"checkbox\", \"radio\", \"button\", \"submit\", \"reset\", \"file\", \"image\"];\n function getRole(el) {\n const explicit = el.getAttribute(\"role\");\n if (explicit) return explicit.trim().split(/\\s+/)[0] || null;\n const tag = el.tagName.toLowerCase();\n if (tag === \"a\") return el.hasAttribute(\"href\") ? \"link\" : null;\n if (tag === \"img\") return el.getAttribute(\"alt\") === \"\" ? null : \"img\";\n if (tag === \"input\") {\n const type = (el.getAttribute(\"type\") || \"text\").toLowerCase();\n return INPUT_ROLES[type] ?? null;\n }\n return TAG_ROLES[tag] ?? null;\n }\n function isEditable(el) {\n if (!el || el.nodeType !== 1) return false;\n const tag = el.tagName.toLowerCase();\n if (tag === \"textarea\") return true;\n if (el.isContentEditable) return true;\n if (tag !== \"input\") return false;\n const type = (el.getAttribute(\"type\") || \"text\").toLowerCase();\n return !NON_EDITABLE_INPUTS.includes(type);\n }\n function accessibleName(el) {\n const aria = el.getAttribute(\"aria-label\");\n if (aria && aria.trim()) return clean(aria);\n const labelledby = el.getAttribute(\"aria-labelledby\");\n if (labelledby) {\n const parts = labelledby.split(/\\s+/).map((id) => document.getElementById(id)).filter((n) => !!n).map((n) => clean(n.textContent));\n const joined = clean(parts.filter(Boolean).join(\" \"));\n if (joined) return joined;\n }\n const tag = el.tagName.toLowerCase();\n if ([\"input\", \"select\", \"textarea\"].includes(tag)) {\n const id = el.getAttribute(\"id\");\n if (id) {\n const forLabel = document.querySelector(`label[for=\"${escAttr(id)}\"]`);\n if (forLabel) {\n const t = clean(forLabel.textContent);\n if (t) return t;\n }\n }\n const wrapping = el.closest(\"label\");\n if (wrapping) {\n const t = clean(wrapping.textContent);\n if (t) return t;\n }\n }\n for (const attr of [\"alt\", \"title\", \"placeholder\"]) {\n const v = el.getAttribute(attr);\n if (v && v.trim()) return clean(v);\n }\n const role = getRole(el);\n if (role && NAME_FROM_CONTENT.includes(role)) {\n const t = clean(el.textContent);\n if (t) return t;\n }\n return \"\";\n }\n function ownText(el) {\n return clean(el.textContent, 60);\n }\n\n // src/recorder/agent/selectors.ts\n var TEST_ID_ATTRS = [\n \"data-testid\",\n \"data-test\",\n \"data-test-id\",\n \"data-cy\",\n \"data-sentry-label\",\n \"data-testid-label\"\n ];\n var MAX_CANDIDATES = 6;\n var INTERACTIVE = 'button, a[href], [role=\"button\"], [role=\"link\"], [role=\"menuitem\"], [role=\"menuitemradio\"], [role=\"option\"], [role=\"tab\"], [role=\"checkbox\"], [role=\"radio\"], [role=\"switch\"], [tabindex], [data-focusable=\"true\"], [onclick]';\n var MAX_CSS_PATH_DEPTH = 6;\n function testIdSelector(el) {\n for (const attr of TEST_ID_ATTRS) {\n const v = el.getAttribute(attr);\n if (v) return `[${attr}=\"${escAttr(v)}\"]`;\n }\n return null;\n }\n function idSelector(el) {\n const id = el.getAttribute(\"id\");\n return id && isStableToken(id) ? `#${escId(id)}` : null;\n }\n function roleNameSelector(el) {\n const role = getRole(el);\n if (!role) return null;\n const name = accessibleName(el);\n if (!name) return null;\n return `role=${role}[name=\"${escAttr(name)}\"]`;\n }\n function appearedSelector(el) {\n return testIdSelector(el) ?? idSelector(el) ?? roleNameSelector(el);\n }\n function goneSelector(el) {\n return testIdSelector(el) ?? idSelector(el);\n }\n function cssSelectorFor(el) {\n return testIdSelector(el) ?? idSelector(el) ?? buildCssPath(el);\n }\n function allElements() {\n return Array.from(document.querySelectorAll(\"*\"));\n }\n function withNth(base, el, matches) {\n if (matches.length <= 1) return base;\n const idx = matches.indexOf(el);\n return idx < 0 ? base : `${base} >> nth=${idx}`;\n }\n function buildCssPath(el) {\n const segs = [];\n let cur = el;\n let depth = 0;\n while (cur && cur.nodeType === 1 && cur !== document.documentElement && depth < MAX_CSS_PATH_DEPTH) {\n const node = cur;\n if (depth > 0) {\n const anchor = testIdSelector(node) ?? idSelector(node);\n if (anchor) {\n segs.unshift(anchor);\n break;\n }\n }\n let seg = node.tagName.toLowerCase();\n const classes = Array.from(node.classList).filter(isStableClass).slice(0, 2);\n if (classes.length) seg += `.${classes.map(escId).join(\".\")}`;\n const parent = node.parentElement;\n if (parent) {\n const sameTag = Array.from(parent.children).filter((c) => c.tagName === node.tagName);\n if (sameTag.length > 1) seg += `:nth-of-type(${sameTag.indexOf(node) + 1})`;\n }\n segs.unshift(seg);\n const partial = segs.join(\" > \");\n try {\n if (document.querySelectorAll(partial).length === 1) return partial;\n } catch {\n return null;\n }\n cur = parent;\n depth++;\n }\n if (!segs.length) return null;\n const sel = segs.join(\" > \");\n try {\n return document.querySelectorAll(sel).length ? sel : null;\n } catch {\n return null;\n }\n }\n function buildCandidates(el) {\n const out = [];\n const push = (s) => {\n if (s && out.indexOf(s) === -1) out.push(s);\n };\n push(testIdSelector(el));\n push(idSelector(el));\n const nameAttr = el.getAttribute(\"name\");\n if (nameAttr && isStableToken(nameAttr)) {\n push(`${el.tagName.toLowerCase()}[name=\"${escAttr(nameAttr)}\"]`);\n }\n const roleName = roleNameSelector(el);\n if (roleName) {\n const role = getRole(el);\n const name = accessibleName(el);\n const matches = allElements().filter((c) => getRole(c) === role && accessibleName(c) === name);\n push(withNth(roleName, el, matches));\n }\n for (const selector of interactiveHostSelectors(el)) push(selector);\n push(labelledAncestorSelector(el));\n const cssPath = buildCssPath(el);\n const text = ownText(el);\n const textSelector = text && isSmallestWithText(el, text) ? withNth(`text=\"${escAttr(text)}\"`, el, allElements().filter((c) => isSmallestWithText(c, text))) : null;\n if (isPositionalOnly(cssPath)) {\n push(textSelector);\n push(cssPath);\n } else {\n push(cssPath);\n push(textSelector);\n }\n return out.slice(0, MAX_CANDIDATES);\n }\n function interactiveHostSelectors(el) {\n let host = null;\n try {\n const found = el.closest(INTERACTIVE);\n host = found && found !== el ? found : null;\n } catch {\n host = null;\n }\n if (!host) return [];\n const out = [];\n const push = (s) => {\n if (s && out.indexOf(s) === -1) out.push(s);\n };\n push(testIdSelector(host));\n push(idSelector(host));\n push(roleNameSelector(host));\n const label = renderedText(host, 60);\n if (label) {\n const tag = host.tagName.toLowerCase();\n const role = host.getAttribute(\"role\");\n const qualifier = host.getAttribute(\"data-focusable\") ? '[data-focusable=\"true\"]' : role ? `[role=\"${escAttr(role)}\"]` : host.hasAttribute(\"tabindex\") ? `[tabindex=\"${escAttr(host.getAttribute(\"tabindex\") ?? \"0\")}\"]` : \"\";\n if (qualifier) push(`${tag}${qualifier}:has-text(\"${escAttr(label)}\")`);\n }\n return out;\n }\n function isPositionalOnly(selector) {\n return Boolean(selector?.includes(\":nth-of-type(\"));\n }\n function labelledAncestorSelector(el) {\n if (testIdSelector(el) ?? idSelector(el)) return null;\n let cur = el.parentElement;\n for (let depth = 0; cur && depth < MAX_CSS_PATH_DEPTH; depth++) {\n const anchor = testIdSelector(cur);\n if (anchor) {\n try {\n return document.querySelectorAll(anchor).length === 1 ? anchor : null;\n } catch {\n return null;\n }\n }\n cur = cur.parentElement;\n }\n return null;\n }\n function isSmallestWithText(el, text) {\n if (ownText(el) !== text) return false;\n return !Array.from(el.children).some((child) => ownText(child) === text);\n }\n function contextLabel(el) {\n const row = el.closest('tr, [role=\"row\"], li, [role=\"listitem\"], [data-testid*=\"row\"]');\n if (row && row !== el) {\n const own = renderedText(el, 60);\n const full = renderedText(row, 120);\n const t = clean(own ? full.split(own).join(\" \") : full, 60);\n if (t) return ` in the row containing \"${t}\"`;\n }\n const section = el.closest('form, section, dialog, [role=\"dialog\"], nav, main, aside');\n if (section && section !== el) {\n const label = section.getAttribute(\"aria-label\") || clean(section.querySelector(\"h1, h2, h3, h4, legend\")?.textContent) || \"\";\n if (label) return ` in the ${section.tagName.toLowerCase()} labelled \"${clean(label, 40)}\"`;\n }\n return \"\";\n }\n function semanticOf(el) {\n const role = getRole(el) || el.tagName.toLowerCase();\n const name = accessibleName(el) || ownText(el);\n const head = name ? `${name} ${role}` : role;\n return head + contextLabel(el);\n }\n function identityOf(el) {\n const own = accessibleName(el) || renderedText(el, 80);\n if (own && countSharingLabel(own) <= 1) return own;\n const row = el.closest(\n 'tr, [role=\"row\"], li, [role=\"listitem\"], [data-testid*=\"row\"], [data-testid*=\"Row\"]'\n );\n if (row && row !== el) {\n const rowText = renderedText(row, 80);\n if (rowText) return rowText;\n }\n return own || void 0;\n }\n function countSharingLabel(label) {\n const wanted = label.replace(/\\s+/g, \" \").trim();\n let count = 0;\n for (const el of allElements()) {\n const text = (el.textContent ?? \"\").replace(/\\s+/g, \" \").trim();\n if (text === wanted && ++count > 1) return count;\n if (el.getAttribute(\"aria-label\")?.trim() === wanted && ++count > 1) return count;\n }\n return count;\n }\n function describe(el) {\n const candidates = buildCandidates(el);\n if (!candidates.length) return null;\n const identity = identityOf(el);\n return { candidates, semantic: semanticOf(el), ...identity ? { identity } : {} };\n }\n\n // src/recorder/agent/capture.ts\n var ECHO_WINDOW_MS = 30;\n var GESTURE_WINDOW_MS = 1e3;\n var FOCUS_SETTLE_MS = 120;\n var MEANINGFUL_KEYS = [\n \"Enter\",\n \"Escape\",\n \"Tab\",\n \"ArrowUp\",\n \"ArrowDown\",\n \"ArrowLeft\",\n \"ArrowRight\",\n \"Backspace\",\n \"Delete\",\n \"Home\",\n \"End\",\n \"PageUp\",\n \"PageDown\",\n \" \"\n ];\n function targetOf(e) {\n const t = e.target;\n return t && t.nodeType === 1 ? t : null;\n }\n function playwrightKey(e) {\n const mods = [];\n if (e.ctrlKey) mods.push(\"Control\");\n if (e.altKey) mods.push(\"Alt\");\n if (e.metaKey) mods.push(\"Meta\");\n if (e.shiftKey && e.key.length > 1) mods.push(\"Shift\");\n const key = e.key === \" \" ? \"Space\" : e.key;\n return [...mods, key].join(\"+\");\n }\n function isStopHotkey(e) {\n return (e.ctrlKey || e.metaKey) && e.shiftKey && e.key.toLowerCase() === \"x\";\n }\n function installCapture(ctx) {\n const { config, transport, reveals } = ctx;\n const focusValue = /* @__PURE__ */ new WeakMap();\n const committed = /* @__PURE__ */ new WeakMap();\n let lastRecorded = null;\n let lastPointerDown = null;\n function resolveGestureTarget(clicked) {\n const pd = lastPointerDown;\n if (!pd || pd.el === clicked) return clicked;\n if (Date.now() - pd.t > GESTURE_WINDOW_MS) return clicked;\n const retargeted = clicked === document.documentElement || clicked === document.body;\n if (retargeted && pd.el.isConnected && describe(pd.el)) return pd.el;\n if (!describe(clicked) && pd.el.isConnected && describe(pd.el)) return pd.el;\n return clicked;\n }\n function isEchoOfRecordedClick(el) {\n const prev = lastRecorded;\n if (!prev) return false;\n if (Date.now() - prev.t > ECHO_WINDOW_MS) return false;\n if (prev.el === el) return true;\n if (prev.el.contains(el) || el.contains(prev.el)) return true;\n const label = el.closest(\"label\");\n return Boolean(label && label === prev.el.closest(\"label\"));\n }\n function emitAction(action, el, value) {\n ctx.beforeAction?.();\n const target = el ? describe(el) : null;\n if (el && !target) return false;\n const t = Date.now();\n reveals.noteAction(t);\n const ev = { kind: \"action\", action, value, target, t, author: \"human\" };\n transport.emit(ev);\n return true;\n }\n let focusTimer = null;\n let lastFocus = null;\n function noteFocusChange() {\n if (focusTimer) clearTimeout(focusTimer);\n focusTimer = setTimeout(() => {\n const el = document.activeElement;\n const selector = el ? cssSelectorFor(el) : null;\n if (!selector || selector === lastFocus) return;\n lastFocus = selector;\n transport.emit({ kind: \"focus\", selector, t: Date.now() });\n }, FOCUS_SETTLE_MS);\n }\n function flushRevealingHover(actionTarget) {\n const hovered = reveals.takeLoadBearingHover(actionTarget);\n if (hovered) emitAction(\"hover\", hovered, null);\n }\n function valueOf(el) {\n if (el.isContentEditable) return clean(el.innerText, 500);\n return el.value ?? \"\";\n }\n function commitFill(el) {\n if (!isEditable(el)) return;\n const value = valueOf(el);\n if (committed.get(el) === value) return;\n if (focusValue.get(el) === value && committed.get(el) === void 0) return;\n committed.set(el, value);\n flushRevealingHover(el);\n emitAction(\"fill\", el, value);\n }\n function flushPendingFill() {\n const active = document.activeElement;\n if (active && isEditable(active)) commitFill(active);\n }\n const on = (type, handler) => {\n document.addEventListener(type, handler, true);\n };\n on(\"focusin\", (e) => {\n const el = targetOf(e);\n if (el && isEditable(el)) focusValue.set(el, valueOf(el));\n noteFocusChange();\n });\n on(\"focusout\", () => noteFocusChange());\n on(\"mouseover\", (e) => {\n const el = targetOf(e);\n if (el) reveals.noteHover(el);\n });\n on(\"pointerdown\", (e) => {\n const el = targetOf(e);\n if (el) lastPointerDown = { el, t: Date.now() };\n });\n on(\"click\", (e) => {\n const clicked = targetOf(e);\n if (!clicked) return;\n const el = resolveGestureTarget(clicked);\n if (isEchoOfRecordedClick(el)) return;\n flushPendingFill();\n flushRevealingHover(el);\n if (emitAction(\"click\", el, null)) lastRecorded = { el, t: Date.now() };\n });\n on(\"dblclick\", (e) => {\n const el = targetOf(e);\n if (!el) return;\n flushPendingFill();\n emitAction(\"dblclick\", el, null);\n });\n on(\"change\", (e) => {\n const el = targetOf(e);\n if (!el) return;\n if (el.tagName.toLowerCase() === \"select\") {\n const sel = el;\n const opt = sel.selectedOptions[0];\n flushPendingFill();\n flushRevealingHover(el);\n emitAction(\"select\", el, opt ? opt.value || clean(opt.textContent) : sel.value);\n return;\n }\n if (isEditable(el)) commitFill(el);\n });\n on(\"blur\", (e) => {\n const el = targetOf(e);\n if (el && isEditable(el)) commitFill(el);\n });\n on(\"keydown\", (e) => {\n if (isStopHotkey(e)) {\n e.preventDefault();\n e.stopPropagation();\n transport.binding(config.stopBinding)?.({ reason: \"hotkey\" });\n return;\n }\n const el = targetOf(e);\n if (isEditable(el)) {\n if (e.key !== \"Enter\" && e.key !== \"Escape\") return;\n commitFill(el);\n } else if (!MEANINGFUL_KEYS.includes(e.key) && !(e.ctrlKey || e.metaKey || e.altKey)) {\n return;\n } else {\n flushPendingFill();\n }\n emitAction(\"press\", el, playwrightKey(e));\n });\n installScrollCapture(ctx, emitAction);\n }\n var RESIZE_PROBE = [\n \".erd_scroll_detection_container\",\n \".resize-sensor\",\n \".resize-triggers\",\n \"[data-resize-sensor]\"\n ];\n function isResizeProbe(el) {\n if (!el) return false;\n return RESIZE_PROBE.some((sel) => {\n try {\n return el.matches(sel) || el.closest(sel) !== null;\n } catch {\n return false;\n }\n });\n }\n function installScrollCapture(ctx, emitAction) {\n const { config } = ctx;\n const lastPosition = /* @__PURE__ */ new WeakMap();\n const timers = /* @__PURE__ */ new WeakMap();\n document.addEventListener(\n \"scroll\",\n (e) => {\n const raw = e.target;\n if (raw && raw.nodeType === 1 && isResizeProbe(raw)) return;\n const isDocument = !raw || raw === document || raw === document.documentElement || raw === document.body;\n const key = isDocument ? document : raw;\n const el = isDocument ? null : raw;\n const x = el ? el.scrollLeft : window.scrollX;\n const y = el ? el.scrollTop : window.scrollY;\n const existing = timers.get(key);\n if (existing) clearTimeout(existing);\n timers.set(\n key,\n setTimeout(() => {\n const last = lastPosition.get(key) ?? { x: 0, y: 0 };\n const moved = Math.abs(x - last.x) >= config.scrollMinDeltaPx || Math.abs(y - last.y) >= config.scrollMinDeltaPx;\n if (!moved) return;\n lastPosition.set(key, { x, y });\n emitAction(\"scroll\", el, JSON.stringify({ x, y }));\n }, config.scrollDebounceMs)\n );\n },\n true\n );\n }\n\n // src/noise.ts\n var TRANSIENT_NAME = /\\b(loading|spinner|progress|skeleton|please wait|submitting|saving)\\b/i;\n function isTransientIndicator(role, name) {\n if (role === \"progressbar\") return true;\n return TRANSIENT_NAME.test(name);\n }\n\n // src/recorder/agent/visibility.ts\n function isVisible(el) {\n if (!el.isConnected) return false;\n const he = el;\n if (he.hidden || el.getAttribute(\"aria-hidden\") === \"true\") return false;\n const rect = he.getBoundingClientRect();\n if (rect.width === 0 && rect.height === 0) return false;\n const cs = window.getComputedStyle(he);\n return cs.visibility !== \"hidden\" && cs.display !== \"none\" && cs.opacity !== \"0\";\n }\n\n // src/recorder/agent/dom-reaction.ts\n var INTERESTING = \"[data-testid], [data-test], [data-test-id], [data-cy], [id], [role], button, a[href]\";\n var OBSERVED_ATTRS = [\"class\", \"style\", \"hidden\", \"aria-hidden\"];\n var APPEAR_CONFIRM_MS = 600;\n function toCssSelector(selector) {\n if (selector.startsWith(\"role=\") || selector.startsWith(\"text=\")) {\n throw new Error(\"not a CSS selector\");\n }\n return selector;\n }\n function harvest(nodes, into, pick, revealed, max) {\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n if (!node || node.nodeType !== 1) continue;\n const el = node;\n revealed.push(el);\n const own = pick(el);\n if (own && into.size < max) into.add(own);\n const descendants = el.querySelectorAll(INTERESTING);\n for (let j = 0; j < descendants.length && into.size < max; j++) {\n const d = descendants[j];\n if (!d) continue;\n const sel = pick(d);\n if (sel) into.add(sel);\n }\n }\n }\n function observeDomReactions(ctx) {\n const { config, transport, reveals } = ctx;\n const visibility = /* @__PURE__ */ new WeakMap();\n let pending = [];\n const stillVisible = (sel) => {\n try {\n const el = document.querySelector(toCssSelector(sel));\n return el ? isVisible(el) : false;\n } catch {\n return true;\n }\n };\n const confirm = (entry) => {\n const survived = entry.selectors.filter(stillVisible);\n if (survived.length) {\n transport.emit({ kind: \"dom\", appeared: survived, gone: [], t: entry.at });\n }\n };\n const flushAppearances = () => {\n const due = pending;\n pending = [];\n for (const entry of due) {\n clearTimeout(entry.timer);\n confirm(entry);\n }\n };\n const visibleAppearedSelector = (el) => {\n if (!isVisible(el)) return null;\n if (isTransientIndicator(getRole(el), accessibleName(el))) return null;\n return appearedSelector(el);\n };\n const start = () => {\n const observer = new MutationObserver((records) => {\n const appeared = /* @__PURE__ */ new Set();\n const gone = /* @__PURE__ */ new Set();\n const revealed = [];\n for (const rec of records) {\n if (rec.type === \"childList\") {\n harvest(rec.addedNodes, appeared, visibleAppearedSelector, revealed, config.maxSelectorsPerMutation);\n harvest(rec.removedNodes, gone, goneSelector, [], config.maxSelectorsPerMutation);\n continue;\n }\n const el = rec.target;\n const sel = appearedSelector(el);\n if (!sel) continue;\n const now = isVisible(el);\n const was = visibility.get(el);\n visibility.set(el, now);\n if (was === void 0 || was === now) continue;\n if (now) {\n appeared.add(sel);\n revealed.push(el);\n } else {\n const g = goneSelector(el);\n if (g) gone.add(g);\n }\n }\n const at = Date.now();\n reveals.noteRevealed(revealed, at);\n if (gone.size) {\n transport.emit({ kind: \"dom\", appeared: [], gone: Array.from(gone), t: at });\n }\n if (appeared.size) {\n const entry = {\n selectors: Array.from(appeared),\n at,\n timer: setTimeout(() => {\n pending = pending.filter((e) => e !== entry);\n confirm(entry);\n }, APPEAR_CONFIRM_MS)\n };\n pending.push(entry);\n }\n });\n observer.observe(document.documentElement, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: OBSERVED_ATTRS\n });\n };\n if (document.documentElement) start();\n else document.addEventListener(\"DOMContentLoaded\", start, { once: true });\n return { flushAppearances };\n }\n\n // src/recorder/agent/reveal-tracker.ts\n var ACTION_COOLDOWN_MS = 600;\n function createRevealTracker(config) {\n let pending = null;\n let lastHovered = null;\n let lastActionAt = 0;\n return {\n noteHover(el) {\n lastHovered = el;\n },\n noteAction(at) {\n lastActionAt = at;\n },\n noteRevealed(nodes, at) {\n if (!nodes.length || !lastHovered) return;\n if (at - lastActionAt <= ACTION_COOLDOWN_MS) return;\n pending = { el: lastHovered, nodes, at };\n },\n takeLoadBearingHover(actionTarget) {\n const reveal = pending;\n pending = null;\n if (!reveal || !actionTarget) return null;\n if (Date.now() - reveal.at > config.hoverRevealWindowMs) return null;\n if (!reveal.el.isConnected) return null;\n const inside = reveal.nodes.some((n) => n === actionTarget || n.contains(actionTarget));\n return inside ? reveal.el : null;\n }\n };\n }\n\n // src/recorder/agent/transport.ts\n var DRAIN_INTERVAL_MS = 25;\n function createTransport(config) {\n const globals = window;\n const pending = [];\n let drainTimer = null;\n function binding(name) {\n const fn = globals[name];\n return typeof fn === \"function\" ? fn : null;\n }\n function drain() {\n const fn = binding(config.emitBinding);\n if (!fn) return;\n while (pending.length) {\n const ev = pending.shift();\n try {\n fn(ev);\n } catch {\n }\n }\n if (drainTimer) {\n clearInterval(drainTimer);\n drainTimer = null;\n }\n }\n function emit(ev) {\n pending.push(ev);\n if (binding(config.emitBinding)) drain();\n else if (!drainTimer) drainTimer = setInterval(drain, DRAIN_INTERVAL_MS);\n }\n return { emit, binding };\n }\n\n // src/recorder/agent/page-agent.ts\n var INSTALLED_FLAG = \"__replayAgentInstalled\";\n function pageAgent(config) {\n const globals = window;\n if (globals[INSTALLED_FLAG]) return;\n if (window.top !== window) return;\n globals[INSTALLED_FLAG] = true;\n const transport = createTransport(config);\n const reveals = createRevealTracker(config);\n const dom = observeDomReactions({ config, transport, reveals });\n installCapture({ config, transport, reveals, beforeAction: () => dom.flushAppearances() });\n globals[FLUSH_GLOBAL] = () => dom.flushAppearances();\n globals[AGENT_READY_FLAG] = true;\n }\n\n // src/recorder/agent/main.ts\n window[INSTALL_GLOBAL] = (config) => {\n pageAgent(config);\n };\n})();\n";
|
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
// Source: src/recorder/agent/main.ts. Regenerate with `npm run build:agent`.
|
|
3
3
|
/* eslint-disable */
|
|
4
4
|
/** The in-page capture agent, bundled as a standalone IIFE. */
|
|
5
|
-
export const AGENT_BUNDLE = "\"use strict\";\n(() => {\n // src/recorder/agent/config.ts\n var INSTALL_GLOBAL = \"__replayInstall\";\n var AGENT_READY_FLAG = \"__replayAgentReady\";\n var FLUSH_GLOBAL = \"__replayFlush\";\n\n // src/recorder/agent/text.ts\n function clean(s, max = 80) {\n if (!s) return \"\";\n const t = s.replace(/\\s+/g, \" \").trim();\n return t.length > max ? `${t.slice(0, max - 1)}\\u2026` : t;\n }\n function escAttr(v) {\n return v.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n }\n function escId(v) {\n return typeof window.CSS?.escape === \"function\" ? window.CSS.escape(v) : v.replace(/([^\\w-])/g, \"\\\\$1\");\n }\n function isStableToken(t) {\n if (!t || t.length > 40) return false;\n if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(t)) return false;\n if (/^(css|sc|emotion|styled|jsx|glamor|makeStyles)-/i.test(t)) return false;\n if (/[0-9a-f]{6,}/i.test(t)) return false;\n if ((t.match(/\\d/g) || []).length >= 3) return false;\n if (/[A-Z]/.test(t) && /\\d/.test(t)) return false;\n if (/^[a-z]{1,2}-[a-z0-9]{5,}$/i.test(t) && /\\d/.test(t)) return false;\n if (t.split(/[-_]/).some(looksGenerated)) return false;\n if (/-(aria|diff|live|announcer|portal)$/i.test(t)) return false;\n return true;\n }\n function looksGenerated(segment) {\n if (segment.length < 6) return false;\n if (!/^[a-z0-9]+$/i.test(segment)) return false;\n const vowels = (segment.match(/[aeiouy]/gi) || []).length;\n return /\\d/.test(segment) ? vowels <= 1 : vowels === 0;\n }\n function isStableClass(c) {\n return isStableToken(c) && !/^_/.test(c);\n }\n function renderedText(el, max = 80) {\n const inner = el.innerText;\n return clean(typeof inner === \"string\" ? inner : el.textContent, max);\n }\n\n // src/recorder/agent/roles.ts\n var TAG_ROLES = {\n button: \"button\",\n select: \"combobox\",\n textarea: \"textbox\",\n nav: \"navigation\",\n main: \"main\",\n header: \"banner\",\n footer: \"contentinfo\",\n aside: \"complementary\",\n form: \"form\",\n table: \"table\",\n tr: \"row\",\n td: \"cell\",\n th: \"columnheader\",\n ul: \"list\",\n ol: \"list\",\n li: \"listitem\",\n dialog: \"dialog\",\n option: \"option\",\n h1: \"heading\",\n h2: \"heading\",\n h3: \"heading\",\n h4: \"heading\",\n h5: \"heading\",\n h6: \"heading\"\n };\n var INPUT_ROLES = {\n button: \"button\",\n submit: \"button\",\n reset: \"button\",\n image: \"button\",\n checkbox: \"checkbox\",\n radio: \"radio\",\n range: \"slider\",\n number: \"spinbutton\",\n search: \"searchbox\",\n email: \"textbox\",\n tel: \"textbox\",\n text: \"textbox\",\n url: \"textbox\"\n };\n var NAME_FROM_CONTENT = [\n \"button\",\n \"link\",\n \"heading\",\n \"cell\",\n \"columnheader\",\n \"rowheader\",\n \"listitem\",\n \"option\",\n \"tab\",\n \"menuitem\",\n \"menuitemcheckbox\",\n \"menuitemradio\",\n \"treeitem\",\n \"switch\",\n \"checkbox\",\n \"radio\"\n ];\n var NON_EDITABLE_INPUTS = [\"checkbox\", \"radio\", \"button\", \"submit\", \"reset\", \"file\", \"image\"];\n function getRole(el) {\n const explicit = el.getAttribute(\"role\");\n if (explicit) return explicit.trim().split(/\\s+/)[0] || null;\n const tag = el.tagName.toLowerCase();\n if (tag === \"a\") return el.hasAttribute(\"href\") ? \"link\" : null;\n if (tag === \"img\") return el.getAttribute(\"alt\") === \"\" ? null : \"img\";\n if (tag === \"input\") {\n const type = (el.getAttribute(\"type\") || \"text\").toLowerCase();\n return INPUT_ROLES[type] ?? null;\n }\n return TAG_ROLES[tag] ?? null;\n }\n function isEditable(el) {\n if (!el || el.nodeType !== 1) return false;\n const tag = el.tagName.toLowerCase();\n if (tag === \"textarea\") return true;\n if (el.isContentEditable) return true;\n if (tag !== \"input\") return false;\n const type = (el.getAttribute(\"type\") || \"text\").toLowerCase();\n return !NON_EDITABLE_INPUTS.includes(type);\n }\n function accessibleName(el) {\n const aria = el.getAttribute(\"aria-label\");\n if (aria && aria.trim()) return clean(aria);\n const labelledby = el.getAttribute(\"aria-labelledby\");\n if (labelledby) {\n const parts = labelledby.split(/\\s+/).map((id) => document.getElementById(id)).filter((n) => !!n).map((n) => clean(n.textContent));\n const joined = clean(parts.filter(Boolean).join(\" \"));\n if (joined) return joined;\n }\n const tag = el.tagName.toLowerCase();\n if ([\"input\", \"select\", \"textarea\"].includes(tag)) {\n const id = el.getAttribute(\"id\");\n if (id) {\n const forLabel = document.querySelector(`label[for=\"${escAttr(id)}\"]`);\n if (forLabel) {\n const t = clean(forLabel.textContent);\n if (t) return t;\n }\n }\n const wrapping = el.closest(\"label\");\n if (wrapping) {\n const t = clean(wrapping.textContent);\n if (t) return t;\n }\n }\n for (const attr of [\"alt\", \"title\", \"placeholder\"]) {\n const v = el.getAttribute(attr);\n if (v && v.trim()) return clean(v);\n }\n const role = getRole(el);\n if (role && NAME_FROM_CONTENT.includes(role)) {\n const t = clean(el.textContent);\n if (t) return t;\n }\n return \"\";\n }\n function ownText(el) {\n return clean(el.textContent, 60);\n }\n\n // src/recorder/agent/selectors.ts\n var TEST_ID_ATTRS = [\n \"data-testid\",\n \"data-test\",\n \"data-test-id\",\n \"data-cy\",\n \"data-sentry-label\",\n \"data-testid-label\"\n ];\n var MAX_CANDIDATES = 6;\n var INTERACTIVE = 'button, a[href], [role=\"button\"], [role=\"link\"], [role=\"menuitem\"], [role=\"menuitemradio\"], [role=\"option\"], [role=\"tab\"], [role=\"checkbox\"], [role=\"radio\"], [role=\"switch\"], [tabindex], [data-focusable=\"true\"], [onclick]';\n var MAX_CSS_PATH_DEPTH = 6;\n function testIdSelector(el) {\n for (const attr of TEST_ID_ATTRS) {\n const v = el.getAttribute(attr);\n if (v) return `[${attr}=\"${escAttr(v)}\"]`;\n }\n return null;\n }\n function idSelector(el) {\n const id = el.getAttribute(\"id\");\n return id && isStableToken(id) ? `#${escId(id)}` : null;\n }\n function roleNameSelector(el) {\n const role = getRole(el);\n if (!role) return null;\n const name = accessibleName(el);\n if (!name) return null;\n return `role=${role}[name=\"${escAttr(name)}\"]`;\n }\n function appearedSelector(el) {\n return testIdSelector(el) ?? idSelector(el) ?? roleNameSelector(el);\n }\n function goneSelector(el) {\n return testIdSelector(el) ?? idSelector(el);\n }\n function cssSelectorFor(el) {\n return testIdSelector(el) ?? idSelector(el) ?? buildCssPath(el);\n }\n function allElements() {\n return Array.from(document.querySelectorAll(\"*\"));\n }\n function withNth(base, el, matches) {\n if (matches.length <= 1) return base;\n const idx = matches.indexOf(el);\n return idx < 0 ? base : `${base} >> nth=${idx}`;\n }\n function buildCssPath(el) {\n const segs = [];\n let cur = el;\n let depth = 0;\n while (cur && cur.nodeType === 1 && cur !== document.documentElement && depth < MAX_CSS_PATH_DEPTH) {\n const node = cur;\n if (depth > 0) {\n const anchor = testIdSelector(node) ?? idSelector(node);\n if (anchor) {\n segs.unshift(anchor);\n break;\n }\n }\n let seg = node.tagName.toLowerCase();\n const classes = Array.from(node.classList).filter(isStableClass).slice(0, 2);\n if (classes.length) seg += `.${classes.map(escId).join(\".\")}`;\n const parent = node.parentElement;\n if (parent) {\n const sameTag = Array.from(parent.children).filter((c) => c.tagName === node.tagName);\n if (sameTag.length > 1) seg += `:nth-of-type(${sameTag.indexOf(node) + 1})`;\n }\n segs.unshift(seg);\n const partial = segs.join(\" > \");\n try {\n if (document.querySelectorAll(partial).length === 1) return partial;\n } catch {\n return null;\n }\n cur = parent;\n depth++;\n }\n if (!segs.length) return null;\n const sel = segs.join(\" > \");\n try {\n return document.querySelectorAll(sel).length ? sel : null;\n } catch {\n return null;\n }\n }\n function buildCandidates(el) {\n const out = [];\n const push = (s) => {\n if (s && out.indexOf(s) === -1) out.push(s);\n };\n push(testIdSelector(el));\n push(idSelector(el));\n const nameAttr = el.getAttribute(\"name\");\n if (nameAttr && isStableToken(nameAttr)) {\n push(`${el.tagName.toLowerCase()}[name=\"${escAttr(nameAttr)}\"]`);\n }\n const roleName = roleNameSelector(el);\n if (roleName) {\n const role = getRole(el);\n const name = accessibleName(el);\n const matches = allElements().filter((c) => getRole(c) === role && accessibleName(c) === name);\n push(withNth(roleName, el, matches));\n }\n for (const selector of interactiveHostSelectors(el)) push(selector);\n push(labelledAncestorSelector(el));\n const cssPath = buildCssPath(el);\n const text = ownText(el);\n const textSelector = text && isSmallestWithText(el, text) ? withNth(`text=\"${escAttr(text)}\"`, el, allElements().filter((c) => isSmallestWithText(c, text))) : null;\n if (isPositionalOnly(cssPath)) {\n push(textSelector);\n push(cssPath);\n } else {\n push(cssPath);\n push(textSelector);\n }\n return out.slice(0, MAX_CANDIDATES);\n }\n function interactiveHostSelectors(el) {\n let host = null;\n try {\n const found = el.closest(INTERACTIVE);\n host = found && found !== el ? found : null;\n } catch {\n host = null;\n }\n if (!host) return [];\n const out = [];\n const push = (s) => {\n if (s && out.indexOf(s) === -1) out.push(s);\n };\n push(testIdSelector(host));\n push(idSelector(host));\n push(roleNameSelector(host));\n const label = renderedText(host, 60);\n if (label) {\n const tag = host.tagName.toLowerCase();\n const role = host.getAttribute(\"role\");\n const qualifier = host.getAttribute(\"data-focusable\") ? '[data-focusable=\"true\"]' : role ? `[role=\"${escAttr(role)}\"]` : host.hasAttribute(\"tabindex\") ? `[tabindex=\"${escAttr(host.getAttribute(\"tabindex\") ?? \"0\")}\"]` : \"\";\n if (qualifier) push(`${tag}${qualifier}:has-text(\"${escAttr(label)}\")`);\n }\n return out;\n }\n function isPositionalOnly(selector) {\n if (!selector) return false;\n if (!selector.includes(\":nth-of-type(\")) return false;\n return !selector.includes(\"[\") && !selector.includes(\".\");\n }\n function labelledAncestorSelector(el) {\n if (testIdSelector(el) ?? idSelector(el)) return null;\n let cur = el.parentElement;\n for (let depth = 0; cur && depth < MAX_CSS_PATH_DEPTH; depth++) {\n const anchor = testIdSelector(cur);\n if (anchor) {\n try {\n return document.querySelectorAll(anchor).length === 1 ? anchor : null;\n } catch {\n return null;\n }\n }\n cur = cur.parentElement;\n }\n return null;\n }\n function isSmallestWithText(el, text) {\n if (ownText(el) !== text) return false;\n return !Array.from(el.children).some((child) => ownText(child) === text);\n }\n function contextLabel(el) {\n const row = el.closest('tr, [role=\"row\"], li, [role=\"listitem\"], [data-testid*=\"row\"]');\n if (row && row !== el) {\n const own = renderedText(el, 60);\n const full = renderedText(row, 120);\n const t = clean(own ? full.split(own).join(\" \") : full, 60);\n if (t) return ` in the row containing \"${t}\"`;\n }\n const section = el.closest('form, section, dialog, [role=\"dialog\"], nav, main, aside');\n if (section && section !== el) {\n const label = section.getAttribute(\"aria-label\") || clean(section.querySelector(\"h1, h2, h3, h4, legend\")?.textContent) || \"\";\n if (label) return ` in the ${section.tagName.toLowerCase()} labelled \"${clean(label, 40)}\"`;\n }\n return \"\";\n }\n function semanticOf(el) {\n const role = getRole(el) || el.tagName.toLowerCase();\n const name = accessibleName(el) || ownText(el);\n const head = name ? `${name} ${role}` : role;\n return head + contextLabel(el);\n }\n function describe(el) {\n const candidates = buildCandidates(el);\n if (!candidates.length) return null;\n return { candidates, semantic: semanticOf(el) };\n }\n\n // src/recorder/agent/capture.ts\n var ECHO_WINDOW_MS = 30;\n var GESTURE_WINDOW_MS = 1e3;\n var FOCUS_SETTLE_MS = 120;\n var MEANINGFUL_KEYS = [\n \"Enter\",\n \"Escape\",\n \"Tab\",\n \"ArrowUp\",\n \"ArrowDown\",\n \"ArrowLeft\",\n \"ArrowRight\",\n \"Backspace\",\n \"Delete\",\n \"Home\",\n \"End\",\n \"PageUp\",\n \"PageDown\",\n \" \"\n ];\n function targetOf(e) {\n const t = e.target;\n return t && t.nodeType === 1 ? t : null;\n }\n function playwrightKey(e) {\n const mods = [];\n if (e.ctrlKey) mods.push(\"Control\");\n if (e.altKey) mods.push(\"Alt\");\n if (e.metaKey) mods.push(\"Meta\");\n if (e.shiftKey && e.key.length > 1) mods.push(\"Shift\");\n const key = e.key === \" \" ? \"Space\" : e.key;\n return [...mods, key].join(\"+\");\n }\n function isStopHotkey(e) {\n return (e.ctrlKey || e.metaKey) && e.shiftKey && e.key.toLowerCase() === \"x\";\n }\n function installCapture(ctx) {\n const { config, transport, reveals } = ctx;\n const focusValue = /* @__PURE__ */ new WeakMap();\n const committed = /* @__PURE__ */ new WeakMap();\n let lastRecorded = null;\n let lastPointerDown = null;\n function resolveGestureTarget(clicked) {\n const pd = lastPointerDown;\n if (!pd || pd.el === clicked) return clicked;\n if (Date.now() - pd.t > GESTURE_WINDOW_MS) return clicked;\n const retargeted = clicked === document.documentElement || clicked === document.body;\n if (retargeted && pd.el.isConnected && describe(pd.el)) return pd.el;\n if (!describe(clicked) && pd.el.isConnected && describe(pd.el)) return pd.el;\n return clicked;\n }\n function isEchoOfRecordedClick(el) {\n const prev = lastRecorded;\n if (!prev) return false;\n if (Date.now() - prev.t > ECHO_WINDOW_MS) return false;\n if (prev.el === el) return true;\n if (prev.el.contains(el) || el.contains(prev.el)) return true;\n const label = el.closest(\"label\");\n return Boolean(label && label === prev.el.closest(\"label\"));\n }\n function emitAction(action, el, value) {\n ctx.beforeAction?.();\n const target = el ? describe(el) : null;\n if (el && !target) return false;\n const t = Date.now();\n reveals.noteAction(t);\n const ev = { kind: \"action\", action, value, target, t, author: \"human\" };\n transport.emit(ev);\n return true;\n }\n let focusTimer = null;\n let lastFocus = null;\n function noteFocusChange() {\n if (focusTimer) clearTimeout(focusTimer);\n focusTimer = setTimeout(() => {\n const el = document.activeElement;\n const selector = el ? cssSelectorFor(el) : null;\n if (!selector || selector === lastFocus) return;\n lastFocus = selector;\n transport.emit({ kind: \"focus\", selector, t: Date.now() });\n }, FOCUS_SETTLE_MS);\n }\n function flushRevealingHover(actionTarget) {\n const hovered = reveals.takeLoadBearingHover(actionTarget);\n if (hovered) emitAction(\"hover\", hovered, null);\n }\n function valueOf(el) {\n if (el.isContentEditable) return clean(el.innerText, 500);\n return el.value ?? \"\";\n }\n function commitFill(el) {\n if (!isEditable(el)) return;\n const value = valueOf(el);\n if (committed.get(el) === value) return;\n if (focusValue.get(el) === value && committed.get(el) === void 0) return;\n committed.set(el, value);\n flushRevealingHover(el);\n emitAction(\"fill\", el, value);\n }\n function flushPendingFill() {\n const active = document.activeElement;\n if (active && isEditable(active)) commitFill(active);\n }\n const on = (type, handler) => {\n document.addEventListener(type, handler, true);\n };\n on(\"focusin\", (e) => {\n const el = targetOf(e);\n if (el && isEditable(el)) focusValue.set(el, valueOf(el));\n noteFocusChange();\n });\n on(\"focusout\", () => noteFocusChange());\n on(\"mouseover\", (e) => {\n const el = targetOf(e);\n if (el) reveals.noteHover(el);\n });\n on(\"pointerdown\", (e) => {\n const el = targetOf(e);\n if (el) lastPointerDown = { el, t: Date.now() };\n });\n on(\"click\", (e) => {\n const clicked = targetOf(e);\n if (!clicked) return;\n const el = resolveGestureTarget(clicked);\n if (isEchoOfRecordedClick(el)) return;\n flushPendingFill();\n flushRevealingHover(el);\n if (emitAction(\"click\", el, null)) lastRecorded = { el, t: Date.now() };\n });\n on(\"dblclick\", (e) => {\n const el = targetOf(e);\n if (!el) return;\n flushPendingFill();\n emitAction(\"dblclick\", el, null);\n });\n on(\"change\", (e) => {\n const el = targetOf(e);\n if (!el) return;\n if (el.tagName.toLowerCase() === \"select\") {\n const sel = el;\n const opt = sel.selectedOptions[0];\n flushPendingFill();\n flushRevealingHover(el);\n emitAction(\"select\", el, opt ? opt.value || clean(opt.textContent) : sel.value);\n return;\n }\n if (isEditable(el)) commitFill(el);\n });\n on(\"blur\", (e) => {\n const el = targetOf(e);\n if (el && isEditable(el)) commitFill(el);\n });\n on(\"keydown\", (e) => {\n if (isStopHotkey(e)) {\n e.preventDefault();\n e.stopPropagation();\n transport.binding(config.stopBinding)?.({ reason: \"hotkey\" });\n return;\n }\n const el = targetOf(e);\n if (isEditable(el)) {\n if (e.key !== \"Enter\" && e.key !== \"Escape\") return;\n commitFill(el);\n } else if (!MEANINGFUL_KEYS.includes(e.key) && !(e.ctrlKey || e.metaKey || e.altKey)) {\n return;\n } else {\n flushPendingFill();\n }\n emitAction(\"press\", el, playwrightKey(e));\n });\n installScrollCapture(ctx, emitAction);\n }\n var RESIZE_PROBE = [\n \".erd_scroll_detection_container\",\n \".resize-sensor\",\n \".resize-triggers\",\n \"[data-resize-sensor]\"\n ];\n function isResizeProbe(el) {\n if (!el) return false;\n return RESIZE_PROBE.some((sel) => {\n try {\n return el.matches(sel) || el.closest(sel) !== null;\n } catch {\n return false;\n }\n });\n }\n function installScrollCapture(ctx, emitAction) {\n const { config } = ctx;\n const lastPosition = /* @__PURE__ */ new WeakMap();\n const timers = /* @__PURE__ */ new WeakMap();\n document.addEventListener(\n \"scroll\",\n (e) => {\n const raw = e.target;\n if (raw && raw.nodeType === 1 && isResizeProbe(raw)) return;\n const isDocument = !raw || raw === document || raw === document.documentElement || raw === document.body;\n const key = isDocument ? document : raw;\n const el = isDocument ? null : raw;\n const x = el ? el.scrollLeft : window.scrollX;\n const y = el ? el.scrollTop : window.scrollY;\n const existing = timers.get(key);\n if (existing) clearTimeout(existing);\n timers.set(\n key,\n setTimeout(() => {\n const last = lastPosition.get(key) ?? { x: 0, y: 0 };\n const moved = Math.abs(x - last.x) >= config.scrollMinDeltaPx || Math.abs(y - last.y) >= config.scrollMinDeltaPx;\n if (!moved) return;\n lastPosition.set(key, { x, y });\n emitAction(\"scroll\", el, JSON.stringify({ x, y }));\n }, config.scrollDebounceMs)\n );\n },\n true\n );\n }\n\n // src/noise.ts\n var TRANSIENT_NAME = /\\b(loading|spinner|progress|skeleton|please wait|submitting|saving)\\b/i;\n function isTransientIndicator(role, name) {\n if (role === \"progressbar\") return true;\n return TRANSIENT_NAME.test(name);\n }\n\n // src/recorder/agent/visibility.ts\n function isVisible(el) {\n if (!el.isConnected) return false;\n const he = el;\n if (he.hidden || el.getAttribute(\"aria-hidden\") === \"true\") return false;\n const rect = he.getBoundingClientRect();\n if (rect.width === 0 && rect.height === 0) return false;\n const cs = window.getComputedStyle(he);\n return cs.visibility !== \"hidden\" && cs.display !== \"none\" && cs.opacity !== \"0\";\n }\n\n // src/recorder/agent/dom-reaction.ts\n var INTERESTING = \"[data-testid], [data-test], [data-test-id], [data-cy], [id], [role], button, a[href]\";\n var OBSERVED_ATTRS = [\"class\", \"style\", \"hidden\", \"aria-hidden\"];\n var APPEAR_CONFIRM_MS = 600;\n function toCssSelector(selector) {\n if (selector.startsWith(\"role=\") || selector.startsWith(\"text=\")) {\n throw new Error(\"not a CSS selector\");\n }\n return selector;\n }\n function harvest(nodes, into, pick, revealed, max) {\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n if (!node || node.nodeType !== 1) continue;\n const el = node;\n revealed.push(el);\n const own = pick(el);\n if (own && into.size < max) into.add(own);\n const descendants = el.querySelectorAll(INTERESTING);\n for (let j = 0; j < descendants.length && into.size < max; j++) {\n const d = descendants[j];\n if (!d) continue;\n const sel = pick(d);\n if (sel) into.add(sel);\n }\n }\n }\n function observeDomReactions(ctx) {\n const { config, transport, reveals } = ctx;\n const visibility = /* @__PURE__ */ new WeakMap();\n let pending = [];\n const stillVisible = (sel) => {\n try {\n const el = document.querySelector(toCssSelector(sel));\n return el ? isVisible(el) : false;\n } catch {\n return true;\n }\n };\n const confirm = (entry) => {\n const survived = entry.selectors.filter(stillVisible);\n if (survived.length) {\n transport.emit({ kind: \"dom\", appeared: survived, gone: [], t: entry.at });\n }\n };\n const flushAppearances = () => {\n const due = pending;\n pending = [];\n for (const entry of due) {\n clearTimeout(entry.timer);\n confirm(entry);\n }\n };\n const visibleAppearedSelector = (el) => {\n if (!isVisible(el)) return null;\n if (isTransientIndicator(getRole(el), accessibleName(el))) return null;\n return appearedSelector(el);\n };\n const start = () => {\n const observer = new MutationObserver((records) => {\n const appeared = /* @__PURE__ */ new Set();\n const gone = /* @__PURE__ */ new Set();\n const revealed = [];\n for (const rec of records) {\n if (rec.type === \"childList\") {\n harvest(rec.addedNodes, appeared, visibleAppearedSelector, revealed, config.maxSelectorsPerMutation);\n harvest(rec.removedNodes, gone, goneSelector, [], config.maxSelectorsPerMutation);\n continue;\n }\n const el = rec.target;\n const sel = appearedSelector(el);\n if (!sel) continue;\n const now = isVisible(el);\n const was = visibility.get(el);\n visibility.set(el, now);\n if (was === void 0 || was === now) continue;\n if (now) {\n appeared.add(sel);\n revealed.push(el);\n } else {\n const g = goneSelector(el);\n if (g) gone.add(g);\n }\n }\n const at = Date.now();\n reveals.noteRevealed(revealed, at);\n if (gone.size) {\n transport.emit({ kind: \"dom\", appeared: [], gone: Array.from(gone), t: at });\n }\n if (appeared.size) {\n const entry = {\n selectors: Array.from(appeared),\n at,\n timer: setTimeout(() => {\n pending = pending.filter((e) => e !== entry);\n confirm(entry);\n }, APPEAR_CONFIRM_MS)\n };\n pending.push(entry);\n }\n });\n observer.observe(document.documentElement, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: OBSERVED_ATTRS\n });\n };\n if (document.documentElement) start();\n else document.addEventListener(\"DOMContentLoaded\", start, { once: true });\n return { flushAppearances };\n }\n\n // src/recorder/agent/reveal-tracker.ts\n var ACTION_COOLDOWN_MS = 600;\n function createRevealTracker(config) {\n let pending = null;\n let lastHovered = null;\n let lastActionAt = 0;\n return {\n noteHover(el) {\n lastHovered = el;\n },\n noteAction(at) {\n lastActionAt = at;\n },\n noteRevealed(nodes, at) {\n if (!nodes.length || !lastHovered) return;\n if (at - lastActionAt <= ACTION_COOLDOWN_MS) return;\n pending = { el: lastHovered, nodes, at };\n },\n takeLoadBearingHover(actionTarget) {\n const reveal = pending;\n pending = null;\n if (!reveal || !actionTarget) return null;\n if (Date.now() - reveal.at > config.hoverRevealWindowMs) return null;\n if (!reveal.el.isConnected) return null;\n const inside = reveal.nodes.some((n) => n === actionTarget || n.contains(actionTarget));\n return inside ? reveal.el : null;\n }\n };\n }\n\n // src/recorder/agent/transport.ts\n var DRAIN_INTERVAL_MS = 25;\n function createTransport(config) {\n const globals = window;\n const pending = [];\n let drainTimer = null;\n function binding(name) {\n const fn = globals[name];\n return typeof fn === \"function\" ? fn : null;\n }\n function drain() {\n const fn = binding(config.emitBinding);\n if (!fn) return;\n while (pending.length) {\n const ev = pending.shift();\n try {\n fn(ev);\n } catch {\n }\n }\n if (drainTimer) {\n clearInterval(drainTimer);\n drainTimer = null;\n }\n }\n function emit(ev) {\n pending.push(ev);\n if (binding(config.emitBinding)) drain();\n else if (!drainTimer) drainTimer = setInterval(drain, DRAIN_INTERVAL_MS);\n }\n return { emit, binding };\n }\n\n // src/recorder/agent/page-agent.ts\n var INSTALLED_FLAG = \"__replayAgentInstalled\";\n function pageAgent(config) {\n const globals = window;\n if (globals[INSTALLED_FLAG]) return;\n if (window.top !== window) return;\n globals[INSTALLED_FLAG] = true;\n const transport = createTransport(config);\n const reveals = createRevealTracker(config);\n const dom = observeDomReactions({ config, transport, reveals });\n installCapture({ config, transport, reveals, beforeAction: () => dom.flushAppearances() });\n globals[FLUSH_GLOBAL] = () => dom.flushAppearances();\n globals[AGENT_READY_FLAG] = true;\n }\n\n // src/recorder/agent/main.ts\n window[INSTALL_GLOBAL] = (config) => {\n pageAgent(config);\n };\n})();\n";
|
|
5
|
+
export const AGENT_BUNDLE = "\"use strict\";\n(() => {\n // src/recorder/agent/config.ts\n var INSTALL_GLOBAL = \"__replayInstall\";\n var AGENT_READY_FLAG = \"__replayAgentReady\";\n var FLUSH_GLOBAL = \"__replayFlush\";\n\n // src/recorder/agent/text.ts\n function clean(s, max = 80) {\n if (!s) return \"\";\n const t = s.replace(/\\s+/g, \" \").trim();\n return t.length > max ? `${t.slice(0, max - 1)}\\u2026` : t;\n }\n function escAttr(v) {\n return v.replace(/\\\\/g, \"\\\\\\\\\").replace(/\"/g, '\\\\\"');\n }\n function escId(v) {\n return typeof window.CSS?.escape === \"function\" ? window.CSS.escape(v) : v.replace(/([^\\w-])/g, \"\\\\$1\");\n }\n function isStableToken(t) {\n if (!t || t.length > 40) return false;\n if (!/^[a-zA-Z][a-zA-Z0-9_-]*$/.test(t)) return false;\n if (/^(css|sc|emotion|styled|jsx|glamor|makeStyles)-/i.test(t)) return false;\n if (/^r-/.test(t)) return false;\n if (/[0-9a-f]{6,}/i.test(t)) return false;\n if ((t.match(/\\d/g) || []).length >= 3) return false;\n if (/[A-Z]/.test(t) && /\\d/.test(t)) return false;\n if (/^[a-z]{1,2}-[a-z0-9]{5,}$/i.test(t) && /\\d/.test(t)) return false;\n if (t.split(/[-_]/).some(looksGenerated)) return false;\n if (/-(aria|diff|live|announcer|portal)$/i.test(t)) return false;\n return true;\n }\n function looksGenerated(segment) {\n if (segment.length < 6) return false;\n if (!/^[a-z0-9]+$/i.test(segment)) return false;\n const vowels = (segment.match(/[aeiouy]/gi) || []).length;\n return /\\d/.test(segment) ? vowels <= 1 : vowels === 0;\n }\n function isStableClass(c) {\n return isStableToken(c) && !/^_/.test(c);\n }\n function renderedText(el, max = 80) {\n const inner = el.innerText;\n return clean(typeof inner === \"string\" ? inner : el.textContent, max);\n }\n\n // src/recorder/agent/roles.ts\n var TAG_ROLES = {\n button: \"button\",\n select: \"combobox\",\n textarea: \"textbox\",\n nav: \"navigation\",\n main: \"main\",\n header: \"banner\",\n footer: \"contentinfo\",\n aside: \"complementary\",\n form: \"form\",\n table: \"table\",\n tr: \"row\",\n td: \"cell\",\n th: \"columnheader\",\n ul: \"list\",\n ol: \"list\",\n li: \"listitem\",\n dialog: \"dialog\",\n option: \"option\",\n h1: \"heading\",\n h2: \"heading\",\n h3: \"heading\",\n h4: \"heading\",\n h5: \"heading\",\n h6: \"heading\"\n };\n var INPUT_ROLES = {\n button: \"button\",\n submit: \"button\",\n reset: \"button\",\n image: \"button\",\n checkbox: \"checkbox\",\n radio: \"radio\",\n range: \"slider\",\n number: \"spinbutton\",\n search: \"searchbox\",\n email: \"textbox\",\n tel: \"textbox\",\n text: \"textbox\",\n url: \"textbox\"\n };\n var NAME_FROM_CONTENT = [\n \"button\",\n \"link\",\n \"heading\",\n \"cell\",\n \"columnheader\",\n \"rowheader\",\n \"listitem\",\n \"option\",\n \"tab\",\n \"menuitem\",\n \"menuitemcheckbox\",\n \"menuitemradio\",\n \"treeitem\",\n \"switch\",\n \"checkbox\",\n \"radio\"\n ];\n var NON_EDITABLE_INPUTS = [\"checkbox\", \"radio\", \"button\", \"submit\", \"reset\", \"file\", \"image\"];\n function getRole(el) {\n const explicit = el.getAttribute(\"role\");\n if (explicit) return explicit.trim().split(/\\s+/)[0] || null;\n const tag = el.tagName.toLowerCase();\n if (tag === \"a\") return el.hasAttribute(\"href\") ? \"link\" : null;\n if (tag === \"img\") return el.getAttribute(\"alt\") === \"\" ? null : \"img\";\n if (tag === \"input\") {\n const type = (el.getAttribute(\"type\") || \"text\").toLowerCase();\n return INPUT_ROLES[type] ?? null;\n }\n return TAG_ROLES[tag] ?? null;\n }\n function isEditable(el) {\n if (!el || el.nodeType !== 1) return false;\n const tag = el.tagName.toLowerCase();\n if (tag === \"textarea\") return true;\n if (el.isContentEditable) return true;\n if (tag !== \"input\") return false;\n const type = (el.getAttribute(\"type\") || \"text\").toLowerCase();\n return !NON_EDITABLE_INPUTS.includes(type);\n }\n function accessibleName(el) {\n const aria = el.getAttribute(\"aria-label\");\n if (aria && aria.trim()) return clean(aria);\n const labelledby = el.getAttribute(\"aria-labelledby\");\n if (labelledby) {\n const parts = labelledby.split(/\\s+/).map((id) => document.getElementById(id)).filter((n) => !!n).map((n) => clean(n.textContent));\n const joined = clean(parts.filter(Boolean).join(\" \"));\n if (joined) return joined;\n }\n const tag = el.tagName.toLowerCase();\n if ([\"input\", \"select\", \"textarea\"].includes(tag)) {\n const id = el.getAttribute(\"id\");\n if (id) {\n const forLabel = document.querySelector(`label[for=\"${escAttr(id)}\"]`);\n if (forLabel) {\n const t = clean(forLabel.textContent);\n if (t) return t;\n }\n }\n const wrapping = el.closest(\"label\");\n if (wrapping) {\n const t = clean(wrapping.textContent);\n if (t) return t;\n }\n }\n for (const attr of [\"alt\", \"title\", \"placeholder\"]) {\n const v = el.getAttribute(attr);\n if (v && v.trim()) return clean(v);\n }\n const role = getRole(el);\n if (role && NAME_FROM_CONTENT.includes(role)) {\n const t = clean(el.textContent);\n if (t) return t;\n }\n return \"\";\n }\n function ownText(el) {\n return clean(el.textContent, 60);\n }\n\n // src/recorder/agent/selectors.ts\n var TEST_ID_ATTRS = [\n \"data-testid\",\n \"data-test\",\n \"data-test-id\",\n \"data-cy\",\n \"data-sentry-label\",\n \"data-testid-label\"\n ];\n var MAX_CANDIDATES = 6;\n var INTERACTIVE = 'button, a[href], [role=\"button\"], [role=\"link\"], [role=\"menuitem\"], [role=\"menuitemradio\"], [role=\"option\"], [role=\"tab\"], [role=\"checkbox\"], [role=\"radio\"], [role=\"switch\"], [tabindex], [data-focusable=\"true\"], [onclick]';\n var MAX_CSS_PATH_DEPTH = 6;\n function testIdSelector(el) {\n for (const attr of TEST_ID_ATTRS) {\n const v = el.getAttribute(attr);\n if (v) return `[${attr}=\"${escAttr(v)}\"]`;\n }\n return null;\n }\n function idSelector(el) {\n const id = el.getAttribute(\"id\");\n return id && isStableToken(id) ? `#${escId(id)}` : null;\n }\n function roleNameSelector(el) {\n const role = getRole(el);\n if (!role) return null;\n const name = accessibleName(el);\n if (!name) return null;\n return `role=${role}[name=\"${escAttr(name)}\"]`;\n }\n function appearedSelector(el) {\n return testIdSelector(el) ?? idSelector(el) ?? roleNameSelector(el);\n }\n function goneSelector(el) {\n return testIdSelector(el) ?? idSelector(el);\n }\n function cssSelectorFor(el) {\n return testIdSelector(el) ?? idSelector(el) ?? buildCssPath(el);\n }\n function allElements() {\n return Array.from(document.querySelectorAll(\"*\"));\n }\n function withNth(base, el, matches) {\n if (matches.length <= 1) return base;\n const idx = matches.indexOf(el);\n return idx < 0 ? base : `${base} >> nth=${idx}`;\n }\n function buildCssPath(el) {\n const segs = [];\n let cur = el;\n let depth = 0;\n while (cur && cur.nodeType === 1 && cur !== document.documentElement && depth < MAX_CSS_PATH_DEPTH) {\n const node = cur;\n if (depth > 0) {\n const anchor = testIdSelector(node) ?? idSelector(node);\n if (anchor) {\n segs.unshift(anchor);\n break;\n }\n }\n let seg = node.tagName.toLowerCase();\n const classes = Array.from(node.classList).filter(isStableClass).slice(0, 2);\n if (classes.length) seg += `.${classes.map(escId).join(\".\")}`;\n const parent = node.parentElement;\n if (parent) {\n const sameTag = Array.from(parent.children).filter((c) => c.tagName === node.tagName);\n if (sameTag.length > 1) seg += `:nth-of-type(${sameTag.indexOf(node) + 1})`;\n }\n segs.unshift(seg);\n const partial = segs.join(\" > \");\n try {\n if (document.querySelectorAll(partial).length === 1) return partial;\n } catch {\n return null;\n }\n cur = parent;\n depth++;\n }\n if (!segs.length) return null;\n const sel = segs.join(\" > \");\n try {\n return document.querySelectorAll(sel).length ? sel : null;\n } catch {\n return null;\n }\n }\n function buildCandidates(el) {\n const out = [];\n const push = (s) => {\n if (s && out.indexOf(s) === -1) out.push(s);\n };\n push(testIdSelector(el));\n push(idSelector(el));\n const nameAttr = el.getAttribute(\"name\");\n if (nameAttr && isStableToken(nameAttr)) {\n push(`${el.tagName.toLowerCase()}[name=\"${escAttr(nameAttr)}\"]`);\n }\n const roleName = roleNameSelector(el);\n if (roleName) {\n const role = getRole(el);\n const name = accessibleName(el);\n const matches = allElements().filter((c) => getRole(c) === role && accessibleName(c) === name);\n push(withNth(roleName, el, matches));\n }\n for (const selector of interactiveHostSelectors(el)) push(selector);\n push(labelledAncestorSelector(el));\n const cssPath = buildCssPath(el);\n const text = ownText(el);\n const textSelector = text && isSmallestWithText(el, text) ? withNth(`text=\"${escAttr(text)}\"`, el, allElements().filter((c) => isSmallestWithText(c, text))) : null;\n if (isPositionalOnly(cssPath)) {\n push(textSelector);\n push(cssPath);\n } else {\n push(cssPath);\n push(textSelector);\n }\n return out.slice(0, MAX_CANDIDATES);\n }\n function interactiveHostSelectors(el) {\n let host = null;\n try {\n const found = el.closest(INTERACTIVE);\n host = found && found !== el ? found : null;\n } catch {\n host = null;\n }\n if (!host) return [];\n const out = [];\n const push = (s) => {\n if (s && out.indexOf(s) === -1) out.push(s);\n };\n push(testIdSelector(host));\n push(idSelector(host));\n push(roleNameSelector(host));\n const label = renderedText(host, 60);\n if (label) {\n const tag = host.tagName.toLowerCase();\n const role = host.getAttribute(\"role\");\n const qualifier = host.getAttribute(\"data-focusable\") ? '[data-focusable=\"true\"]' : role ? `[role=\"${escAttr(role)}\"]` : host.hasAttribute(\"tabindex\") ? `[tabindex=\"${escAttr(host.getAttribute(\"tabindex\") ?? \"0\")}\"]` : \"\";\n if (qualifier) push(`${tag}${qualifier}:has-text(\"${escAttr(label)}\")`);\n }\n return out;\n }\n function isPositionalOnly(selector) {\n return Boolean(selector?.includes(\":nth-of-type(\"));\n }\n function labelledAncestorSelector(el) {\n if (testIdSelector(el) ?? idSelector(el)) return null;\n let cur = el.parentElement;\n for (let depth = 0; cur && depth < MAX_CSS_PATH_DEPTH; depth++) {\n const anchor = testIdSelector(cur);\n if (anchor) {\n try {\n return document.querySelectorAll(anchor).length === 1 ? anchor : null;\n } catch {\n return null;\n }\n }\n cur = cur.parentElement;\n }\n return null;\n }\n function isSmallestWithText(el, text) {\n if (ownText(el) !== text) return false;\n return !Array.from(el.children).some((child) => ownText(child) === text);\n }\n function contextLabel(el) {\n const row = el.closest('tr, [role=\"row\"], li, [role=\"listitem\"], [data-testid*=\"row\"]');\n if (row && row !== el) {\n const own = renderedText(el, 60);\n const full = renderedText(row, 120);\n const t = clean(own ? full.split(own).join(\" \") : full, 60);\n if (t) return ` in the row containing \"${t}\"`;\n }\n const section = el.closest('form, section, dialog, [role=\"dialog\"], nav, main, aside');\n if (section && section !== el) {\n const label = section.getAttribute(\"aria-label\") || clean(section.querySelector(\"h1, h2, h3, h4, legend\")?.textContent) || \"\";\n if (label) return ` in the ${section.tagName.toLowerCase()} labelled \"${clean(label, 40)}\"`;\n }\n return \"\";\n }\n function semanticOf(el) {\n const role = getRole(el) || el.tagName.toLowerCase();\n const name = accessibleName(el) || ownText(el);\n const head = name ? `${name} ${role}` : role;\n return head + contextLabel(el);\n }\n function identityOf(el) {\n const own = accessibleName(el) || renderedText(el, 80);\n if (own && countSharingLabel(own) <= 1) return own;\n const row = el.closest(\n 'tr, [role=\"row\"], li, [role=\"listitem\"], [data-testid*=\"row\"], [data-testid*=\"Row\"]'\n );\n if (row && row !== el) {\n const rowText = renderedText(row, 80);\n if (rowText) return rowText;\n }\n return own || void 0;\n }\n function countSharingLabel(label) {\n const wanted = label.replace(/\\s+/g, \" \").trim();\n let count = 0;\n for (const el of allElements()) {\n const text = (el.textContent ?? \"\").replace(/\\s+/g, \" \").trim();\n if (text === wanted && ++count > 1) return count;\n if (el.getAttribute(\"aria-label\")?.trim() === wanted && ++count > 1) return count;\n }\n return count;\n }\n function describe(el) {\n const candidates = buildCandidates(el);\n if (!candidates.length) return null;\n const identity = identityOf(el);\n return { candidates, semantic: semanticOf(el), ...identity ? { identity } : {} };\n }\n\n // src/recorder/agent/capture.ts\n var ECHO_WINDOW_MS = 30;\n var GESTURE_WINDOW_MS = 1e3;\n var FOCUS_SETTLE_MS = 120;\n var MEANINGFUL_KEYS = [\n \"Enter\",\n \"Escape\",\n \"Tab\",\n \"ArrowUp\",\n \"ArrowDown\",\n \"ArrowLeft\",\n \"ArrowRight\",\n \"Backspace\",\n \"Delete\",\n \"Home\",\n \"End\",\n \"PageUp\",\n \"PageDown\",\n \" \"\n ];\n function targetOf(e) {\n const t = e.target;\n return t && t.nodeType === 1 ? t : null;\n }\n function playwrightKey(e) {\n const mods = [];\n if (e.ctrlKey) mods.push(\"Control\");\n if (e.altKey) mods.push(\"Alt\");\n if (e.metaKey) mods.push(\"Meta\");\n if (e.shiftKey && e.key.length > 1) mods.push(\"Shift\");\n const key = e.key === \" \" ? \"Space\" : e.key;\n return [...mods, key].join(\"+\");\n }\n function isStopHotkey(e) {\n return (e.ctrlKey || e.metaKey) && e.shiftKey && e.key.toLowerCase() === \"x\";\n }\n function installCapture(ctx) {\n const { config, transport, reveals } = ctx;\n const focusValue = /* @__PURE__ */ new WeakMap();\n const committed = /* @__PURE__ */ new WeakMap();\n let lastRecorded = null;\n let lastPointerDown = null;\n function resolveGestureTarget(clicked) {\n const pd = lastPointerDown;\n if (!pd || pd.el === clicked) return clicked;\n if (Date.now() - pd.t > GESTURE_WINDOW_MS) return clicked;\n const retargeted = clicked === document.documentElement || clicked === document.body;\n if (retargeted && pd.el.isConnected && describe(pd.el)) return pd.el;\n if (!describe(clicked) && pd.el.isConnected && describe(pd.el)) return pd.el;\n return clicked;\n }\n function isEchoOfRecordedClick(el) {\n const prev = lastRecorded;\n if (!prev) return false;\n if (Date.now() - prev.t > ECHO_WINDOW_MS) return false;\n if (prev.el === el) return true;\n if (prev.el.contains(el) || el.contains(prev.el)) return true;\n const label = el.closest(\"label\");\n return Boolean(label && label === prev.el.closest(\"label\"));\n }\n function emitAction(action, el, value) {\n ctx.beforeAction?.();\n const target = el ? describe(el) : null;\n if (el && !target) return false;\n const t = Date.now();\n reveals.noteAction(t);\n const ev = { kind: \"action\", action, value, target, t, author: \"human\" };\n transport.emit(ev);\n return true;\n }\n let focusTimer = null;\n let lastFocus = null;\n function noteFocusChange() {\n if (focusTimer) clearTimeout(focusTimer);\n focusTimer = setTimeout(() => {\n const el = document.activeElement;\n const selector = el ? cssSelectorFor(el) : null;\n if (!selector || selector === lastFocus) return;\n lastFocus = selector;\n transport.emit({ kind: \"focus\", selector, t: Date.now() });\n }, FOCUS_SETTLE_MS);\n }\n function flushRevealingHover(actionTarget) {\n const hovered = reveals.takeLoadBearingHover(actionTarget);\n if (hovered) emitAction(\"hover\", hovered, null);\n }\n function valueOf(el) {\n if (el.isContentEditable) return clean(el.innerText, 500);\n return el.value ?? \"\";\n }\n function commitFill(el) {\n if (!isEditable(el)) return;\n const value = valueOf(el);\n if (committed.get(el) === value) return;\n if (focusValue.get(el) === value && committed.get(el) === void 0) return;\n committed.set(el, value);\n flushRevealingHover(el);\n emitAction(\"fill\", el, value);\n }\n function flushPendingFill() {\n const active = document.activeElement;\n if (active && isEditable(active)) commitFill(active);\n }\n const on = (type, handler) => {\n document.addEventListener(type, handler, true);\n };\n on(\"focusin\", (e) => {\n const el = targetOf(e);\n if (el && isEditable(el)) focusValue.set(el, valueOf(el));\n noteFocusChange();\n });\n on(\"focusout\", () => noteFocusChange());\n on(\"mouseover\", (e) => {\n const el = targetOf(e);\n if (el) reveals.noteHover(el);\n });\n on(\"pointerdown\", (e) => {\n const el = targetOf(e);\n if (el) lastPointerDown = { el, t: Date.now() };\n });\n on(\"click\", (e) => {\n const clicked = targetOf(e);\n if (!clicked) return;\n const el = resolveGestureTarget(clicked);\n if (isEchoOfRecordedClick(el)) return;\n flushPendingFill();\n flushRevealingHover(el);\n if (emitAction(\"click\", el, null)) lastRecorded = { el, t: Date.now() };\n });\n on(\"dblclick\", (e) => {\n const el = targetOf(e);\n if (!el) return;\n flushPendingFill();\n emitAction(\"dblclick\", el, null);\n });\n on(\"change\", (e) => {\n const el = targetOf(e);\n if (!el) return;\n if (el.tagName.toLowerCase() === \"select\") {\n const sel = el;\n const opt = sel.selectedOptions[0];\n flushPendingFill();\n flushRevealingHover(el);\n emitAction(\"select\", el, opt ? opt.value || clean(opt.textContent) : sel.value);\n return;\n }\n if (isEditable(el)) commitFill(el);\n });\n on(\"blur\", (e) => {\n const el = targetOf(e);\n if (el && isEditable(el)) commitFill(el);\n });\n on(\"keydown\", (e) => {\n if (isStopHotkey(e)) {\n e.preventDefault();\n e.stopPropagation();\n transport.binding(config.stopBinding)?.({ reason: \"hotkey\" });\n return;\n }\n const el = targetOf(e);\n if (isEditable(el)) {\n if (e.key !== \"Enter\" && e.key !== \"Escape\") return;\n commitFill(el);\n } else if (!MEANINGFUL_KEYS.includes(e.key) && !(e.ctrlKey || e.metaKey || e.altKey)) {\n return;\n } else {\n flushPendingFill();\n }\n emitAction(\"press\", el, playwrightKey(e));\n });\n installScrollCapture(ctx, emitAction);\n }\n var RESIZE_PROBE = [\n \".erd_scroll_detection_container\",\n \".resize-sensor\",\n \".resize-triggers\",\n \"[data-resize-sensor]\"\n ];\n function isResizeProbe(el) {\n if (!el) return false;\n return RESIZE_PROBE.some((sel) => {\n try {\n return el.matches(sel) || el.closest(sel) !== null;\n } catch {\n return false;\n }\n });\n }\n function installScrollCapture(ctx, emitAction) {\n const { config } = ctx;\n const lastPosition = /* @__PURE__ */ new WeakMap();\n const timers = /* @__PURE__ */ new WeakMap();\n document.addEventListener(\n \"scroll\",\n (e) => {\n const raw = e.target;\n if (raw && raw.nodeType === 1 && isResizeProbe(raw)) return;\n const isDocument = !raw || raw === document || raw === document.documentElement || raw === document.body;\n const key = isDocument ? document : raw;\n const el = isDocument ? null : raw;\n const x = el ? el.scrollLeft : window.scrollX;\n const y = el ? el.scrollTop : window.scrollY;\n const existing = timers.get(key);\n if (existing) clearTimeout(existing);\n timers.set(\n key,\n setTimeout(() => {\n const last = lastPosition.get(key) ?? { x: 0, y: 0 };\n const moved = Math.abs(x - last.x) >= config.scrollMinDeltaPx || Math.abs(y - last.y) >= config.scrollMinDeltaPx;\n if (!moved) return;\n lastPosition.set(key, { x, y });\n emitAction(\"scroll\", el, JSON.stringify({ x, y }));\n }, config.scrollDebounceMs)\n );\n },\n true\n );\n }\n\n // src/noise.ts\n var TRANSIENT_NAME = /\\b(loading|spinner|progress|skeleton|please wait|submitting|saving)\\b/i;\n function isTransientIndicator(role, name) {\n if (role === \"progressbar\") return true;\n return TRANSIENT_NAME.test(name);\n }\n\n // src/recorder/agent/visibility.ts\n function isVisible(el) {\n if (!el.isConnected) return false;\n const he = el;\n if (he.hidden || el.getAttribute(\"aria-hidden\") === \"true\") return false;\n const rect = he.getBoundingClientRect();\n if (rect.width === 0 && rect.height === 0) return false;\n const cs = window.getComputedStyle(he);\n return cs.visibility !== \"hidden\" && cs.display !== \"none\" && cs.opacity !== \"0\";\n }\n\n // src/recorder/agent/dom-reaction.ts\n var INTERESTING = \"[data-testid], [data-test], [data-test-id], [data-cy], [id], [role], button, a[href]\";\n var OBSERVED_ATTRS = [\"class\", \"style\", \"hidden\", \"aria-hidden\"];\n var APPEAR_CONFIRM_MS = 600;\n function toCssSelector(selector) {\n if (selector.startsWith(\"role=\") || selector.startsWith(\"text=\")) {\n throw new Error(\"not a CSS selector\");\n }\n return selector;\n }\n function harvest(nodes, into, pick, revealed, max) {\n for (let i = 0; i < nodes.length; i++) {\n const node = nodes[i];\n if (!node || node.nodeType !== 1) continue;\n const el = node;\n revealed.push(el);\n const own = pick(el);\n if (own && into.size < max) into.add(own);\n const descendants = el.querySelectorAll(INTERESTING);\n for (let j = 0; j < descendants.length && into.size < max; j++) {\n const d = descendants[j];\n if (!d) continue;\n const sel = pick(d);\n if (sel) into.add(sel);\n }\n }\n }\n function observeDomReactions(ctx) {\n const { config, transport, reveals } = ctx;\n const visibility = /* @__PURE__ */ new WeakMap();\n let pending = [];\n const stillVisible = (sel) => {\n try {\n const el = document.querySelector(toCssSelector(sel));\n return el ? isVisible(el) : false;\n } catch {\n return true;\n }\n };\n const confirm = (entry) => {\n const survived = entry.selectors.filter(stillVisible);\n if (survived.length) {\n transport.emit({ kind: \"dom\", appeared: survived, gone: [], t: entry.at });\n }\n };\n const flushAppearances = () => {\n const due = pending;\n pending = [];\n for (const entry of due) {\n clearTimeout(entry.timer);\n confirm(entry);\n }\n };\n const visibleAppearedSelector = (el) => {\n if (!isVisible(el)) return null;\n if (isTransientIndicator(getRole(el), accessibleName(el))) return null;\n return appearedSelector(el);\n };\n const start = () => {\n const observer = new MutationObserver((records) => {\n const appeared = /* @__PURE__ */ new Set();\n const gone = /* @__PURE__ */ new Set();\n const revealed = [];\n for (const rec of records) {\n if (rec.type === \"childList\") {\n harvest(rec.addedNodes, appeared, visibleAppearedSelector, revealed, config.maxSelectorsPerMutation);\n harvest(rec.removedNodes, gone, goneSelector, [], config.maxSelectorsPerMutation);\n continue;\n }\n const el = rec.target;\n const sel = appearedSelector(el);\n if (!sel) continue;\n const now = isVisible(el);\n const was = visibility.get(el);\n visibility.set(el, now);\n if (was === void 0 || was === now) continue;\n if (now) {\n appeared.add(sel);\n revealed.push(el);\n } else {\n const g = goneSelector(el);\n if (g) gone.add(g);\n }\n }\n const at = Date.now();\n reveals.noteRevealed(revealed, at);\n if (gone.size) {\n transport.emit({ kind: \"dom\", appeared: [], gone: Array.from(gone), t: at });\n }\n if (appeared.size) {\n const entry = {\n selectors: Array.from(appeared),\n at,\n timer: setTimeout(() => {\n pending = pending.filter((e) => e !== entry);\n confirm(entry);\n }, APPEAR_CONFIRM_MS)\n };\n pending.push(entry);\n }\n });\n observer.observe(document.documentElement, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: OBSERVED_ATTRS\n });\n };\n if (document.documentElement) start();\n else document.addEventListener(\"DOMContentLoaded\", start, { once: true });\n return { flushAppearances };\n }\n\n // src/recorder/agent/reveal-tracker.ts\n var ACTION_COOLDOWN_MS = 600;\n function createRevealTracker(config) {\n let pending = null;\n let lastHovered = null;\n let lastActionAt = 0;\n return {\n noteHover(el) {\n lastHovered = el;\n },\n noteAction(at) {\n lastActionAt = at;\n },\n noteRevealed(nodes, at) {\n if (!nodes.length || !lastHovered) return;\n if (at - lastActionAt <= ACTION_COOLDOWN_MS) return;\n pending = { el: lastHovered, nodes, at };\n },\n takeLoadBearingHover(actionTarget) {\n const reveal = pending;\n pending = null;\n if (!reveal || !actionTarget) return null;\n if (Date.now() - reveal.at > config.hoverRevealWindowMs) return null;\n if (!reveal.el.isConnected) return null;\n const inside = reveal.nodes.some((n) => n === actionTarget || n.contains(actionTarget));\n return inside ? reveal.el : null;\n }\n };\n }\n\n // src/recorder/agent/transport.ts\n var DRAIN_INTERVAL_MS = 25;\n function createTransport(config) {\n const globals = window;\n const pending = [];\n let drainTimer = null;\n function binding(name) {\n const fn = globals[name];\n return typeof fn === \"function\" ? fn : null;\n }\n function drain() {\n const fn = binding(config.emitBinding);\n if (!fn) return;\n while (pending.length) {\n const ev = pending.shift();\n try {\n fn(ev);\n } catch {\n }\n }\n if (drainTimer) {\n clearInterval(drainTimer);\n drainTimer = null;\n }\n }\n function emit(ev) {\n pending.push(ev);\n if (binding(config.emitBinding)) drain();\n else if (!drainTimer) drainTimer = setInterval(drain, DRAIN_INTERVAL_MS);\n }\n return { emit, binding };\n }\n\n // src/recorder/agent/page-agent.ts\n var INSTALLED_FLAG = \"__replayAgentInstalled\";\n function pageAgent(config) {\n const globals = window;\n if (globals[INSTALLED_FLAG]) return;\n if (window.top !== window) return;\n globals[INSTALLED_FLAG] = true;\n const transport = createTransport(config);\n const reveals = createRevealTracker(config);\n const dom = observeDomReactions({ config, transport, reveals });\n installCapture({ config, transport, reveals, beforeAction: () => dom.flushAppearances() });\n globals[FLUSH_GLOBAL] = () => dom.flushAppearances();\n globals[AGENT_READY_FLAG] = true;\n }\n\n // src/recorder/agent/main.ts\n window[INSTALL_GLOBAL] = (config) => {\n pageAgent(config);\n };\n})();\n";
|
|
6
6
|
//# sourceMappingURL=agent-bundle.generated.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-bundle.generated.js","sourceRoot":"","sources":["../../src/recorder/agent-bundle.generated.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,6EAA6E;AAC7E,oBAAoB;AAEpB,+DAA+D;AAC/D,MAAM,CAAC,MAAM,YAAY,GAAG,
|
|
1
|
+
{"version":3,"file":"agent-bundle.generated.js","sourceRoot":"","sources":["../../src/recorder/agent-bundle.generated.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,6EAA6E;AAC7E,oBAAoB;AAEpB,+DAA+D;AAC/D,MAAM,CAAC,MAAM,YAAY,GAAG,o+3BAAo+3B,CAAC"}
|
package/dist/recorder/types.d.ts
CHANGED
|
@@ -13,6 +13,34 @@ export interface Resolved {
|
|
|
13
13
|
/** Index into target.candidates, so callers can report degraded resolution. */
|
|
14
14
|
candidateIndex: number;
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* The selector resolved, but to something that is not what was recorded.
|
|
18
|
+
*
|
|
19
|
+
* Distinct from "nothing matched": the app is reachable and the flow could
|
|
20
|
+
* continue, but continuing would act on the wrong record and produce a verdict
|
|
21
|
+
* about a bug that was never exercised.
|
|
22
|
+
*/
|
|
23
|
+
export declare class IdentityMismatchError extends Error {
|
|
24
|
+
readonly target: Target;
|
|
25
|
+
readonly selector: string;
|
|
26
|
+
readonly found: string;
|
|
27
|
+
constructor(target: Target, selector: string, found: string);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Normalised, forgiving comparison.
|
|
31
|
+
*
|
|
32
|
+
* Either side containing the other counts: a row's text includes the name plus
|
|
33
|
+
* whatever else the row renders, and an accessible name is often a fragment of
|
|
34
|
+
* the visible label. Requiring equality would refuse constantly.
|
|
35
|
+
*/
|
|
36
|
+
export declare function identityMatches(found: string, identity: string): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Identities too weak to judge by.
|
|
39
|
+
*
|
|
40
|
+
* A bare number or a one-word label appears all over a page, so a mismatch
|
|
41
|
+
* would say nothing — and a check that refuses on noise gets switched off.
|
|
42
|
+
*/
|
|
43
|
+
export declare function isCheckableIdentity(identity: string | undefined): identity is string;
|
|
16
44
|
export declare class TargetResolutionError extends Error {
|
|
17
45
|
readonly target: Target;
|
|
18
46
|
readonly attempts: {
|
package/dist/replayer/resolve.js
CHANGED
|
@@ -1,4 +1,53 @@
|
|
|
1
1
|
export const DEFAULT_RESOLVE_TIMEOUTS = { first: 800, subsequent: 400 };
|
|
2
|
+
/**
|
|
3
|
+
* The selector resolved, but to something that is not what was recorded.
|
|
4
|
+
*
|
|
5
|
+
* Distinct from "nothing matched": the app is reachable and the flow could
|
|
6
|
+
* continue, but continuing would act on the wrong record and produce a verdict
|
|
7
|
+
* about a bug that was never exercised.
|
|
8
|
+
*/
|
|
9
|
+
export class IdentityMismatchError extends Error {
|
|
10
|
+
target;
|
|
11
|
+
selector;
|
|
12
|
+
found;
|
|
13
|
+
constructor(target, selector, found) {
|
|
14
|
+
super(`Selector ${selector} matched an element that is not "${target.identity}".\n` +
|
|
15
|
+
` Expected to act on: ${target.semantic}\n` +
|
|
16
|
+
` Actually found: ${found || '(no text)'}\n` +
|
|
17
|
+
` Acting on it would produce a verdict about the wrong record.`);
|
|
18
|
+
this.target = target;
|
|
19
|
+
this.selector = selector;
|
|
20
|
+
this.found = found;
|
|
21
|
+
this.name = 'IdentityMismatchError';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Normalised, forgiving comparison.
|
|
26
|
+
*
|
|
27
|
+
* Either side containing the other counts: a row's text includes the name plus
|
|
28
|
+
* whatever else the row renders, and an accessible name is often a fragment of
|
|
29
|
+
* the visible label. Requiring equality would refuse constantly.
|
|
30
|
+
*/
|
|
31
|
+
export function identityMatches(found, identity) {
|
|
32
|
+
const norm = (v) => v.replace(/\s+/g, ' ').trim().toLowerCase();
|
|
33
|
+
const a = norm(found);
|
|
34
|
+
const b = norm(identity);
|
|
35
|
+
if (!a || !b)
|
|
36
|
+
return true;
|
|
37
|
+
return a.includes(b) || b.includes(a);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Identities too weak to judge by.
|
|
41
|
+
*
|
|
42
|
+
* A bare number or a one-word label appears all over a page, so a mismatch
|
|
43
|
+
* would say nothing — and a check that refuses on noise gets switched off.
|
|
44
|
+
*/
|
|
45
|
+
export function isCheckableIdentity(identity) {
|
|
46
|
+
if (!identity)
|
|
47
|
+
return false;
|
|
48
|
+
const trimmed = identity.trim();
|
|
49
|
+
return trimmed.length >= 4 && /[a-z]/i.test(trimmed);
|
|
50
|
+
}
|
|
2
51
|
export class TargetResolutionError extends Error {
|
|
3
52
|
target;
|
|
4
53
|
attempts;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/replayer/resolve.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,MAAM,wBAAwB,GAAoB,EAAE,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC;AASzF,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAEnC;IACA;IAFX,YACW,MAAc,EACd,QAA+C;QAExD,KAAK,CAAC,kBAAkB,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;QAHlC,WAAM,GAAN,MAAM,CAAQ;QACd,aAAQ,GAAR,QAAQ,CAAuC;QAGxD,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;IACtC,CAAC;CACF;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAU,EACV,MAAc,EACd,WAA4B,wBAAwB,EACpD,WAAoE;IAEpE,MAAM,QAAQ,GAA0C,EAAE,CAAC;IAE3D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACtC,IAAI,CAAC,QAAQ;YAAE,SAAS;QACxB,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC;QAC/D,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,CAAC;YAC/C,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC;YACrD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,CAAC,EAAE,CAAC;QAClD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC/C,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,CAAC;YAC7C,MAAM,OAAO,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;YACrE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC,EAAE,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,MAAM,IAAI,qBAAqB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AACpD,CAAC;AAED,SAAS,SAAS,CAAC,GAAY;IAC7B,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7D,OAAO,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;AACnC,CAAC"}
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/replayer/resolve.ts"],"names":[],"mappings":"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"}
|
package/dist/replayer/run.js
CHANGED
|
@@ -8,7 +8,7 @@ import { reproPaths } from '../ir/io.js';
|
|
|
8
8
|
import { collectReactions } from '../recorder/reaction.js';
|
|
9
9
|
import { writeFailureArtifacts } from './artifacts.js';
|
|
10
10
|
import { checkBugRecurred, checkInvariants, hasBugSignature, hasFixCriterion, } from './invariants.js';
|
|
11
|
-
import { DEFAULT_RESOLVE_TIMEOUTS, resolveTarget, TargetResolutionError, } from './resolve.js';
|
|
11
|
+
import { DEFAULT_RESOLVE_TIMEOUTS, identityMatches, IdentityMismatchError, isCheckableIdentity, resolveTarget, TargetResolutionError, } from './resolve.js';
|
|
12
12
|
import { retargetRepro, retargetStorageState } from './retarget.js';
|
|
13
13
|
import { createExpander } from './values.js';
|
|
14
14
|
import { waitForReaction } from './waits.js';
|
|
@@ -458,7 +458,10 @@ function expectationOf(step) {
|
|
|
458
458
|
}
|
|
459
459
|
/** Performs one step; returns which candidate selector worked (-1 when targetless). */
|
|
460
460
|
async function performStep(page, step, baseUrl, options, expand) {
|
|
461
|
-
|
|
461
|
+
// Derived from what this step actually measured, not from a constant. A flat
|
|
462
|
+
// 800ms is wrong by more than an order of magnitude on a heavy app, and
|
|
463
|
+
// guessing the first budget contradicts the rule every other wait follows.
|
|
464
|
+
const timeouts = options.resolveTimeouts ?? deriveResolveTimeouts(step);
|
|
462
465
|
if (step.action === 'goto') {
|
|
463
466
|
await page.goto(rebase(step.value, baseUrl), { waitUntil: 'domcontentloaded' });
|
|
464
467
|
return -1;
|
|
@@ -480,6 +483,28 @@ async function performStep(page, step, baseUrl, options, expand) {
|
|
|
480
483
|
};
|
|
481
484
|
const resolved = await resolveTarget(page, target, timeouts, options.onStepFailure);
|
|
482
485
|
const { locator } = resolved;
|
|
486
|
+
// Confirm the element we found is the one that was recorded, before doing
|
|
487
|
+
// anything to it. A selector that drifts onto a neighbouring row still
|
|
488
|
+
// resolves, still clicks, and still produces a well-formed verdict — about
|
|
489
|
+
// the wrong record.
|
|
490
|
+
const identity = expand.expand(target.identity);
|
|
491
|
+
if (isCheckableIdentity(identity)) {
|
|
492
|
+
// The control's own label and the row it sits in, together. A "Remove"
|
|
493
|
+
// button reads the same on every row, so its own text can neither confirm
|
|
494
|
+
// nor deny which record it belongs to — only the row can. Checking just one
|
|
495
|
+
// of the two would refuse on every correct list row.
|
|
496
|
+
const found = await locator
|
|
497
|
+
.evaluate((el) => {
|
|
498
|
+
const self = el.innerText || el.textContent || '';
|
|
499
|
+
const row = el.closest('tr, [role="row"], li, [role="listitem"], [data-testid*="row"], [data-testid*="Row"]');
|
|
500
|
+
const context = row && row !== el ? (row.innerText ?? '') : '';
|
|
501
|
+
return `${self} ${context}`;
|
|
502
|
+
})
|
|
503
|
+
.catch(() => '');
|
|
504
|
+
if (!identityMatches(found, identity)) {
|
|
505
|
+
throw new IdentityMismatchError(target, resolved.selector, found.replace(/\s+/g, ' ').trim());
|
|
506
|
+
}
|
|
507
|
+
}
|
|
483
508
|
switch (step.action) {
|
|
484
509
|
case 'click':
|
|
485
510
|
await locator.click();
|
|
@@ -512,6 +537,17 @@ async function performStep(page, step, baseUrl, options, expand) {
|
|
|
512
537
|
}
|
|
513
538
|
return resolved.candidateIndex;
|
|
514
539
|
}
|
|
540
|
+
/**
|
|
541
|
+
* A selector budget proportional to how slowly this app was observed to react.
|
|
542
|
+
*
|
|
543
|
+
* A quarter of the step's own wait: long enough for a heavy app to render the
|
|
544
|
+
* control, short enough that a genuinely missing element fails fast instead of
|
|
545
|
+
* burning the whole budget on the first of five candidates.
|
|
546
|
+
*/
|
|
547
|
+
function deriveResolveTimeouts(step) {
|
|
548
|
+
const first = Math.min(15_000, Math.max(DEFAULT_RESOLVE_TIMEOUTS.first, Math.round(step.waitAfter.timeoutMs / 4)));
|
|
549
|
+
return { first, subsequent: Math.max(DEFAULT_RESOLVE_TIMEOUTS.subsequent, Math.round(first / 2)) };
|
|
550
|
+
}
|
|
515
551
|
/** Re-point a recorded absolute URL at the base URL replay is actually using. */
|
|
516
552
|
function rebase(recorded, baseUrl) {
|
|
517
553
|
if (!recorded)
|
package/dist/replayer/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/replayer/run.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/replayer/run.ts"],"names":[],"mappings":"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"}
|