@enricai/barnacle 1.12.72 → 1.12.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/scraper/browser-click-expr.d.ts +68 -0
- package/dist/scraper/browser-click-expr.d.ts.map +1 -1
- package/dist/scraper/browser-click-expr.js +121 -1
- package/dist/scraper/browser-click-expr.js.map +1 -1
- package/dist/scraper/flow-runner.d.ts +62 -6
- package/dist/scraper/flow-runner.d.ts.map +1 -1
- package/dist/scraper/flow-runner.js +225 -51
- package/dist/scraper/flow-runner.js.map +1 -1
- package/dist/scraper/phantom-click.d.ts +8 -0
- package/dist/scraper/phantom-click.d.ts.map +1 -1
- package/dist/scraper/phantom-click.js +21 -1
- package/dist/scraper/phantom-click.js.map +1 -1
- package/dist/scraper/submit-control.d.ts.map +1 -1
- package/dist/scraper/submit-control.js +2 -19
- package/dist/scraper/submit-control.js.map +1 -1
- package/dist/scripts/recon-browser.d.ts +10 -2
- package/dist/scripts/recon-browser.d.ts.map +1 -1
- package/dist/scripts/recon-browser.js +93 -27
- package/dist/scripts/recon-browser.js.map +1 -1
- package/dist/scripts/recon-generate.d.ts.map +1 -1
- package/dist/scripts/recon-generate.js +65 -13
- package/dist/scripts/recon-generate.js.map +1 -1
- package/package.json +1 -1
|
@@ -40,6 +40,14 @@ export interface PhantomClickAttempt {
|
|
|
40
40
|
*/
|
|
41
41
|
isSubmitShapedStep?: boolean;
|
|
42
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Credits a navigation as real only when origin or pathname actually
|
|
45
|
+
* changed, so a same-page query-string mutation (e.g. a step counter) never
|
|
46
|
+
* counts as an advance. Shared by {@link classifyPhantomClick} and
|
|
47
|
+
* flow-runner's own urlChanged/retryUrlChanged checks so both agree on what
|
|
48
|
+
* counts as a genuine navigation.
|
|
49
|
+
*/
|
|
50
|
+
export declare function hasOriginOrPathChanged(preUrl: string, postUrl: string): boolean;
|
|
43
51
|
export type PhantomClickVerdict =
|
|
44
52
|
/** Stagehand reported success but pre/post shows no observable effect — a no-op click. */
|
|
45
53
|
"phantom"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"phantom-click.d.ts","sourceRoot":"","sources":["../../src/scraper/phantom-click.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,qFAAqF;AACrF,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,wCAAwC;IACxC,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,yEAAyE;IACzE,gBAAgB,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,GAAG,EAAE,oBAAoB,CAAC;IAC1B,IAAI,EAAE,oBAAoB,CAAC;IAC3B;;;;;;;;;;OAUG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,MAAM,mBAAmB;AAC7B,0FAA0F;AACxF,SAAS;AACX,mEAAmE;GACjE,WAAW;AACb,kKAAkK;GAChK,YAAY,CAAC;AAEjB;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,mBAAmB,CAyBtF"}
|
|
1
|
+
{"version":3,"file":"phantom-click.d.ts","sourceRoot":"","sources":["../../src/scraper/phantom-click.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,qFAAqF;AACrF,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,wCAAwC;IACxC,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,yEAAyE;IACzE,gBAAgB,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,GAAG,EAAE,oBAAoB,CAAC;IAC1B,IAAI,EAAE,oBAAoB,CAAC;IAC3B;;;;;;;;;;OAUG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAWD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAE/E;AAED,MAAM,MAAM,mBAAmB;AAC7B,0FAA0F;AACxF,SAAS;AACX,mEAAmE;GACjE,WAAW;AACb,kKAAkK;GAChK,YAAY,CAAC;AAEjB;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,mBAAmB,GAAG,mBAAmB,CAyBtF"}
|
|
@@ -8,7 +8,27 @@
|
|
|
8
8
|
*/
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.TRIVIAL_DOM_DELTA_BYTES = void 0;
|
|
11
|
+
exports.hasOriginOrPathChanged = hasOriginOrPathChanged;
|
|
11
12
|
exports.classifyPhantomClick = classifyPhantomClick;
|
|
13
|
+
function originAndPathOf(url) {
|
|
14
|
+
try {
|
|
15
|
+
const parsed = new URL(url);
|
|
16
|
+
return `${parsed.origin}${parsed.pathname}`;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return url;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Credits a navigation as real only when origin or pathname actually
|
|
24
|
+
* changed, so a same-page query-string mutation (e.g. a step counter) never
|
|
25
|
+
* counts as an advance. Shared by {@link classifyPhantomClick} and
|
|
26
|
+
* flow-runner's own urlChanged/retryUrlChanged checks so both agree on what
|
|
27
|
+
* counts as a genuine navigation.
|
|
28
|
+
*/
|
|
29
|
+
function hasOriginOrPathChanged(preUrl, postUrl) {
|
|
30
|
+
return originAndPathOf(preUrl) !== originAndPathOf(postUrl);
|
|
31
|
+
}
|
|
12
32
|
/**
|
|
13
33
|
* Bytes of body-HTML growth treated as noise rather than a real DOM effect.
|
|
14
34
|
* Reused from `describeAttemptEffectSignals`'s dom-grew-without-network
|
|
@@ -30,7 +50,7 @@ function classifyPhantomClick(attempt) {
|
|
|
30
50
|
return "unresolved";
|
|
31
51
|
const networkDelta = attempt.post.networkCount - attempt.pre.networkCount;
|
|
32
52
|
const bytesDelta = attempt.post.bodyHtmlLength - attempt.pre.bodyHtmlLength;
|
|
33
|
-
const urlChanged = attempt.
|
|
53
|
+
const urlChanged = hasOriginOrPathChanged(attempt.pre.url, attempt.post.url);
|
|
34
54
|
// The resolved element's OWN committed selection state changed across the
|
|
35
55
|
// click — a design-system option/toggle (Base Web `kind` flip, hashed-class
|
|
36
56
|
// swap, ARIA, native `checked`) registers here with no network, no URL, and a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"phantom-click.js","sourceRoot":"","sources":["../../src/scraper/phantom-click.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG
|
|
1
|
+
{"version":3,"file":"phantom-click.js","sourceRoot":"","sources":["../../src/scraper/phantom-click.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;;;AAuCH,SAAS,eAAe,CAAC,GAAW;IAClC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC5B,OAAO,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,gCAAuC,MAAc,EAAE,OAAe;IACpE,OAAO,eAAe,CAAC,MAAM,CAAC,KAAK,eAAe,CAAC,OAAO,CAAC,CAAC;AAC9D,CAAC;AAUD;;;;;;GAMG;AACU,QAAA,uBAAuB,GAAG,GAAG,CAAC;AAE3C;;;;;;;GAOG;AACH,8BAAqC,OAA4B;IAC/D,IAAI,OAAO,CAAC,gBAAgB,KAAK,IAAI;QAAE,OAAO,YAAY,CAAC;IAE3D,MAAM,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IAC1E,MAAM,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IAC5E,MAAM,UAAU,GAAG,sBAAsB,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC7E,0EAA0E;IAC1E,4EAA4E;IAC5E,8EAA8E;IAC9E,uEAAuE;IACvE,+EAA+E;IAC/E,8EAA8E;IAC9E,8EAA8E;IAC9E,+EAA+E;IAC/E,2DAA2D;IAC3D,MAAM,mBAAmB,GAAG,CAAC,OAAO,CAAC,kBAAkB,IAAI,OAAO,CAAC,mBAAmB,KAAK,IAAI,CAAC;IAChG,8EAA8E;IAC9E,4EAA4E;IAC5E,6CAA6C;IAC7C,MAAM,yBAAyB,GAC7B,CAAC,OAAO,CAAC,kBAAkB,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,QAAA,uBAAuB,CAAC;IAEjF,MAAM,SAAS,GACb,YAAY,KAAK,CAAC,IAAI,UAAU,IAAI,mBAAmB,IAAI,yBAAyB,CAAC;IACvF,OAAO,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submit-control.d.ts","sourceRoot":"","sources":["../../src/scraper/submit-control.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;
|
|
1
|
+
{"version":3,"file":"submit-control.d.ts","sourceRoot":"","sources":["../../src/scraper/submit-control.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAQH;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,sOAG5B,CAAC;AA4DJ;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,0BAA0B,s4CAyBpC,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,iBAAiB,uoEAQ3B,CAAC;AA+CJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,SAAa,GAAG,MAAM,CA0BvE;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,SAAa,GAAG,MAAM,CAYtF;AAED,2HAA2H;AAC3H,MAAM,MAAM,mBAAmB,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAElD,qGAAqG;AACrG,MAAM,WAAW,eAAe;IAC9B,mIAAmI;IACnI,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,0EAA0E;AAC1E,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,oKAAoK;IACpK,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B"}
|
|
@@ -83,23 +83,6 @@ const IS_DISABLED_EXPR = `((el) => {
|
|
|
83
83
|
}
|
|
84
84
|
return false;
|
|
85
85
|
})`;
|
|
86
|
-
/**
|
|
87
|
-
* Recursive open-shadow-root walker, composed as a browser-context
|
|
88
|
-
* expression string via string interpolation rather than runtime code that
|
|
89
|
-
* could share a module import.
|
|
90
|
-
*/
|
|
91
|
-
const DEEP_ELEMENTS_EXPR = `((root) => {
|
|
92
|
-
const out = [];
|
|
93
|
-
const walk = (node) => {
|
|
94
|
-
const kids = node.querySelectorAll ? Array.from(node.querySelectorAll("*")) : [];
|
|
95
|
-
for (const el of kids) {
|
|
96
|
-
out.push(el);
|
|
97
|
-
if (el.shadowRoot) walk(el.shadowRoot);
|
|
98
|
-
}
|
|
99
|
-
};
|
|
100
|
-
walk(root);
|
|
101
|
-
return out;
|
|
102
|
-
})`;
|
|
103
86
|
/**
|
|
104
87
|
* Tag/role-agnostic tier-0.5 fallback: a generic-action-verb accessible name
|
|
105
88
|
* (create/continue/next/confirm/proceed — the labels a JS-handled action
|
|
@@ -252,7 +235,7 @@ function buildRankSubmitCandidatesExpr(root = "document") {
|
|
|
252
235
|
const rankTier = ${RANK_TIERS_EXPR};
|
|
253
236
|
const isVisible = ${IS_VISIBLE_EXPR};
|
|
254
237
|
const isDisabled = ${IS_DISABLED_EXPR};
|
|
255
|
-
const deepElements = ${DEEP_ELEMENTS_EXPR};
|
|
238
|
+
const deepElements = ${browser_click_expr_1.DEEP_ELEMENTS_EXPR};
|
|
256
239
|
const all = deepElements(${root});
|
|
257
240
|
const ranked = [];
|
|
258
241
|
for (let i = 0; i < all.length; i++) {
|
|
@@ -301,7 +284,7 @@ function buildClickByDeepIndexExpr(deepIndex, root = "document") {
|
|
|
301
284
|
return `(() => {
|
|
302
285
|
const isVisible = ${IS_VISIBLE_EXPR};
|
|
303
286
|
const isDisabled = ${IS_DISABLED_EXPR};
|
|
304
|
-
const deepElements = ${DEEP_ELEMENTS_EXPR};
|
|
287
|
+
const deepElements = ${browser_click_expr_1.DEEP_ELEMENTS_EXPR};
|
|
305
288
|
const all = deepElements(${root});
|
|
306
289
|
const el = all[${JSON.stringify(deepIndex)}];
|
|
307
290
|
if (!el) return { clicked: false };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submit-control.js","sourceRoot":"","sources":["../../src/scraper/submit-control.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;AAEH,
|
|
1
|
+
{"version":3,"file":"submit-control.js","sourceRoot":"","sources":["../../src/scraper/submit-control.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;;;AAEH,qEAIsC;AAEtC;;;;;;;;;GASG;AACU,QAAA,kBAAkB,GAAG;;;GAG/B,CAAC;AAEJ;;;;;;;;GAQG;AACH,MAAM,oBAAoB,GAAG;;;;;GAK1B,CAAC;AAEJ;;;;;;;;;;GAUG;AACH,MAAM,eAAe,GAAG;;;;;GAKrB,CAAC;AAEJ;;;;;;;;;;;;;;GAcG;AACH,MAAM,gBAAgB,GAAG;gCACO,iDAA4B;;;;;;GAMzD,CAAC;AAEJ;;;;;;;;;;;;;;;GAeG;AACU,QAAA,0BAA0B,GAAG;;;;;;;kCAOR,iDAA4B;;;;;;;;2BAQnC,oBAAoB;;;;;;;;;;GAU5C,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;GAoBG;AACU,QAAA,iBAAiB,GAAG;;uBAEV,QAAA,kBAAkB;2BACd,oBAAoB;;;6BAGlB,QAAA,0BAA0B;;GAEpD,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,eAAe,GAAG;uBACD,QAAA,kBAAkB;;;;;;;;;;6BAUZ,QAAA,0BAA0B;;;GAGpD,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,uCAA8C,IAAI,GAAG,UAAU;IAC7D,OAAO;6BACoB,oBAAoB;uBAC1B,eAAe;wBACd,eAAe;yBACd,gBAAgB;2BACd,uCAAkB;+BACd,IAAI;;;;;;;;;;;;;;;;;;OAkB5B,CAAC;AACR,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,mCAA0C,SAAiB,EAAE,IAAI,GAAG,UAAU;IAC5E,OAAO;wBACe,eAAe;yBACd,gBAAgB;2BACd,uCAAkB;+BACd,IAAI;qBACd,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC;;;MAGxC,IAAA,wCAAmB,EAAC,IAAI,CAAC;;OAExB,CAAC;AACR,CAAC"}
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
import type Anthropic from "@anthropic-ai/sdk";
|
|
50
50
|
import type { Action, LoadState, Page, Stagehand } from "@browserbasehq/stagehand";
|
|
51
51
|
import { z } from "zod/v4";
|
|
52
|
-
import { type AttemptRecord, type CaptureFn, type EmailStepConfig } from "../scraper/flow-runner";
|
|
52
|
+
import { type AttemptRecord, type CaptureFn, type EmailStepConfig, type FieldValueAtFailure } from "../scraper/flow-runner";
|
|
53
53
|
import { type ProviderName } from "../scraper/session";
|
|
54
54
|
import type { TargetResolutionDiagnosticSnapshot } from "../scraper/target-resolution-diagnostic";
|
|
55
55
|
import type { Logger } from "../types/logging";
|
|
@@ -383,7 +383,7 @@ export declare function dedupeIdenticalSteps<T>(items: T[]): T[];
|
|
|
383
383
|
* wins.
|
|
384
384
|
*/
|
|
385
385
|
export declare function dedupeReplanStepsByTarget(steps: NormalizedStep[]): NormalizedStep[];
|
|
386
|
-
export declare function filterCompletedFromReplan(newSteps: readonly NormalizedStep[], completedSteps: readonly string[], failedStep: string, bodyHtmlAtFailure?: string | null): NormalizedStep[];
|
|
386
|
+
export declare function filterCompletedFromReplan(newSteps: readonly NormalizedStep[], completedSteps: readonly string[], failedStep: string, bodyHtmlAtFailure?: string | null, fieldValuesAtFailure?: readonly FieldValueAtFailure[] | null): NormalizedStep[];
|
|
387
387
|
/**
|
|
388
388
|
* Extract the field names a submit-judge rejection explicitly names as
|
|
389
389
|
* still-required, e.g. from `submit-judge-rejected: Form still displays
|
|
@@ -682,6 +682,14 @@ declare function dumpStepFailure(params: {
|
|
|
682
682
|
* page unprompted. Complements `finalObserve` (which is observe-with-step).
|
|
683
683
|
*/
|
|
684
684
|
unfocusedObserve: Action[];
|
|
685
|
+
/**
|
|
686
|
+
* Live label-keyed field values at failure time (see
|
|
687
|
+
* {@link fieldValuesAtFailureExpr}) — persisted so {@link filterCompletedFromReplan}'s
|
|
688
|
+
* resume-from-failure check can source a fill's VALUE from a signal that
|
|
689
|
+
* can actually reflect a DOM-direct `.value =` write, which `bodyOuterHtml`
|
|
690
|
+
* structurally cannot. `null` when the capture itself failed.
|
|
691
|
+
*/
|
|
692
|
+
fieldValuesAtFailure: FieldValueAtFailure[] | null;
|
|
685
693
|
/**
|
|
686
694
|
* Bounded snapshot of the submit-shaped candidate ranking at the moment
|
|
687
695
|
* resolution gave up, or `null` when the capture itself failed on the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"recon-browser.d.ts","sourceRoot":"","sources":["../../src/scripts/recon-browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAMH,OAAO,KAAK,SAAS,MAAM,mBAAmB,CAAC;AAE/C,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAGnF,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AA4B3B,OAAO,EACL,KAAK,aAAa,EAElB,KAAK,SAAS,EAEd,KAAK,eAAe,
|
|
1
|
+
{"version":3,"file":"recon-browser.d.ts","sourceRoot":"","sources":["../../src/scripts/recon-browser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAMH,OAAO,KAAK,SAAS,MAAM,mBAAmB,CAAC;AAE/C,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAGnF,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AA4B3B,OAAO,EACL,KAAK,aAAa,EAElB,KAAK,SAAS,EAEd,KAAK,eAAe,EAKpB,KAAK,mBAAmB,EAgBzB,MAAM,uBAAuB,CAAC;AAQ/B,OAAO,EAAwB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAI5E,OAAO,KAAK,EAAE,kCAAkC,EAAE,MAAM,wCAAwC,CAAC;AAMjG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAM9C,UAAU,WAAW;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,cAAc,GAAG,mBAAmB,CAAC;IAC5C,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,cAAc,EAAE,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,SAAS,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CAChD;AAoED;;;;;;;;;GASG;AACH,iBAAe,2BAA2B,CACxC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE;IAAE,CAAC,EAAE,MAAM,CAAA;CAAE,EACtB,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,GAAE,MAAe,GAAG,SAAS,CAQ7F;AAiBD,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,OAAO,GAAG;IAC5D,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CA4BA;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE;IACtC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB,EAAE,OAAO,CAAC;CACjC,GAAG,OAAO,CAEV;AA+GD;;;;;;;;;;;;;;GAcG;AACH,iBAAS,mBAAmB,CAAC,MAAM,EAAE;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,IAAI,CAuCP;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wBAAwB,EAAE,SAAS,MAAM,EAAE,CAAC;CAC7C,GAAG,MAAM,GAAG,IAAI,CAmBhB;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,SAAS;IACjB,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B,EAAE,GACF,OAAO,CAGT;AAED,wBAAgB,2BAA2B,CAAC,MAAM,EAAE;IAClD,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAoBT;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,YAAY,EAAE,SAAS,WAAW,EAAE,EACpC,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,YAAY,EAAE;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAChD,OAAO,CAaT;AAED,QAAA,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAAyC,CAAC;AAEjE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAwIjC,CAAC;AAEH;;;;;;;GAOG;AACH,UAAU,cAAc;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;IAOhB,UAAU,CAAC,EAAE,OAAO,CAAC;IAIrB,YAAY,CAAC,EAAE,OAAO,CAAC;IAIvB,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB,eAAe,CAAC,EAAE,eAAe,CAAC;IAMlC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAI3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,UAAU,GAAG,QAAQ,CAAC;IAI9B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,iBAAS,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,GAAG,cAAc,EAAE,CAoBjF;AAuBD;;;;;GAKG;AACH,iBAAS,eAAe,CAAC,IAAI,EAAE,cAAc,GACzC,MAAM,GACN;IACE,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,UAAU,CAAC,EAAE,IAAI,CAAC;IAClB,YAAY,CAAC,EAAE,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAgDJ;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAUvD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAWnF;AAuID,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,cAAc,EAAE,SAAS,MAAM,EAAE,EACjC,UAAU,EAAE,MAAM,EAClB,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,EACjC,oBAAoB,CAAC,EAAE,SAAS,mBAAmB,EAAE,GAAG,IAAI,GAC3D,cAAc,EAAE,CA+BlB;AA4BD;;;;;;;;;;GAUG;AACH,wBAAgB,gCAAgC,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,CAUrF;AA4DD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,wCAAwC,CACtD,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,UAAU,EAAE,cAAc,GACzB,cAAc,EAAE,CAkBlB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mCAAmC,CACjD,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,iBAAiB,EAAE,SAAS,cAAc,EAAE,GAC3C,cAAc,EAAE,CAMlB;AA0BD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,UAAU,EAAE,MAAM,GACjB,OAAO,CAMT;AAgBD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,8BAA8B,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAKhG;AAaD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oCAAoC,CAClD,QAAQ,EAAE,SAAS,cAAc,EAAE,EACnC,cAAc,EAAE,SAAS,MAAM,EAAE,GAChC,OAAO,CAUT;AAcD;;;;;;;;GAQG;AACH,wBAAgB,6BAA6B,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAG1E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,SAAS,cAAc,EAAE,GAC/B,cAAc,EAAE,CAIlB;AAqCD;;;;;;;;;;;GAWG;AACH,iBAAS,oBAAoB,CAAC,MAAM,EAAE;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;IACnC,wEAAwE;IACxE,qBAAqB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,qFAAqF;IACrF,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,4FAA4F;IAC5F,0BAA0B,CAAC,EAAE,OAAO,CAAC;IACrC,oGAAoG;IACpG,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,uGAAuG;IACvG,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,oGAAoG;IACpG,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,uGAAuG;IACvG,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;CACpC,GAAG,IAAI,CAqGP;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7C,MAAM,CAkBR;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,sBAAsB,CACpC,iBAAiB,EAAE,MAAM,EACzB,YAAY,EAAE,SAAS,WAAW,EAAE,GACnC,MAAM,CAcR;AAED,iBAAe,uBAAuB,CACpC,eAAe,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE;IACR,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAC1B,uBAAuB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ;;;;;;OAMG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,GACA,OAAO,CAAC;IACT,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC,CAAC,CAmFD;AAED;;;;GAIG;AACH,iBAAe,mBAAmB,CAAC,MAAM,EAAE;IACzC,MAAM,EAAE,SAAS,CAAC;IAClB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,IAAI,CAAC;IACX,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;;OAIG;IACH,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC;;;;;;OAMG;IACH,mBAAmB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACxC;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5C;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,SAAS;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,aAAa,CAAC,YAAY,CAAC,CAAA;KAAE,EAAE,CAAC;IACvF;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;CACvC,GAAG,OAAO,CAAC,cAAc,EAAE,GAAG,IAAI,CAAC,CAgVnC;AAiCD,iBAAS,eAAe,CAAC,MAAM,EAAE;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB;;;;;OAKG;IACH,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;;OAGG;IACH,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B;;;;;;OAMG;IACH,oBAAoB,EAAE,mBAAmB,EAAE,GAAG,IAAI,CAAC;IACnD;;;;;OAKG;IACH,0BAA0B,EAAE,kCAAkC,GAAG,IAAI,CAAC;CACvE,GAAG,MAAM,CAsBT;AAmCD,iBAAS,QAAQ,IAAI;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,YAAY,GAAG,SAAS,CAAC;IACnC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;IACzB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,uBAAuB,EAAE,MAAM,EAAE,CAAC;IAClC,0BAA0B,EAAE,OAAO,CAAC;IACpC,4BAA4B,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5C,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,uBAAuB,EAAE,MAAM,EAAE,CAAC;IAClC,sBAAsB,EAAE,MAAM,EAAE,CAAC;IACjC,wBAAwB,EAAE,MAAM,EAAE,CAAC;IACnC,aAAa,EAAE,OAAO,GAAG,QAAQ,CAAC;IAClC,cAAc,EAAE,OAAO,CAAC;CACzB,CAmNA;AA6BD,iBAAe,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CA+7BnC;AAgBD,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,mBAAmB,EACnB,uBAAuB,EACvB,wBAAwB,GACzB,MAAM,uBAAuB,CAAC;AAI/B,OAAO,EACL,iBAAiB,EACjB,kBAAkB,EAClB,0BAA0B,EAC1B,4BAA4B,EAC5B,sBAAsB,EACtB,4BAA4B,EAC5B,sBAAsB,EACtB,uBAAuB,EACvB,sBAAsB,EACtB,wBAAwB,EACxB,8BAA8B,EAC9B,yBAAyB,EACzB,gBAAgB,EAChB,aAAa,EACb,wBAAwB,EACxB,uBAAuB,EACvB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,kBAAkB,EAClB,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,eAAe,EACf,aAAa,EACb,0BAA0B,EAC1B,uBAAuB,EACvB,uBAAuB,EACvB,sBAAsB,EACtB,eAAe,EACf,6BAA6B,EAC7B,iBAAiB,EACjB,sBAAsB,EACtB,mBAAmB,EACnB,yBAAyB,EACzB,+BAA+B,EAC/B,kBAAkB,EAClB,qBAAqB,EACrB,0BAA0B,EAC1B,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,cAAc,EAAE,WAAW,EAAE,CAAC;AAI5C,OAAO,EACL,eAAe,EACf,eAAe,EACf,IAAI,EACJ,aAAa,EACb,QAAQ,EACR,oBAAoB,EACpB,uBAAuB,EACvB,mBAAmB,EACnB,2BAA2B,EAC3B,mBAAmB,GACpB,CAAC"}
|
|
@@ -812,10 +812,11 @@ function dedupeReplanStepsByTarget(steps) {
|
|
|
812
812
|
* named still holds its expected value — resolved by parsing
|
|
813
813
|
* `bodyHtmlAtFailure` into a DOM and matching the step's field label to a
|
|
814
814
|
* control's accessible name, the same field-label-first resolution the live
|
|
815
|
-
* page cascade uses.
|
|
816
|
-
*
|
|
817
|
-
* to
|
|
818
|
-
*
|
|
815
|
+
* page cascade uses. When the field's identity can't be resolved to a
|
|
816
|
+
* specific control — no field label parses, or no control's accessible name
|
|
817
|
+
* relates to it — the step is treated as stale (kept) rather than falling
|
|
818
|
+
* back to a whole-body value search, which is unsound whenever sibling
|
|
819
|
+
* fields are designed to share a value (e.g. password + confirm password).
|
|
819
820
|
*/
|
|
820
821
|
/** Whitespace-collapsed, lowercased comparison key, mirroring `flow-runner.ts`'s `normalizeFieldLabel`. */
|
|
821
822
|
function normalizeStaleFillLabel(text) {
|
|
@@ -856,6 +857,26 @@ function accessibleNameForControl(el, window) {
|
|
|
856
857
|
return wrappingLabel.textContent;
|
|
857
858
|
return el.getAttribute("name") || id || el.getAttribute("placeholder") || "";
|
|
858
859
|
}
|
|
860
|
+
/**
|
|
861
|
+
* Exact-then-substring normalized-label match shared by {@link resolveFieldElementValue}
|
|
862
|
+
* (parsed-DOM entries) and {@link resolveFieldValueFromCapture} (live-capture
|
|
863
|
+
* entries), mirroring `flow-runner.ts`'s `findDeepLocatorCandidateByFieldLabel`.
|
|
864
|
+
*/
|
|
865
|
+
function matchByNormalizedLabel(entries, normalizedLabel) {
|
|
866
|
+
const named = entries.filter((entry) => entry.text.length > 0);
|
|
867
|
+
const exact = named.find((entry) => entry.text === normalizedLabel);
|
|
868
|
+
if (exact)
|
|
869
|
+
return exact.value;
|
|
870
|
+
const candidates = named.filter((entry) => entry.text.includes(normalizedLabel) || normalizedLabel.includes(entry.text));
|
|
871
|
+
const mostSpecific = candidates.reduce((closest, entry) => {
|
|
872
|
+
if (!closest)
|
|
873
|
+
return entry;
|
|
874
|
+
const entryDistance = Math.abs(entry.text.length - normalizedLabel.length);
|
|
875
|
+
const closestDistance = Math.abs(closest.text.length - normalizedLabel.length);
|
|
876
|
+
return entryDistance < closestDistance ? entry : closest;
|
|
877
|
+
}, null);
|
|
878
|
+
return mostSpecific?.value ?? null;
|
|
879
|
+
}
|
|
859
880
|
/**
|
|
860
881
|
* Resolves the specific input/textarea/select `bodyHtmlAtFailure` contains
|
|
861
882
|
* for the named field, using the same exact-then-substring normalized-label
|
|
@@ -872,38 +893,69 @@ function resolveFieldElementValue(bodyHtmlAtFailure, fieldLabel) {
|
|
|
872
893
|
try {
|
|
873
894
|
window.document.body.innerHTML = bodyHtmlAtFailure;
|
|
874
895
|
const controls = Array.from(window.document.querySelectorAll("input,textarea,select"));
|
|
875
|
-
const
|
|
876
|
-
.map((control) => ({
|
|
877
|
-
control,
|
|
896
|
+
const entries = controls.map((control) => ({
|
|
878
897
|
text: normalizeStaleFillLabel(accessibleNameForControl(control, window)),
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
const partial = exact ??
|
|
883
|
-
named.find((entry) => entry.text.includes(normalizedLabel) || normalizedLabel.includes(entry.text));
|
|
884
|
-
if (!partial)
|
|
885
|
-
return null;
|
|
886
|
-
return partial.control.value;
|
|
898
|
+
value: control.value,
|
|
899
|
+
}));
|
|
900
|
+
return matchByNormalizedLabel(entries, normalizedLabel);
|
|
887
901
|
}
|
|
888
902
|
finally {
|
|
889
903
|
window.close();
|
|
890
904
|
}
|
|
891
905
|
}
|
|
892
|
-
|
|
906
|
+
/**
|
|
907
|
+
* Resolves a field's VALUE from the live label-keyed capture taken at
|
|
908
|
+
* step-failure time (see `flow-runner.ts`'s `fieldValuesAtFailureExpr`),
|
|
909
|
+
* using the same normalized-label matching as `resolveFieldElementValue`.
|
|
910
|
+
* This is the authoritative value source: the capture reads each control's
|
|
911
|
+
* live `.value`/`.checked` property, which a DOM-direct fill sets without
|
|
912
|
+
* ever touching the serialized `value=` attribute `bodyOuterHtml` reflects —
|
|
913
|
+
* so a reparsed HTML snapshot can structurally never prove what a text field
|
|
914
|
+
* currently holds. Returns `null` — never a guess — when no captured
|
|
915
|
+
* field's label relates to `fieldLabel` at all.
|
|
916
|
+
*/
|
|
917
|
+
function resolveFieldValueFromCapture(fieldValuesAtFailure, fieldLabel) {
|
|
918
|
+
const normalizedLabel = normalizeStaleFillLabel(fieldLabel);
|
|
919
|
+
if (!normalizedLabel)
|
|
920
|
+
return null;
|
|
921
|
+
const entries = fieldValuesAtFailure.map((field) => ({
|
|
922
|
+
text: normalizeStaleFillLabel(field.label),
|
|
923
|
+
value: field.value,
|
|
924
|
+
}));
|
|
925
|
+
return matchByNormalizedLabel(entries, normalizedLabel);
|
|
926
|
+
}
|
|
927
|
+
function filterCompletedFromReplan(newSteps, completedSteps, failedStep, bodyHtmlAtFailure, fieldValuesAtFailure) {
|
|
893
928
|
const isStaleFill = (step) => {
|
|
894
|
-
if (!bodyHtmlAtFailure)
|
|
929
|
+
if (!bodyHtmlAtFailure && !fieldValuesAtFailure)
|
|
895
930
|
return false;
|
|
896
931
|
const parsedFill = (0, flow_runner_1.parseFillStep)(step);
|
|
897
932
|
const fieldLabel = parsedFill?.fieldLabel;
|
|
898
|
-
if (fieldLabel && parsedFill?.value) {
|
|
899
|
-
const fieldValue = resolveFieldElementValue(bodyHtmlAtFailure, fieldLabel);
|
|
900
|
-
if (fieldValue !== null)
|
|
901
|
-
return fieldValue !== parsedFill.value;
|
|
902
|
-
}
|
|
903
933
|
const value = parsedFill?.value ?? (0, flow_runner_1.parseFillValueIntent)(step)?.value;
|
|
904
934
|
if (!value)
|
|
905
935
|
return false;
|
|
906
|
-
|
|
936
|
+
if (fieldLabel) {
|
|
937
|
+
// Live-captured value is authoritative when present — it can prove a
|
|
938
|
+
// DOM-direct fill survived even though the field's static attribute
|
|
939
|
+
// shows empty (see resolveFieldValueFromCapture). Only fall back to
|
|
940
|
+
// the structural bodyHtmlAtFailure re-parse when the capture has no
|
|
941
|
+
// entry for this field (e.g. capture itself failed, or this call site
|
|
942
|
+
// predates it).
|
|
943
|
+
const liveValue = fieldValuesAtFailure
|
|
944
|
+
? resolveFieldValueFromCapture(fieldValuesAtFailure, fieldLabel)
|
|
945
|
+
: null;
|
|
946
|
+
if (liveValue !== null)
|
|
947
|
+
return liveValue !== value;
|
|
948
|
+
const fieldValue = bodyHtmlAtFailure
|
|
949
|
+
? resolveFieldElementValue(bodyHtmlAtFailure, fieldLabel)
|
|
950
|
+
: null;
|
|
951
|
+
if (fieldValue !== null)
|
|
952
|
+
return fieldValue !== value;
|
|
953
|
+
}
|
|
954
|
+
// The step's field identity couldn't be resolved to a specific control in the
|
|
955
|
+
// failure-time DOM; a whole-body value search is unsound when sibling fields
|
|
956
|
+
// (e.g. password + confirm password) share the same value, so treat the step
|
|
957
|
+
// as stale rather than risk wrongly dropping a still-required field.
|
|
958
|
+
return true;
|
|
907
959
|
};
|
|
908
960
|
const completed = new Set(completedSteps.filter((s) => !isStaleFill(s)));
|
|
909
961
|
return newSteps.filter((s) => s.instruction === failedStep || !completed.has(s.instruction));
|
|
@@ -918,8 +970,18 @@ function normalizeInstruction(instruction) {
|
|
|
918
970
|
* Quoted phrases are the strongest, lowest-noise signal a flow author or the
|
|
919
971
|
* replanner gives for "which control": comparing these directly avoids false
|
|
920
972
|
* positives from prose that merely mentions the same page section.
|
|
973
|
+
*
|
|
974
|
+
* For a fill-shaped instruction (`parseFillStep` matches), the only quoted
|
|
975
|
+
* substring is the VALUE being typed, not the field's identity — two sibling
|
|
976
|
+
* fields sharing one value (e.g. a password and its confirmation) would
|
|
977
|
+
* otherwise extract identical "labels" and collide in every consumer that
|
|
978
|
+
* keys off this function. In that case the field label itself is returned
|
|
979
|
+
* instead of the raw quoted match.
|
|
921
980
|
*/
|
|
922
981
|
function extractQuotedLabels(instruction) {
|
|
982
|
+
const fieldLabel = (0, flow_runner_1.parseFillStep)(instruction)?.fieldLabel;
|
|
983
|
+
if (fieldLabel)
|
|
984
|
+
return [normalizeInstruction(fieldLabel)];
|
|
923
985
|
const matches = instruction.matchAll(/['"]([^'"]{2,80})['"]/g);
|
|
924
986
|
return [...matches].map((m) => normalizeInstruction(m[1]));
|
|
925
987
|
}
|
|
@@ -1787,6 +1849,7 @@ function dumpStepFailure(params) {
|
|
|
1787
1849
|
finalObserve: params.finalObserve,
|
|
1788
1850
|
unfocusedObserve: params.unfocusedObserve,
|
|
1789
1851
|
bodyOuterHtml: params.bodyOuterHtml,
|
|
1852
|
+
fieldValuesAtFailure: params.fieldValuesAtFailure,
|
|
1790
1853
|
recentCaptures: params.recentCaptures.slice(-5),
|
|
1791
1854
|
targetResolutionDiagnostic: params.targetResolutionDiagnostic,
|
|
1792
1855
|
};
|
|
@@ -2565,16 +2628,19 @@ async function main() {
|
|
|
2565
2628
|
// failed step's re-emission. originalRemaining is re-appended below.
|
|
2566
2629
|
// The untruncated failure-time DOM re-verifies completed fills so a
|
|
2567
2630
|
// silently-reset field isn't trusted as still-completed.
|
|
2568
|
-
const bodyHtmlAtFailure = (() => {
|
|
2631
|
+
const { bodyHtmlAtFailure, fieldValuesAtFailure } = (() => {
|
|
2569
2632
|
try {
|
|
2570
2633
|
const dump = JSON.parse((0, node_fs_1.readFileSync)(dumpPath, "utf8"));
|
|
2571
|
-
return
|
|
2634
|
+
return {
|
|
2635
|
+
bodyHtmlAtFailure: dump.bodyOuterHtml ?? null,
|
|
2636
|
+
fieldValuesAtFailure: dump.fieldValuesAtFailure ?? null,
|
|
2637
|
+
};
|
|
2572
2638
|
}
|
|
2573
2639
|
catch {
|
|
2574
|
-
return null;
|
|
2640
|
+
return { bodyHtmlAtFailure: null, fieldValuesAtFailure: null };
|
|
2575
2641
|
}
|
|
2576
2642
|
})();
|
|
2577
|
-
const newSteps = filterCompletedFromReplan(rawNewSteps, completedSteps, step.instruction, bodyHtmlAtFailure);
|
|
2643
|
+
const newSteps = filterCompletedFromReplan(rawNewSteps, completedSteps, step.instruction, bodyHtmlAtFailure, fieldValuesAtFailure);
|
|
2578
2644
|
const droppedCompleted = rawNewSteps.length - newSteps.length;
|
|
2579
2645
|
if (droppedCompleted > 0) {
|
|
2580
2646
|
logger.info(`replan #${replanIndex}: dropped ${droppedCompleted} bridge step(s) that re-ran already-completed steps`);
|