@testmuai/playwright-bindings 0.1.26 → 0.1.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/dist/actionEngine.d.ts +37 -0
  2. package/dist/actionEngine.d.ts.map +1 -0
  3. package/dist/actionEngine.js +194 -0
  4. package/dist/actionEngine.js.map +1 -0
  5. package/dist/actionSpecs.d.ts +35 -0
  6. package/dist/actionSpecs.d.ts.map +1 -0
  7. package/dist/actionSpecs.js +354 -0
  8. package/dist/actionSpecs.js.map +1 -0
  9. package/dist/capability.d.ts +3 -5
  10. package/dist/capability.d.ts.map +1 -1
  11. package/dist/capability.js +66 -6
  12. package/dist/capability.js.map +1 -1
  13. package/dist/configure.d.ts +16 -0
  14. package/dist/configure.d.ts.map +1 -1
  15. package/dist/configure.js +14 -0
  16. package/dist/configure.js.map +1 -1
  17. package/dist/errors.d.ts +19 -0
  18. package/dist/errors.d.ts.map +1 -1
  19. package/dist/errors.js +29 -0
  20. package/dist/errors.js.map +1 -1
  21. package/dist/healCache.d.ts +28 -0
  22. package/dist/healCache.d.ts.map +1 -0
  23. package/dist/healCache.js +17 -0
  24. package/dist/healCache.js.map +1 -0
  25. package/dist/healPatch.d.ts.map +1 -1
  26. package/dist/healPatch.js +45 -3
  27. package/dist/healPatch.js.map +1 -1
  28. package/dist/helpers/assertion.d.ts.map +1 -1
  29. package/dist/helpers/assertion.js +18 -0
  30. package/dist/helpers/assertion.js.map +1 -1
  31. package/dist/helpers/assertionV3.d.ts +67 -0
  32. package/dist/helpers/assertionV3.d.ts.map +1 -0
  33. package/dist/helpers/assertionV3.js +384 -0
  34. package/dist/helpers/assertionV3.js.map +1 -0
  35. package/dist/helpers/condition.d.ts +84 -0
  36. package/dist/helpers/condition.d.ts.map +1 -0
  37. package/dist/helpers/condition.js +292 -0
  38. package/dist/helpers/condition.js.map +1 -0
  39. package/dist/helpers/cookies.d.ts +12 -0
  40. package/dist/helpers/cookies.d.ts.map +1 -0
  41. package/dist/helpers/cookies.js +66 -0
  42. package/dist/helpers/cookies.js.map +1 -0
  43. package/dist/helpers/coordinateResolver.d.ts +29 -0
  44. package/dist/helpers/coordinateResolver.d.ts.map +1 -0
  45. package/dist/helpers/coordinateResolver.js +118 -0
  46. package/dist/helpers/coordinateResolver.js.map +1 -0
  47. package/dist/helpers/coordinateResolverRead.d.ts +36 -0
  48. package/dist/helpers/coordinateResolverRead.d.ts.map +1 -0
  49. package/dist/helpers/coordinateResolverRead.js +107 -0
  50. package/dist/helpers/coordinateResolverRead.js.map +1 -0
  51. package/dist/helpers/dialog.d.ts +29 -0
  52. package/dist/helpers/dialog.d.ts.map +1 -0
  53. package/dist/helpers/dialog.js +35 -0
  54. package/dist/helpers/dialog.js.map +1 -0
  55. package/dist/helpers/drag.d.ts +36 -1
  56. package/dist/helpers/drag.d.ts.map +1 -1
  57. package/dist/helpers/drag.js +267 -0
  58. package/dist/helpers/drag.js.map +1 -1
  59. package/dist/helpers/executeApi.d.ts +2 -0
  60. package/dist/helpers/executeApi.d.ts.map +1 -1
  61. package/dist/helpers/executeApi.js +30 -10
  62. package/dist/helpers/executeApi.js.map +1 -1
  63. package/dist/helpers/executeJs.d.ts.map +1 -1
  64. package/dist/helpers/executeJs.js +46 -3
  65. package/dist/helpers/executeJs.js.map +1 -1
  66. package/dist/helpers/gesture.d.ts +45 -0
  67. package/dist/helpers/gesture.d.ts.map +1 -0
  68. package/dist/helpers/gesture.js +131 -0
  69. package/dist/helpers/gesture.js.map +1 -0
  70. package/dist/helpers/healCascade.d.ts +57 -0
  71. package/dist/helpers/healCascade.d.ts.map +1 -0
  72. package/dist/helpers/healCascade.js +363 -0
  73. package/dist/helpers/healCascade.js.map +1 -0
  74. package/dist/helpers/png.d.ts +3 -0
  75. package/dist/helpers/png.d.ts.map +1 -0
  76. package/dist/helpers/png.js +18 -0
  77. package/dist/helpers/png.js.map +1 -0
  78. package/dist/helpers/screenshot.d.ts +27 -0
  79. package/dist/helpers/screenshot.d.ts.map +1 -1
  80. package/dist/helpers/screenshot.js +56 -0
  81. package/dist/helpers/screenshot.js.map +1 -1
  82. package/dist/helpers/scrollUntil.d.ts +13 -0
  83. package/dist/helpers/scrollUntil.d.ts.map +1 -0
  84. package/dist/helpers/scrollUntil.js +88 -0
  85. package/dist/helpers/scrollUntil.js.map +1 -0
  86. package/dist/helpers/tabs.d.ts +42 -1
  87. package/dist/helpers/tabs.d.ts.map +1 -1
  88. package/dist/helpers/tabs.js +259 -5
  89. package/dist/helpers/tabs.js.map +1 -1
  90. package/dist/helpers/text.d.ts +15 -0
  91. package/dist/helpers/text.d.ts.map +1 -0
  92. package/dist/helpers/text.js +24 -0
  93. package/dist/helpers/text.js.map +1 -0
  94. package/dist/helpers/textNormalize.d.ts +18 -0
  95. package/dist/helpers/textNormalize.d.ts.map +1 -0
  96. package/dist/helpers/textNormalize.js +39 -0
  97. package/dist/helpers/textNormalize.js.map +1 -0
  98. package/dist/helpers/textualRead.d.ts +37 -0
  99. package/dist/helpers/textualRead.d.ts.map +1 -0
  100. package/dist/helpers/textualRead.js +211 -0
  101. package/dist/helpers/textualRead.js.map +1 -0
  102. package/dist/helpers/vision.d.ts +2 -0
  103. package/dist/helpers/vision.d.ts.map +1 -1
  104. package/dist/helpers/vision.js +11 -0
  105. package/dist/helpers/vision.js.map +1 -1
  106. package/dist/helpers/visionV3.d.ts +38 -0
  107. package/dist/helpers/visionV3.d.ts.map +1 -0
  108. package/dist/helpers/visionV3.js +291 -0
  109. package/dist/helpers/visionV3.js.map +1 -0
  110. package/dist/helpers/wait.d.ts +14 -1
  111. package/dist/helpers/wait.d.ts.map +1 -1
  112. package/dist/helpers/wait.js +25 -0
  113. package/dist/helpers/wait.js.map +1 -1
  114. package/dist/index.d.ts +29 -3
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.js +23 -4
  117. package/dist/index.js.map +1 -1
  118. package/dist/log.d.ts +4 -1
  119. package/dist/log.d.ts.map +1 -1
  120. package/dist/log.js +8 -3
  121. package/dist/log.js.map +1 -1
  122. package/dist/rankedLocator.d.ts +27 -0
  123. package/dist/rankedLocator.d.ts.map +1 -0
  124. package/dist/rankedLocator.js +85 -0
  125. package/dist/rankedLocator.js.map +1 -0
  126. package/dist/reporters/index.d.ts +2 -0
  127. package/dist/reporters/index.d.ts.map +1 -1
  128. package/dist/reporters/index.js.map +1 -1
  129. package/dist/reporters/lt.d.ts.map +1 -1
  130. package/dist/reporters/lt.js +7 -1
  131. package/dist/reporters/lt.js.map +1 -1
  132. package/dist/routeFailure.d.ts +9 -0
  133. package/dist/routeFailure.d.ts.map +1 -0
  134. package/dist/routeFailure.js +34 -0
  135. package/dist/routeFailure.js.map +1 -0
  136. package/dist/session.d.ts.map +1 -1
  137. package/dist/session.js +21 -0
  138. package/dist/session.js.map +1 -1
  139. package/dist/step.d.ts +10 -0
  140. package/dist/step.d.ts.map +1 -1
  141. package/dist/step.js +14 -1
  142. package/dist/step.js.map +1 -1
  143. package/dist/testConfig.d.ts.map +1 -1
  144. package/dist/testConfig.js +8 -1
  145. package/dist/testConfig.js.map +1 -1
  146. package/dist/vars.d.ts +10 -0
  147. package/dist/vars.d.ts.map +1 -1
  148. package/dist/vars.js +30 -3
  149. package/dist/vars.js.map +1 -1
  150. package/dist/visionLocator.d.ts +53 -0
  151. package/dist/visionLocator.d.ts.map +1 -0
  152. package/dist/visionLocator.js +117 -0
  153. package/dist/visionLocator.js.map +1 -0
  154. package/package.json +2 -2
@@ -0,0 +1,107 @@
1
+ import { log } from '../log.js';
2
+ // === CANONICAL_READ_RESOLVER_JS_START === (edit ALL trees together; spec §4.3)
3
+ export const READ_RESOLVER_JS = `\
4
+ try {
5
+ var el = document.elementFromPoint(x, y);
6
+ if (!el) { return null; }
7
+ while (el.shadowRoot) {
8
+ var deeper = el.shadowRoot.elementFromPoint(x, y);
9
+ if (!deeper || deeper === el) { break; }
10
+ el = deeper;
11
+ }
12
+ if (el.getRootNode && el.getRootNode() !== document) { return null; }
13
+ var hitTag = el.tagName ? el.tagName.toLowerCase() : '';
14
+ if (hitTag === 'iframe' || hitTag === 'frame' || hitTag === 'canvas' || hitTag === 'video' || hitTag === 'img') { return null; }
15
+
16
+ // *** NO interactable up-walk here (the ONLY structural difference from
17
+ // RESOLVER_JS): the read must stay on the exact direct hit so non-inherited
18
+ // CSS (background-color) is read off the correct box. ***
19
+
20
+ function xpathLiteral(v) {
21
+ if (v.indexOf("'") === -1) { return "'" + v + "'"; }
22
+ if (v.indexOf('"') === -1) { return '"' + v + '"'; }
23
+ return "concat('" + v.split("'").join("', \\"'\\", '") + "')";
24
+ }
25
+ function verifies(xp) {
26
+ try {
27
+ var r = document.evaluate(xp, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
28
+ return r.snapshotLength === 1 && r.snapshotItem(0) === el;
29
+ } catch (e) { return false; }
30
+ }
31
+ var tag = el.tagName.toLowerCase();
32
+ var candidates = [];
33
+ if (el.id) { candidates.push('//*[@id=' + xpathLiteral(el.id) + ']'); }
34
+ var ATTRS = ['data-testid', 'data-test', 'data-qa', 'name', 'aria-label', 'placeholder', 'title'];
35
+ for (var i = 0; i < ATTRS.length; i++) {
36
+ var av = el.getAttribute(ATTRS[i]);
37
+ if (av) { candidates.push('//' + tag + '[@' + ATTRS[i] + '=' + xpathLiteral(av) + ']'); break; }
38
+ }
39
+ var text = (el.textContent || '').replace(/\\s+/g, ' ').trim();
40
+ if (text && text.length <= 64) {
41
+ candidates.push('//' + tag + '[normalize-space(.)=' + xpathLiteral(text) + ']');
42
+ }
43
+ var parts = [];
44
+ var node = el;
45
+ while (node && node.nodeType === 1) {
46
+ var name = node.tagName.toLowerCase();
47
+ var idx = 1;
48
+ var sib = node.previousElementSibling;
49
+ while (sib) { if (sib.tagName === node.tagName) { idx += 1; } sib = sib.previousElementSibling; }
50
+ parts.unshift(name + '[' + idx + ']');
51
+ node = node.parentElement;
52
+ }
53
+ candidates.push('/' + parts.join('/'));
54
+ for (var c = 0; c < candidates.length; c++) {
55
+ if (verifies(candidates[c])) {
56
+ return { xpath: candidates[c], tag: tag, id: el.id || '', text: text.slice(0, 80) };
57
+ }
58
+ }
59
+ return null;
60
+ } catch (e) {
61
+ return null;
62
+ }
63
+ `;
64
+ // === CANONICAL_READ_RESOLVER_JS_END ===
65
+ // Built via the Function constructor (browser-executed by Playwright, which
66
+ // serializes fn.toString() over the wire) — the grid CDP relay returns
67
+ // undefined for STRING page-functions, so a plain string wrap never runs.
68
+ // eslint-disable-next-line @typescript-eslint/no-implied-eval
69
+ const WRAPPED_READ_FN = new Function('args', 'const [x, y] = args;\n' + READ_RESOLVER_JS);
70
+ /**
71
+ * Resolve viewport-CSS (x, y) to a verified XPath for READING, or null.
72
+ *
73
+ * Identical no-throw contract to resolveCoordinate but uses READ_RESOLVER_JS
74
+ * (no interactable up-walk), so the derived xpath is the EXACT direct hit —
75
+ * correct for non-interactable nodes and non-inherited CSS (background-color).
76
+ *
77
+ * null ALWAYS means "use the server fallback" (shadow-DOM hit, iframe hit,
78
+ * canvas/video/img hit, no node, verification failure, or any JS error).
79
+ */
80
+ export async function resolveCoordinateRead(page, x, y) {
81
+ let raw;
82
+ try {
83
+ raw = await page.evaluate(WRAPPED_READ_FN, [Math.trunc(x), Math.trunc(y)]);
84
+ }
85
+ catch (exc) {
86
+ log.helper(` [read-resolver] derived_xpath=None reason=js-error: ${String(exc)}`);
87
+ return null;
88
+ }
89
+ if (raw === null || typeof raw !== 'object') {
90
+ log.helper(' [read-resolver] derived_xpath=None reason=no-node-or-bail');
91
+ return null;
92
+ }
93
+ const obj = raw;
94
+ const xpath = obj['xpath'];
95
+ if (typeof xpath !== 'string' || !xpath) {
96
+ log.helper(' [read-resolver] derived_xpath=None reason=verify-failed');
97
+ return null;
98
+ }
99
+ const meta = {
100
+ tag: String(obj['tag'] ?? ''),
101
+ id: String(obj['id'] ?? ''),
102
+ text: String(obj['text'] ?? ''),
103
+ };
104
+ log.helper(` [read-resolver] derived_xpath=${xpath} meta=${JSON.stringify(meta)}`);
105
+ return { xpath, meta };
106
+ }
107
+ //# sourceMappingURL=coordinateResolverRead.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinateResolverRead.js","sourceRoot":"","sources":["../../src/helpers/coordinateResolverRead.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAEhC,gFAAgF;AAChF,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4D/B,CAAC;AACF,yCAAyC;AAEzC,4EAA4E;AAC5E,uEAAuE;AACvE,0EAA0E;AAC1E,8DAA8D;AAC9D,MAAM,eAAe,GAAG,IAAI,QAAQ,CAAC,MAAM,EAAE,wBAAwB,GAAG,gBAAgB,CAE5E,CAAC;AAQb;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAAU,EACV,CAAS,EACT,CAAS;IAET,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,eAAwB,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAU,CAAC,CAAC;IAC/F,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,MAAM,CAAC,2DAA2D,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACrF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5C,GAAG,CAAC,MAAM,CAAC,+DAA+D,CAAC,CAAC;QAC5E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,GAAG,GAAG,GAA8B,CAAC;IAC3C,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,EAAE,CAAC;QACxC,GAAG,CAAC,MAAM,CAAC,6DAA6D,CAAC,CAAC;QAC1E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,IAAI,GAAG;QACX,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC3B,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;KAChC,CAAC;IACF,GAAG,CAAC,MAAM,CAAC,qCAAqC,KAAK,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACtF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * V3 JS-dialog handling — prime a persistent accept/dismiss policy.
3
+ *
4
+ * Playwright auto-dismisses a JavaScript dialog (alert / confirm / prompt)
5
+ * unless a `page.on('dialog')` listener is registered BEFORE the action that
6
+ * opens it. The generator records the dialog-response operation AFTER the
7
+ * triggering action (instruction N = trigger, N+1 = JS_DIALOG — the Selenium
8
+ * post-hoc order), so a Selenium-style `switch_to.alert` is impossible here:
9
+ * by the time the JS_DIALOG op runs the dialog is already gone.
10
+ *
11
+ * The fix is a permanent handler primed up front. `primeDialog` registers ONE
12
+ * idempotent, page-scoped listener and mutates a per-page policy the listener
13
+ * consults for every dialog.
14
+ */
15
+ import type { Page } from 'playwright';
16
+ /**
17
+ * Arm/refresh the JS-dialog policy for `page` and ensure a live listener.
18
+ *
19
+ * Idempotent per page: the listener is registered exactly once; later calls
20
+ * only update the policy applied to every future dialog.
21
+ *
22
+ * Async so generated code can `await` it uniformly with the other page
23
+ * helpers; it performs no I/O itself.
24
+ */
25
+ export declare function primeDialog(page: Page, opts?: {
26
+ action?: string;
27
+ value?: string;
28
+ }): Promise<void>;
29
+ //# sourceMappingURL=dialog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog.d.ts","sourceRoot":"","sources":["../../src/helpers/dialog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAU,IAAI,EAAE,MAAM,YAAY,CAAC;AAa/C;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,IAAI,EACV,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC7C,OAAO,CAAC,IAAI,CAAC,CAsBf"}
@@ -0,0 +1,35 @@
1
+ const DEFAULT_POLICY = { action: 'dismiss', value: '' };
2
+ // Keyed weakly so a closed/GC'd page auto-evicts.
3
+ const policies = new WeakMap();
4
+ const registered = new WeakMap();
5
+ /**
6
+ * Arm/refresh the JS-dialog policy for `page` and ensure a live listener.
7
+ *
8
+ * Idempotent per page: the listener is registered exactly once; later calls
9
+ * only update the policy applied to every future dialog.
10
+ *
11
+ * Async so generated code can `await` it uniformly with the other page
12
+ * helpers; it performs no I/O itself.
13
+ */
14
+ export async function primeDialog(page, opts = {}) {
15
+ policies.set(page, {
16
+ action: (opts.action || 'dismiss').trim().toLowerCase(),
17
+ value: opts.value || '',
18
+ });
19
+ if (registered.get(page))
20
+ return;
21
+ page.on('dialog', (dialog) => {
22
+ const policy = policies.get(page) ?? DEFAULT_POLICY;
23
+ const settled = policy.action === 'accept'
24
+ ? policy.value
25
+ ? dialog.accept(policy.value)
26
+ : dialog.accept()
27
+ : dialog.dismiss();
28
+ // The listener is sync but accept()/dismiss() are async. Swallow rejection
29
+ // rather than let it float: an unhandled rejection kills the Node process
30
+ // before the LT status is reported, surfacing as "completed" on the grid.
31
+ void settled.catch(() => { });
32
+ });
33
+ registered.set(page, true);
34
+ }
35
+ //# sourceMappingURL=dialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dialog.js","sourceRoot":"","sources":["../../src/helpers/dialog.ts"],"names":[],"mappings":"AAqBA,MAAM,cAAc,GAAiB,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAEtE,kDAAkD;AAClD,MAAM,QAAQ,GAAG,IAAI,OAAO,EAAsB,CAAC;AACnD,MAAM,UAAU,GAAG,IAAI,OAAO,EAAiB,CAAC;AAEhD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,IAAU,EACV,OAA4C,EAAE;IAE9C,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE;QACjB,MAAM,EAAE,CAAC,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE;QACvD,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,EAAE;KACxB,CAAC,CAAC;IAEH,IAAI,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO;IAEjC,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAc,EAAE,EAAE;QACnC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC;QACpD,MAAM,OAAO,GACX,MAAM,CAAC,MAAM,KAAK,QAAQ;YACxB,CAAC,CAAC,MAAM,CAAC,KAAK;gBACZ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;gBAC7B,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE;YACnB,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACvB,2EAA2E;QAC3E,0EAA0E;QAC1E,0EAA0E;QAC1E,KAAK,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,GAA+C,CAAC,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IACH,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC7B,CAAC"}
@@ -1,3 +1,38 @@
1
- import type { Page } from 'playwright';
1
+ /**
2
+ * Drag helpers — PY _helpers/drag.py port. clickDrag is the legacy V4
3
+ * coordinate drag; dragDrop / elementDrag add the V3-gated heal path
4
+ * (DESKTOP_LOCATE on endpoint-lookup miss, derived-xpath verify, same-round
5
+ * coordinate fallback, fallback_coordinates as true last resort).
6
+ */
7
+ import type { ElementHandle, Locator, Page } from 'playwright';
8
+ import type { SelectorSpec } from '../visionLocator.js';
9
+ type Endpoint = Locator | ElementHandle | SelectorSpec[];
10
+ type XY = [number, number];
2
11
  export declare function clickDrag(page: Page, x1: number, y1: number, x2: number, y2: number, steps?: number): Promise<void>;
12
+ export interface DragDropOptions {
13
+ sourceDescription?: string;
14
+ targetDescription?: string;
15
+ fallbackCoordinates?: [XY, XY] | null;
16
+ autoheal?: boolean;
17
+ maxAttempts?: number;
18
+ retryDelayMs?: number;
19
+ }
20
+ /**
21
+ * Drag source onto target with the V2 gesture; heal selector-list endpoints.
22
+ * Locator/handle pair → element gesture (heal opts ignored on this shape).
23
+ */
24
+ export declare function dragDrop(page: Page, source: Endpoint, target: Endpoint, opts?: DragDropOptions): Promise<boolean | undefined>;
25
+ export interface ElementDragOptions {
26
+ description?: string;
27
+ fallbackCoordinates?: XY | null;
28
+ autoheal?: boolean;
29
+ maxAttempts?: number;
30
+ retryDelayMs?: number;
31
+ }
32
+ /**
33
+ * Heal-capable relative element drag. Locator/handle source → centre to
34
+ * centre+(dx,dy); selector-list source → V3-gated heal path.
35
+ */
36
+ export declare function elementDrag(page: Page, source: Endpoint, dx: number, dy: number, opts?: ElementDragOptions): Promise<boolean>;
37
+ export {};
3
38
  //# sourceMappingURL=drag.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"drag.d.ts","sourceRoot":"","sources":["../../src/helpers/drag.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAGvC,wBAAsB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAMrH"}
1
+ {"version":3,"file":"drag.d.ts","sourceRoot":"","sources":["../../src/helpers/drag.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAK/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAcxD,KAAK,QAAQ,GAAG,OAAO,GAAG,aAAa,GAAG,YAAY,EAAE,CAAC;AACzD,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAE3B,wBAAsB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAMrH;AA0JD,MAAM,WAAW,eAAe;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mBAAmB,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,QAAQ,EAChB,MAAM,EAAE,QAAQ,EAChB,IAAI,GAAE,eAAoB,GACzB,OAAO,CAAC,OAAO,GAAG,SAAS,CAAC,CA+C9B;AAsBD,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mBAAmB,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,QAAQ,EAChB,EAAE,EAAE,MAAM,EACV,EAAE,EAAE,MAAM,EACV,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,OAAO,CAAC,CA+ClB"}
@@ -1,4 +1,17 @@
1
+ import { AutohealExhausted } from '../errors.js';
2
+ import { get as configGet, isV3 } from '../configure.js';
3
+ import { getV3DesktopLocateTarget } from './healCascade.js';
4
+ import { resolveCoordinate } from './coordinateResolver.js';
1
5
  import { log } from '../log.js';
6
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
7
+ // V2-parity constants (not parameterized in V2).
8
+ const DROP_ZONE_NUDGE_X = 0.1;
9
+ const DROP_ZONE_NUDGE_Y = 0.1;
10
+ const COORD_GESTURE_PAUSE_MS = 100;
11
+ const DRAG_STEPS = 20;
12
+ // Cap the derived-xpath re-lookup so a stale selector fails fast to the same
13
+ // round's coordinates instead of burning the full action timeout.
14
+ const DERIVED_LOOKUP_CAP_MS = 5000;
2
15
  export async function clickDrag(page, x1, y1, x2, y2, steps = 20) {
3
16
  log.helper(`[click_drag] from=(${x1},${y1}) to=(${x2},${y2}) steps=${steps}`);
4
17
  await page.mouse.move(x1, y1);
@@ -6,4 +19,258 @@ export async function clickDrag(page, x1, y1, x2, y2, steps = 20) {
6
19
  await page.mouse.move(x2, y2, { steps });
7
20
  await page.mouse.up();
8
21
  }
22
+ /** Internal control-flow marker: DESKTOP_LOCATE missed for an endpoint. */
23
+ class LocateMiss extends Error {
24
+ original;
25
+ constructor(original) {
26
+ super('DESKTOP_LOCATE miss');
27
+ this.name = 'LocateMiss';
28
+ this.original = original;
29
+ }
30
+ }
31
+ function isRecoverable(e) {
32
+ return e?.name === 'TimeoutError';
33
+ }
34
+ function buildLocator(page, selectorList) {
35
+ const sel = selectorList[0];
36
+ const raw = sel.selector ?? '';
37
+ return sel.isXPath ? page.locator(`xpath=${raw}`) : page.locator(raw);
38
+ }
39
+ function lookupTimeoutMs() {
40
+ return Number(configGet('defaultActionTimeoutMs') ?? 0) || 10000;
41
+ }
42
+ async function viewport(page) {
43
+ const dims = (await page.evaluate(() => [window.innerWidth, window.innerHeight]));
44
+ return [Math.trunc(dims[0] ?? 0), Math.trunc(dims[1] ?? 0)];
45
+ }
46
+ /** Element endpoint → viewport-CSS rect centre, clamped. A missing box throws
47
+ * a TimeoutError-named error so the attempt loop can retry. */
48
+ async function elementCenter(page, locator) {
49
+ const box = await locator.boundingBox();
50
+ if (!box) {
51
+ const e = new Error('element has no bounding box (not visible/attached)');
52
+ e.name = 'TimeoutError';
53
+ throw e;
54
+ }
55
+ const cx = box.x + box.width / 2;
56
+ const cy = box.y + box.height / 2;
57
+ const [vw, vh] = await viewport(page);
58
+ return [
59
+ Math.max(0, Math.min(Math.trunc(cx), vw - 1)),
60
+ Math.max(0, Math.min(Math.trunc(cy), vh - 1)),
61
+ ];
62
+ }
63
+ /** V2 element drag: press at source, travel, (0.1, 0.1) nudge at the drop
64
+ * zone to activate the droppable, release. */
65
+ async function elementGesture(page, [sx, sy], [tx, ty]) {
66
+ await page.mouse.move(sx, sy);
67
+ await page.mouse.down();
68
+ await page.mouse.move(tx, ty, { steps: DRAG_STEPS });
69
+ await page.mouse.move(tx + DROP_ZONE_NUDGE_X, ty + DROP_ZONE_NUDGE_Y);
70
+ await page.mouse.up();
71
+ return true;
72
+ }
73
+ /** V2 coordinate drag: press at src, settle, travel, settle, release. */
74
+ async function coordinateGesture(page, [sx, sy], [tx, ty]) {
75
+ await page.mouse.move(sx, sy);
76
+ await page.mouse.down();
77
+ await sleep(COORD_GESTURE_PAUSE_MS);
78
+ await page.mouse.move(tx, ty, { steps: DRAG_STEPS });
79
+ await sleep(COORD_GESTURE_PAUSE_MS);
80
+ await page.mouse.up();
81
+ return true;
82
+ }
83
+ /** Both endpoints elements → centres first (a stale endpoint fails BEFORE any
84
+ * mouse press), then the V2 element gesture. */
85
+ async function elementPairGesture(page, source, target) {
86
+ const srcC = await elementCenter(page, source);
87
+ const tgtC = await elementCenter(page, target);
88
+ return elementGesture(page, srcC, tgtC);
89
+ }
90
+ /** Resolve one endpoint → { loc | xy } + this round's fresh heal coords (the
91
+ * caller stashes them so the next attempt skips locate). Throws LocateMiss on
92
+ * a locate miss; the original lookup error when heal is unavailable. */
93
+ async function resolveEndpoint(page, endpoint, description, opts) {
94
+ if (opts.stashedCoords !== null)
95
+ return [{ loc: null, xy: opts.stashedCoords }, null];
96
+ if (!Array.isArray(endpoint))
97
+ return [{ loc: endpoint, xy: null }, null];
98
+ let lookupExc;
99
+ try {
100
+ if (!endpoint.length) {
101
+ const e = new Error('empty selector list');
102
+ e.name = 'TimeoutError';
103
+ throw e;
104
+ }
105
+ const locator = buildLocator(page, endpoint);
106
+ await locator.waitFor({ state: 'visible', timeout: lookupTimeoutMs() });
107
+ return [{ loc: locator, xy: null }, null];
108
+ }
109
+ catch (e) {
110
+ if (!isRecoverable(e))
111
+ throw e;
112
+ lookupExc = e;
113
+ }
114
+ // Heal is V3-only; v4 (or autoheal off) propagates without a locate call.
115
+ if (!opts.autoheal || !isV3())
116
+ throw lookupExc;
117
+ const label = opts.isTarget ? 'target' : 'source';
118
+ log.helper(`[${opts.verbName}] ${label} endpoint lookup failed; DESKTOP_LOCATE drop_aware=${opts.isTarget}`);
119
+ const coords = await getV3DesktopLocateTarget(page, description, opts.verbName, {
120
+ dropAware: opts.isTarget,
121
+ });
122
+ if (coords === null)
123
+ throw new LocateMiss(lookupExc);
124
+ const [vx, vy] = coords;
125
+ const resolved = await resolveCoordinate(page, vx, vy);
126
+ if (resolved !== null) {
127
+ try {
128
+ const derived = page.locator(`xpath=${resolved.xpath}`);
129
+ await derived.waitFor({
130
+ state: 'visible',
131
+ timeout: Math.min(lookupTimeoutMs(), DERIVED_LOOKUP_CAP_MS),
132
+ });
133
+ return [{ loc: derived, xy: null }, [vx, vy]];
134
+ }
135
+ catch (e) {
136
+ if (!isRecoverable(e))
137
+ throw e;
138
+ // Derived xpath unfindable — same round's coordinates carry the gesture.
139
+ }
140
+ }
141
+ return [{ loc: null, xy: [vx, vy] }, [vx, vy]];
142
+ }
143
+ /** Exhaustion: the stored pair is dispatched exactly once (its own failure
144
+ * propagates), else AutohealExhausted. */
145
+ async function exhaust(page, fallbackCoordinates, original) {
146
+ if (fallbackCoordinates !== null) {
147
+ const [srcXy, tgtXy] = fallbackCoordinates;
148
+ log.helper(`[drag_drop] heal exhausted; recorded fallback_coordinates ${JSON.stringify(srcXy)} -> ${JSON.stringify(tgtXy)}`);
149
+ return coordinateGesture(page, srcXy, tgtXy);
150
+ }
151
+ const err = new AutohealExhausted('drag_drop heal cascade exhausted');
152
+ err.cause = original;
153
+ throw err;
154
+ }
155
+ /**
156
+ * Drag source onto target with the V2 gesture; heal selector-list endpoints.
157
+ * Locator/handle pair → element gesture (heal opts ignored on this shape).
158
+ */
159
+ export async function dragDrop(page, source, target, opts = {}) {
160
+ const { sourceDescription = '', targetDescription = '', fallbackCoordinates = null, autoheal = true, maxAttempts = 3, retryDelayMs = 500, } = opts;
161
+ if (!Array.isArray(source) && !Array.isArray(target)) {
162
+ await elementPairGesture(page, source, target);
163
+ return undefined;
164
+ }
165
+ let firstExc = null;
166
+ // Per-endpoint fresh-coords stash: [source, target].
167
+ const stash = [null, null];
168
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
169
+ log.helper(`[drag_drop] is_retry: ${attempt > 0}`);
170
+ let src, tgt;
171
+ try {
172
+ [src, stash[0]] = await resolveEndpoint(page, source, sourceDescription, {
173
+ isTarget: false, autoheal, stashedCoords: stash[0], verbName: 'drag_drop',
174
+ });
175
+ [tgt, stash[1]] = await resolveEndpoint(page, target, targetDescription, {
176
+ isTarget: true, autoheal, stashedCoords: stash[1], verbName: 'drag_drop',
177
+ });
178
+ }
179
+ catch (e) {
180
+ if (e?.name === 'LocateMiss') {
181
+ return exhaust(page, fallbackCoordinates, firstExc ?? e.original);
182
+ }
183
+ throw e;
184
+ }
185
+ try {
186
+ if (src.loc !== null && tgt.loc !== null) {
187
+ return await elementPairGesture(page, src.loc, tgt.loc);
188
+ }
189
+ const srcXy = src.xy ?? (await elementCenter(page, src.loc));
190
+ const tgtXy = tgt.xy ?? (await elementCenter(page, tgt.loc));
191
+ log.helper(`[drag_drop] coordinate gesture ${JSON.stringify(srcXy)} -> ${JSON.stringify(tgtXy)}`);
192
+ return await coordinateGesture(page, srcXy, tgtXy);
193
+ }
194
+ catch (e) {
195
+ if (!isRecoverable(e))
196
+ throw e;
197
+ if (firstExc === null)
198
+ firstExc = e;
199
+ if (!autoheal)
200
+ throw e;
201
+ if (attempt === maxAttempts - 1)
202
+ return exhaust(page, fallbackCoordinates, firstExc);
203
+ log.helper(`[drag_drop] retry ${attempt + 1}/${maxAttempts} after ${e.name}`);
204
+ await sleep(retryDelayMs);
205
+ }
206
+ }
207
+ return undefined;
208
+ }
209
+ async function elementDragExhaust(page, dx, dy, fallbackCoordinates, original) {
210
+ if (fallbackCoordinates !== null) {
211
+ const [fx, fy] = fallbackCoordinates;
212
+ const [vw, vh] = await viewport(page);
213
+ const ex = Math.max(0, Math.min(Math.trunc(fx + dx), vw - 1));
214
+ const ey = Math.max(0, Math.min(Math.trunc(fy + dy), vh - 1));
215
+ log.helper(`[element_drag] heal exhausted; recorded fallback (${fx}, ${fy}) -> (${ex}, ${ey})`);
216
+ return coordinateGesture(page, [fx, fy], [ex, ey]);
217
+ }
218
+ const err = new AutohealExhausted('element_drag heal cascade exhausted');
219
+ err.cause = original;
220
+ throw err;
221
+ }
222
+ /**
223
+ * Heal-capable relative element drag. Locator/handle source → centre to
224
+ * centre+(dx,dy); selector-list source → V3-gated heal path.
225
+ */
226
+ export async function elementDrag(page, source, dx, dy, opts = {}) {
227
+ const { description = '', fallbackCoordinates = null, autoheal = true, maxAttempts = 4, retryDelayMs = 500, } = opts;
228
+ if (!Array.isArray(source)) {
229
+ const [cx, cy] = await elementCenter(page, source);
230
+ log.helper(`[element_drag] element centre (${cx}, ${cy}) dx=${dx} dy=${dy}`);
231
+ return coordinateGesture(page, [cx, cy], [cx + dx, cy + dy]);
232
+ }
233
+ let firstExc = null;
234
+ let stash = null;
235
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
236
+ log.helper(`[element_drag] is_retry: ${attempt > 0}`);
237
+ let origin, fresh;
238
+ try {
239
+ [origin, fresh] = await resolveEndpoint(page, source, description, {
240
+ isTarget: false, autoheal, stashedCoords: stash, verbName: 'element_drag',
241
+ });
242
+ }
243
+ catch (e) {
244
+ if (e?.name === 'LocateMiss') {
245
+ return elementDragExhaust(page, dx, dy, fallbackCoordinates, firstExc ?? e.original);
246
+ }
247
+ throw e;
248
+ }
249
+ stash = fresh;
250
+ try {
251
+ const [ox, oy] = origin.xy ?? (await elementCenter(page, origin.loc));
252
+ const [vw, vh] = await viewport(page);
253
+ const ex = Math.max(0, Math.min(Math.trunc(ox + dx), vw - 1));
254
+ const ey = Math.max(0, Math.min(Math.trunc(oy + dy), vh - 1));
255
+ log.helper(`[element_drag] origin (${ox}, ${oy}) -> end (${ex}, ${ey})`);
256
+ return await coordinateGesture(page, [ox, oy], [ex, ey]);
257
+ }
258
+ catch (e) {
259
+ if (!isRecoverable(e))
260
+ throw e;
261
+ if (firstExc === null)
262
+ firstExc = e;
263
+ if (!autoheal)
264
+ throw e;
265
+ if (attempt === maxAttempts - 1) {
266
+ return elementDragExhaust(page, dx, dy, fallbackCoordinates, firstExc);
267
+ }
268
+ log.helper(`[element_drag] retry ${attempt + 1}/${maxAttempts} after ${e.name}`);
269
+ await sleep(retryDelayMs);
270
+ }
271
+ }
272
+ const err = new AutohealExhausted('element_drag attempt loop exhausted');
273
+ err.cause = firstExc;
274
+ throw err;
275
+ }
9
276
  //# sourceMappingURL=drag.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"drag.js","sourceRoot":"","sources":["../../src/helpers/drag.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAEhC,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAU,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,EAAU,EAAE,KAAK,GAAG,EAAE;IACpG,GAAG,CAAC,MAAM,CAAC,sBAAsB,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,KAAK,EAAE,CAAC,CAAC;IAC9E,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC9B,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACxB,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;IACzC,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;AACxB,CAAC"}
1
+ {"version":3,"file":"drag.js","sourceRoot":"","sources":["../../src/helpers/drag.ts"],"names":[],"mappings":"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"}
@@ -47,6 +47,8 @@ export interface ApiResponse {
47
47
  response_body: unknown;
48
48
  body: string;
49
49
  time: number;
50
+ /** Set only on the V3 fail-open soft result. */
51
+ message?: string;
50
52
  }
51
53
  export declare function executeApi(req: ApiRequest): Promise<ApiResponse>;
52
54
  //# sourceMappingURL=executeApi.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"executeApi.d.ts","sourceRoot":"","sources":["../../src/helpers/executeApi.ts"],"names":[],"mappings":"AAwBA,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAc9D;AAED,wBAAsB,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAM5F;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,SAAS,GAAG,MAAM,CAQhE;AAGD,MAAM,WAAW,UAAU;IAAG,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAAE;AACxE,MAAM,WAAW,SAAS;IAAI,IAAI,EAAE,OAAO,CAAC;IAAE,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAAE;AAC9F,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE;QACJ,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;KAC/B,CAAC;CACH;AACD,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,SAAS,GAAG,gBAAgB,GAAG,MAAM,CAAC;AAE/E,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;IACzC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wFAAwF;IACxF,QAAQ,CAAC,EAAE;QAAE,6BAA6B,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CACxD;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAID,wBAAsB,UAAU,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAsLtE"}
1
+ {"version":3,"file":"executeApi.d.ts","sourceRoot":"","sources":["../../src/helpers/executeApi.ts"],"names":[],"mappings":"AAyBA,wBAAgB,WAAW,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAc9D;AAED,wBAAsB,WAAW,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAM5F;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,SAAS,GAAG,MAAM,CAQhE;AAGD,MAAM,WAAW,UAAU;IAAG,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAAE;AACxE,MAAM,WAAW,SAAS;IAAI,IAAI,EAAE,OAAO,CAAC;IAAE,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAAE;AAC9F,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE;QACJ,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;KAC/B,CAAC;CACH;AACD,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,SAAS,GAAG,gBAAgB,GAAG,MAAM,CAAC;AAE/E,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC;IACzC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wFAAwF;IACxF,QAAQ,CAAC,EAAE;QAAE,6BAA6B,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CACxD;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,aAAa,EAAE,OAAO,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,wBAAsB,UAAU,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAwMtE"}
@@ -1,5 +1,6 @@
1
1
  import { resolveVar } from '../vars.js';
2
2
  import { getApiProxyUrl } from '../config.js';
3
+ import { isV3 } from '../configure.js';
3
4
  import { log, preview } from '../log.js';
4
5
  import { recordApiCall } from './apiCalls.js';
5
6
  // Header names that commonly carry credentials — masked before logging.
@@ -184,16 +185,35 @@ export async function executeApi(req) {
184
185
  const { httpRequest } = await import('../httpClient.js');
185
186
  log.helper(`[execute_api] headers=${preview(JSON.stringify(redactHeadersForLog(headers)), 200)}`);
186
187
  const started = Date.now();
187
- const resp = await httpRequest({
188
- method: req.method,
189
- url: url.toString(),
190
- headers,
191
- body,
192
- proxyUrl,
193
- verify,
194
- timeoutMs: timeout,
195
- followRedirects: req.settings?.automatically_follow_redirect !== false,
196
- });
188
+ let resp;
189
+ try {
190
+ resp = await httpRequest({
191
+ method: req.method,
192
+ url: url.toString(),
193
+ headers,
194
+ body,
195
+ proxyUrl,
196
+ verify,
197
+ timeoutMs: timeout,
198
+ followRedirects: req.settings?.automatically_follow_redirect !== false,
199
+ });
200
+ }
201
+ catch (e) {
202
+ // V3 fails OPEN on a request failure (network error, proxy/connect stall,
203
+ // timeout): a soft {status:400} lets the author's own status assertion
204
+ // decide. Input-validation errors above still propagate. V4 unchanged.
205
+ if (isV3()) {
206
+ log.helper(`[execute_api] request failed (v3 fail-open): ${String(e)}`);
207
+ return {
208
+ status: 400, headers: {}, cookies: {},
209
+ response_body: `API request failed ${String(e)}`,
210
+ body: `API request failed ${String(e)}`,
211
+ time: Date.now() - started,
212
+ message: `API request failed ${String(e)}`,
213
+ };
214
+ }
215
+ throw e;
216
+ }
197
217
  const elapsed = Date.now() - started;
198
218
  log.helper(`[execute_api] status=${resp.status} time=${elapsed}ms`);
199
219
  const respHeaders = {};