@nuanu-ai/agentbrowse 0.2.7 → 0.2.8

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 (191) hide show
  1. package/README.md +36 -8
  2. package/dist/agentpay-stagehand-llm.d.ts.map +1 -1
  3. package/dist/agentpay-stagehand-llm.js +5 -1
  4. package/dist/commands/act.d.ts +6 -2
  5. package/dist/commands/act.d.ts.map +1 -1
  6. package/dist/commands/act.js +840 -55
  7. package/dist/commands/act.test-harness.d.ts +19 -0
  8. package/dist/commands/act.test-harness.d.ts.map +1 -0
  9. package/dist/commands/act.test-harness.js +245 -0
  10. package/dist/commands/action-acceptance.d.ts +90 -0
  11. package/dist/commands/action-acceptance.d.ts.map +1 -0
  12. package/dist/commands/action-acceptance.js +1411 -0
  13. package/dist/commands/action-artifacts.d.ts +33 -0
  14. package/dist/commands/action-artifacts.d.ts.map +1 -0
  15. package/dist/commands/action-artifacts.js +104 -0
  16. package/dist/commands/action-execution-guards.d.ts +5 -0
  17. package/dist/commands/action-execution-guards.d.ts.map +1 -0
  18. package/dist/commands/action-execution-guards.js +3 -0
  19. package/dist/commands/action-executor-helpers.d.ts +21 -0
  20. package/dist/commands/action-executor-helpers.d.ts.map +1 -0
  21. package/dist/commands/action-executor-helpers.js +242 -0
  22. package/dist/commands/action-executor.d.ts +12 -0
  23. package/dist/commands/action-executor.d.ts.map +1 -0
  24. package/dist/commands/action-executor.js +45 -0
  25. package/dist/commands/action-fallbacks.d.ts +6 -0
  26. package/dist/commands/action-fallbacks.d.ts.map +1 -0
  27. package/dist/commands/action-fallbacks.js +43 -0
  28. package/dist/commands/action-value-projection.d.ts +32 -0
  29. package/dist/commands/action-value-projection.d.ts.map +1 -0
  30. package/dist/commands/action-value-projection.js +151 -0
  31. package/dist/commands/browse-actions.d.ts +4 -0
  32. package/dist/commands/browse-actions.d.ts.map +1 -0
  33. package/dist/commands/browse-actions.js +4 -0
  34. package/dist/commands/captcha-solve.d.ts.map +1 -1
  35. package/dist/commands/captcha-solve.js +13 -3
  36. package/dist/commands/click-action-executor.d.ts +10 -0
  37. package/dist/commands/click-action-executor.d.ts.map +1 -0
  38. package/dist/commands/click-action-executor.js +68 -0
  39. package/dist/commands/create-intent.d.ts +6 -0
  40. package/dist/commands/create-intent.d.ts.map +1 -0
  41. package/dist/commands/create-intent.js +75 -0
  42. package/dist/commands/datepicker-action-executor.d.ts +12 -0
  43. package/dist/commands/datepicker-action-executor.d.ts.map +1 -0
  44. package/dist/commands/datepicker-action-executor.js +218 -0
  45. package/dist/commands/descriptor-validation.d.ts +27 -0
  46. package/dist/commands/descriptor-validation.d.ts.map +1 -0
  47. package/dist/commands/descriptor-validation.js +333 -0
  48. package/dist/commands/extract-scope-resolution.d.ts +20 -0
  49. package/dist/commands/extract-scope-resolution.d.ts.map +1 -0
  50. package/dist/commands/extract-scope-resolution.js +100 -0
  51. package/dist/commands/extract-stagehand-executor.d.ts +17 -0
  52. package/dist/commands/extract-stagehand-executor.d.ts.map +1 -0
  53. package/dist/commands/extract-stagehand-executor.js +18 -0
  54. package/dist/commands/extract.d.ts +3 -2
  55. package/dist/commands/extract.d.ts.map +1 -1
  56. package/dist/commands/extract.js +256 -39
  57. package/dist/commands/fill-secret.d.ts +7 -0
  58. package/dist/commands/fill-secret.d.ts.map +1 -0
  59. package/dist/commands/fill-secret.js +371 -0
  60. package/dist/commands/get-secrets-catalog.d.ts +6 -0
  61. package/dist/commands/get-secrets-catalog.d.ts.map +1 -0
  62. package/dist/commands/get-secrets-catalog.js +23 -0
  63. package/dist/commands/launch.d.ts.map +1 -1
  64. package/dist/commands/launch.js +41 -7
  65. package/dist/commands/navigate.d.ts +2 -1
  66. package/dist/commands/navigate.d.ts.map +1 -1
  67. package/dist/commands/navigate.js +49 -12
  68. package/dist/commands/observe-inventory.d.ts +109 -0
  69. package/dist/commands/observe-inventory.d.ts.map +1 -0
  70. package/dist/commands/observe-inventory.js +2837 -0
  71. package/dist/commands/observe-persistence.d.ts +14 -0
  72. package/dist/commands/observe-persistence.d.ts.map +1 -0
  73. package/dist/commands/observe-persistence.js +170 -0
  74. package/dist/commands/observe-projection.d.ts +84 -0
  75. package/dist/commands/observe-projection.d.ts.map +1 -0
  76. package/dist/commands/observe-projection.js +140 -0
  77. package/dist/commands/observe-protected.d.ts +5 -0
  78. package/dist/commands/observe-protected.d.ts.map +1 -0
  79. package/dist/commands/observe-protected.js +18 -0
  80. package/dist/commands/observe-semantics.d.ts +10 -0
  81. package/dist/commands/observe-semantics.d.ts.map +1 -0
  82. package/dist/commands/observe-semantics.js +338 -0
  83. package/dist/commands/observe-stagehand.d.ts +48 -0
  84. package/dist/commands/observe-stagehand.d.ts.map +1 -0
  85. package/dist/commands/observe-stagehand.js +105 -0
  86. package/dist/commands/observe-surfaces.d.ts +9 -0
  87. package/dist/commands/observe-surfaces.d.ts.map +1 -0
  88. package/dist/commands/observe-surfaces.js +195 -0
  89. package/dist/commands/observe.d.ts +47 -1
  90. package/dist/commands/observe.d.ts.map +1 -1
  91. package/dist/commands/observe.js +173 -20
  92. package/dist/commands/observe.test-harness.d.ts +67 -0
  93. package/dist/commands/observe.test-harness.d.ts.map +1 -0
  94. package/dist/commands/observe.test-harness.js +107 -0
  95. package/dist/commands/poll-intent.d.ts +6 -0
  96. package/dist/commands/poll-intent.d.ts.map +1 -0
  97. package/dist/commands/poll-intent.js +57 -0
  98. package/dist/commands/screenshot.d.ts +2 -1
  99. package/dist/commands/screenshot.d.ts.map +1 -1
  100. package/dist/commands/screenshot.js +44 -12
  101. package/dist/commands/select-action-executor.d.ts +10 -0
  102. package/dist/commands/select-action-executor.d.ts.map +1 -0
  103. package/dist/commands/select-action-executor.js +91 -0
  104. package/dist/commands/semantic-observe.d.ts +24 -0
  105. package/dist/commands/semantic-observe.d.ts.map +1 -0
  106. package/dist/commands/semantic-observe.js +344 -0
  107. package/dist/commands/status.d.ts.map +1 -1
  108. package/dist/commands/status.js +75 -2
  109. package/dist/commands/structured-grid-action-executor.d.ts +3 -0
  110. package/dist/commands/structured-grid-action-executor.d.ts.map +1 -0
  111. package/dist/commands/structured-grid-action-executor.js +4 -0
  112. package/dist/commands/target-resolution.d.ts +4 -0
  113. package/dist/commands/target-resolution.d.ts.map +1 -0
  114. package/dist/commands/target-resolution.js +33 -0
  115. package/dist/commands/text-input-action-executor.d.ts +5 -0
  116. package/dist/commands/text-input-action-executor.d.ts.map +1 -0
  117. package/dist/commands/text-input-action-executor.js +116 -0
  118. package/dist/commands/user-actionable.d.ts +4 -0
  119. package/dist/commands/user-actionable.d.ts.map +1 -0
  120. package/dist/commands/user-actionable.js +95 -0
  121. package/dist/control-semantics.d.ts +29 -0
  122. package/dist/control-semantics.d.ts.map +1 -0
  123. package/dist/control-semantics.js +299 -0
  124. package/dist/index.d.ts.map +1 -1
  125. package/dist/index.js +95 -32
  126. package/dist/output.d.ts +14 -2
  127. package/dist/output.d.ts.map +1 -1
  128. package/dist/output.js +17 -29
  129. package/dist/playwright-runtime.d.ts +35 -0
  130. package/dist/playwright-runtime.d.ts.map +1 -0
  131. package/dist/playwright-runtime.js +224 -0
  132. package/dist/runtime-resolution.d.ts +9 -0
  133. package/dist/runtime-resolution.d.ts.map +1 -0
  134. package/dist/runtime-resolution.js +19 -0
  135. package/dist/runtime-state.d.ts +217 -0
  136. package/dist/runtime-state.d.ts.map +1 -0
  137. package/dist/runtime-state.js +629 -0
  138. package/dist/secrets/backend.d.ts +32 -0
  139. package/dist/secrets/backend.d.ts.map +1 -0
  140. package/dist/secrets/backend.js +169 -0
  141. package/dist/secrets/catalog-applicability.d.ts +5 -0
  142. package/dist/secrets/catalog-applicability.d.ts.map +1 -0
  143. package/dist/secrets/catalog-applicability.js +59 -0
  144. package/dist/secrets/catalog-sync.d.ts +14 -0
  145. package/dist/secrets/catalog-sync.d.ts.map +1 -0
  146. package/dist/secrets/catalog-sync.js +35 -0
  147. package/dist/secrets/field-policy.d.ts +3 -0
  148. package/dist/secrets/field-policy.d.ts.map +1 -0
  149. package/dist/secrets/field-policy.js +3 -0
  150. package/dist/secrets/fill-ordering.d.ts +11 -0
  151. package/dist/secrets/fill-ordering.d.ts.map +1 -0
  152. package/dist/secrets/fill-ordering.js +44 -0
  153. package/dist/secrets/form-matcher.d.ts +60 -0
  154. package/dist/secrets/form-matcher.d.ts.map +1 -0
  155. package/dist/secrets/form-matcher.js +596 -0
  156. package/dist/secrets/intent-output.d.ts +11 -0
  157. package/dist/secrets/intent-output.d.ts.map +1 -0
  158. package/dist/secrets/intent-output.js +64 -0
  159. package/dist/secrets/mock-agentpay-backend.d.ts +13 -0
  160. package/dist/secrets/mock-agentpay-backend.d.ts.map +1 -0
  161. package/dist/secrets/mock-agentpay-backend.js +87 -0
  162. package/dist/secrets/mock-agentpay-cabinet.d.ts +43 -0
  163. package/dist/secrets/mock-agentpay-cabinet.d.ts.map +1 -0
  164. package/dist/secrets/mock-agentpay-cabinet.js +195 -0
  165. package/dist/secrets/protected-artifact-guard.d.ts +25 -0
  166. package/dist/secrets/protected-artifact-guard.d.ts.map +1 -0
  167. package/dist/secrets/protected-artifact-guard.js +26 -0
  168. package/dist/secrets/protected-bindings.d.ts +10 -0
  169. package/dist/secrets/protected-bindings.d.ts.map +1 -0
  170. package/dist/secrets/protected-bindings.js +17 -0
  171. package/dist/secrets/protected-field-values.d.ts +13 -0
  172. package/dist/secrets/protected-field-values.d.ts.map +1 -0
  173. package/dist/secrets/protected-field-values.js +100 -0
  174. package/dist/secrets/protected-fill.d.ts +47 -0
  175. package/dist/secrets/protected-fill.d.ts.map +1 -0
  176. package/dist/secrets/protected-fill.js +512 -0
  177. package/dist/secrets/types.d.ts +84 -0
  178. package/dist/secrets/types.d.ts.map +1 -0
  179. package/dist/secrets/types.js +27 -0
  180. package/dist/session.d.ts +22 -0
  181. package/dist/session.d.ts.map +1 -1
  182. package/dist/session.js +74 -2
  183. package/dist/solver/browser-launcher.d.ts.map +1 -1
  184. package/dist/solver/browser-launcher.js +6 -3
  185. package/dist/stagehand-runtime.d.ts +4 -0
  186. package/dist/stagehand-runtime.d.ts.map +1 -0
  187. package/dist/stagehand-runtime.js +10 -0
  188. package/dist/stagehand.d.ts +0 -5
  189. package/dist/stagehand.d.ts.map +1 -1
  190. package/dist/stagehand.js +0 -6
  191. package/package.json +5 -2
@@ -3,9 +3,51 @@
3
3
  */
4
4
  import { loadSession, isSessionAlive, getSessionPort, supportsCaptchaSolve } from '../session.js';
5
5
  import { outputJSON } from '../output.js';
6
+ function tryResolveHost(url) {
7
+ if (!url) {
8
+ return undefined;
9
+ }
10
+ try {
11
+ return new URL(url).hostname || undefined;
12
+ }
13
+ catch {
14
+ return undefined;
15
+ }
16
+ }
17
+ function buildProtectedStatusPayload(params) {
18
+ return {
19
+ success: true,
20
+ alive: true,
21
+ outcomeType: 'protected_exposure_active',
22
+ ...(params.captchaSolveCapable !== undefined
23
+ ? { captchaSolveCapable: params.captchaSolveCapable }
24
+ : {}),
25
+ runtime: params.runtimeSummary,
26
+ protectedExposureActive: true,
27
+ pageRef: params.protectedExposure.pageRef,
28
+ url: params.pageUrl ?? 'unknown',
29
+ title: params.pageTitle ?? 'unknown',
30
+ ...(tryResolveHost(params.pageUrl) ? { host: tryResolveHost(params.pageUrl) } : {}),
31
+ fillRef: params.protectedExposure.fillRef,
32
+ intentId: params.protectedExposure.intentId,
33
+ activatedAt: params.protectedExposure.activatedAt,
34
+ exposureReason: params.protectedExposure.reason,
35
+ message: 'Protected values may still be visible on the current page.',
36
+ reason: 'AgentBrowse is treating the current page as sensitive because a protected fill was executed and values may still be visible.',
37
+ };
38
+ }
6
39
  export async function status() {
7
40
  const session = loadSession();
8
41
  const port = getSessionPort(session);
42
+ const runtimeSummary = session?.runtime
43
+ ? {
44
+ currentPageRef: session.runtime.currentPageRef,
45
+ pageCount: Object.keys(session.runtime.pages).length,
46
+ surfaceCount: Object.keys(session.runtime.surfaces ?? {}).length,
47
+ targetCount: Object.keys(session.runtime.targets).length,
48
+ metrics: session.runtime.metrics,
49
+ }
50
+ : undefined;
9
51
  if (!session || !isSessionAlive(session)) {
10
52
  // Try CDP endpoint directly — Chrome may have been launched externally
11
53
  try {
@@ -15,33 +57,64 @@ export async function status() {
15
57
  const listRes = await fetch(`http://localhost:${port}/json/list`);
16
58
  const targets = (await listRes.json());
17
59
  const page = targets.find((t) => t.type === 'page' && !t.url.startsWith('devtools://'));
60
+ const currentPageRef = session?.runtime?.currentPageRef;
61
+ const protectedExposure = currentPageRef
62
+ ? session?.runtime?.protectedExposureByPage?.[currentPageRef]
63
+ : undefined;
64
+ if (protectedExposure) {
65
+ outputJSON(buildProtectedStatusPayload({
66
+ runtimeSummary,
67
+ pageUrl: page?.url,
68
+ pageTitle: page?.title,
69
+ protectedExposure,
70
+ }));
71
+ return;
72
+ }
18
73
  outputJSON({
19
74
  success: true,
20
75
  alive: true,
21
76
  url: page?.url ?? 'unknown',
22
77
  title: page?.title ?? 'unknown',
78
+ runtime: runtimeSummary,
23
79
  });
80
+ return;
24
81
  }
25
82
  }
26
83
  catch {
27
84
  // Chrome not running
28
85
  }
29
- outputJSON({ success: true, alive: false });
86
+ return outputJSON({ success: true, alive: false });
30
87
  }
31
88
  // Session exists and PID is alive — get page info via CDP
32
89
  try {
33
90
  const listRes = await fetch(`http://localhost:${port}/json/list`);
34
91
  const targets = (await listRes.json());
35
92
  const page = targets.find((t) => t.type === 'page' && !t.url.startsWith('devtools://'));
93
+ const currentPageRef = session.runtime?.currentPageRef;
94
+ const protectedExposure = currentPageRef
95
+ ? session.runtime?.protectedExposureByPage?.[currentPageRef]
96
+ : undefined;
97
+ if (protectedExposure) {
98
+ outputJSON(buildProtectedStatusPayload({
99
+ runtimeSummary,
100
+ pageUrl: page?.url,
101
+ pageTitle: page?.title,
102
+ captchaSolveCapable: supportsCaptchaSolve(session),
103
+ protectedExposure,
104
+ }));
105
+ return;
106
+ }
36
107
  outputJSON({
37
108
  success: true,
38
109
  alive: true,
39
110
  captchaSolveCapable: supportsCaptchaSolve(session),
40
111
  url: page?.url ?? 'unknown',
41
112
  title: page?.title ?? 'unknown',
113
+ runtime: runtimeSummary,
42
114
  });
115
+ return;
43
116
  }
44
117
  catch {
45
- outputJSON({ success: true, alive: false });
118
+ return outputJSON({ success: true, alive: false, runtime: runtimeSummary });
46
119
  }
47
120
  }
@@ -0,0 +1,3 @@
1
+ import type { Locator, Page } from 'playwright-core';
2
+ export declare function applyStructuredGridAction(page: Page, locator: Locator, attempts: string[]): Promise<boolean>;
3
+ //# sourceMappingURL=structured-grid-action-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structured-grid-action-executor.d.ts","sourceRoot":"","sources":["../../src/commands/structured-grid-action-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAGrD,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,OAAO,CAAC,CAElB"}
@@ -0,0 +1,4 @@
1
+ import { applyTriggerAction } from './click-action-executor.js';
2
+ export async function applyStructuredGridAction(page, locator, attempts) {
3
+ return applyTriggerAction(page, locator, attempts);
4
+ }
@@ -0,0 +1,4 @@
1
+ import type { Locator, Page } from 'playwright-core';
2
+ import type { SurfaceDescriptor } from '../runtime-state.js';
3
+ export declare function resolveSurfaceScopeRoot(page: Page, surface: SurfaceDescriptor | null, attempts?: string[]): Promise<Locator | null>;
4
+ //# sourceMappingURL=target-resolution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"target-resolution.d.ts","sourceRoot":"","sources":["../../src/commands/target-resolution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAK7D,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,iBAAiB,GAAG,IAAI,EACjC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAClB,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAoCzB"}
@@ -0,0 +1,33 @@
1
+ import { buildLocator, resolveLocatorRoot } from './action-fallbacks.js';
2
+ const STRUCTURAL_SURFACE_STRATEGIES = new Set(['css', 'xpath', 'testId', 'role']);
3
+ export async function resolveSurfaceScopeRoot(page, surface, attempts) {
4
+ if (!surface) {
5
+ return null;
6
+ }
7
+ const baseRoot = resolveLocatorRoot(page, surface.framePath);
8
+ for (const candidate of surface.locatorCandidates) {
9
+ if (!STRUCTURAL_SURFACE_STRATEGIES.has(candidate.strategy)) {
10
+ continue;
11
+ }
12
+ attempts?.push(`surface.resolve:${candidate.strategy}`);
13
+ const locator = buildLocator(baseRoot, candidate);
14
+ if (!locator) {
15
+ attempts?.push(`surface.resolve.skip:${candidate.strategy}:unsupported`);
16
+ continue;
17
+ }
18
+ const count = await locator.count().catch(() => 0);
19
+ if (count === 0) {
20
+ attempts?.push(`surface.resolve.skip:${candidate.strategy}:empty`);
21
+ continue;
22
+ }
23
+ const resolvedSurface = locator.first();
24
+ const visible = await resolvedSurface.isVisible().catch(() => false);
25
+ if (!visible) {
26
+ attempts?.push(`surface.resolve.skip:${candidate.strategy}:hidden`);
27
+ continue;
28
+ }
29
+ attempts?.push(`surface.resolve.ok:${candidate.strategy}`);
30
+ return resolvedSurface;
31
+ }
32
+ return null;
33
+ }
@@ -0,0 +1,5 @@
1
+ import type { Locator, Page } from 'playwright-core';
2
+ import { type ActionExecutionGuards } from './action-execution-guards.js';
3
+ export declare function applyTextFillAction(page: Page, locator: Locator, value: string, attempts: string[], guards?: ActionExecutionGuards): Promise<boolean>;
4
+ export declare function applyTypeAction(page: Page, locator: Locator, value: string, attempts: string[], guards?: ActionExecutionGuards): Promise<boolean>;
5
+ //# sourceMappingURL=text-input-action-executor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-input-action-executor.d.ts","sourceRoot":"","sources":["../../src/commands/text-input-action-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAYrD,OAAO,EAEL,KAAK,qBAAqB,EAC3B,MAAM,8BAA8B,CAAC;AAEtC,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAAE,EAClB,MAAM,CAAC,EAAE,qBAAqB,GAC7B,OAAO,CAAC,OAAO,CAAC,CA6FlB;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAAE,EAClB,MAAM,CAAC,EAAE,qBAAqB,GAC7B,OAAO,CAAC,OAAO,CAAC,CAqBlB"}
@@ -0,0 +1,116 @@
1
+ import { LOCATOR_FILL_TIMEOUT_MS, applyValueWithJsFallback, blurLocator, clearLocatorForReplacement, deriveMaskedSequentialValue, focusLocator, normalizeFillValue, planTextFillStrategy, readLocatorCurrentValue, } from './action-executor-helpers.js';
2
+ import { runActionExecutionGuard, } from './action-execution-guards.js';
3
+ export async function applyTextFillAction(page, locator, value, attempts, guards) {
4
+ const { normalizedValue, preferSequential, settleMs, initialPhonePrefix, blurAfterFill } = await planTextFillStrategy(locator, value, attempts);
5
+ if (preferSequential) {
6
+ await focusLocator(page, locator, attempts);
7
+ await clearLocatorForReplacement(locator, attempts);
8
+ const residualValue = await readLocatorCurrentValue(locator);
9
+ const sequentialValue = deriveMaskedSequentialValue(normalizedValue, residualValue, initialPhonePrefix, attempts);
10
+ if (typeof locator.pressSequentially === 'function') {
11
+ attempts.push('locator.pressSequentially.masked');
12
+ try {
13
+ await runActionExecutionGuard(guards, 'fill.masked.press-sequentially');
14
+ await locator.pressSequentially(sequentialValue);
15
+ if (settleMs > 0 && typeof page.waitForTimeout === 'function') {
16
+ attempts.push(`fill.settle:${settleMs}`);
17
+ await page.waitForTimeout(settleMs);
18
+ }
19
+ if (blurAfterFill) {
20
+ await blurLocator(locator, attempts);
21
+ }
22
+ return true;
23
+ }
24
+ catch {
25
+ // Fall through to fill/js fallback with the normalized masked value.
26
+ }
27
+ }
28
+ attempts.push('locator.fill.masked-fallback');
29
+ try {
30
+ await runActionExecutionGuard(guards, 'fill.masked.fill');
31
+ await locator.fill(sequentialValue, { timeout: LOCATOR_FILL_TIMEOUT_MS });
32
+ if (settleMs > 0 && typeof page.waitForTimeout === 'function') {
33
+ attempts.push(`fill.settle:${settleMs}`);
34
+ await page.waitForTimeout(settleMs);
35
+ }
36
+ if (blurAfterFill) {
37
+ await blurLocator(locator, attempts);
38
+ }
39
+ return true;
40
+ }
41
+ catch {
42
+ await runActionExecutionGuard(guards, 'fill.masked.js-fallback');
43
+ await applyValueWithJsFallback(locator, sequentialValue, attempts);
44
+ if (blurAfterFill) {
45
+ await blurLocator(locator, attempts);
46
+ }
47
+ return true;
48
+ }
49
+ }
50
+ const directFillValue = await normalizeFillValue(locator, normalizedValue, attempts);
51
+ attempts.push('locator.fill');
52
+ try {
53
+ await locator.fill(directFillValue, { timeout: LOCATOR_FILL_TIMEOUT_MS });
54
+ return false;
55
+ }
56
+ catch {
57
+ await runActionExecutionGuard(guards, 'fill.after-error');
58
+ await focusLocator(page, locator, attempts);
59
+ await clearLocatorForReplacement(locator, attempts);
60
+ if (typeof locator.pressSequentially === 'function') {
61
+ attempts.push('locator.pressSequentially');
62
+ try {
63
+ await runActionExecutionGuard(guards, 'fill.press-sequentially');
64
+ await locator.pressSequentially(directFillValue);
65
+ if (blurAfterFill) {
66
+ await blurLocator(locator, attempts);
67
+ }
68
+ return true;
69
+ }
70
+ catch {
71
+ // Fall through to retry and DOM-event fallback.
72
+ }
73
+ }
74
+ attempts.push('locator.fill.retry');
75
+ try {
76
+ await runActionExecutionGuard(guards, 'fill.retry');
77
+ await locator.fill(directFillValue, { timeout: LOCATOR_FILL_TIMEOUT_MS });
78
+ if (blurAfterFill) {
79
+ await blurLocator(locator, attempts);
80
+ }
81
+ return true;
82
+ }
83
+ catch {
84
+ await runActionExecutionGuard(guards, 'fill.js-fallback');
85
+ await applyValueWithJsFallback(locator, directFillValue, attempts);
86
+ }
87
+ if (blurAfterFill) {
88
+ await blurLocator(locator, attempts);
89
+ }
90
+ return true;
91
+ }
92
+ }
93
+ export async function applyTypeAction(page, locator, value, attempts, guards) {
94
+ await focusLocator(page, locator, attempts);
95
+ if (typeof locator.pressSequentially === 'function') {
96
+ attempts.push('locator.pressSequentially');
97
+ try {
98
+ await runActionExecutionGuard(guards, 'type.press-sequentially');
99
+ await locator.pressSequentially(value);
100
+ return false;
101
+ }
102
+ catch {
103
+ // Fall through to fill/DOM-event fallback.
104
+ }
105
+ }
106
+ attempts.push('locator.fill');
107
+ try {
108
+ await runActionExecutionGuard(guards, 'type.fill');
109
+ await locator.fill(value, { timeout: LOCATOR_FILL_TIMEOUT_MS });
110
+ }
111
+ catch {
112
+ await runActionExecutionGuard(guards, 'type.js-fallback');
113
+ await applyValueWithJsFallback(locator, value, attempts);
114
+ }
115
+ return true;
116
+ }
@@ -0,0 +1,4 @@
1
+ import type { Locator } from 'playwright-core';
2
+ export declare const TRANSPARENT_ACTIONABLE_CONTROL_HELPER_SCRIPT: string;
3
+ export declare function isLocatorUserActionable(locator: Locator): Promise<boolean>;
4
+ //# sourceMappingURL=user-actionable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-actionable.d.ts","sourceRoot":"","sources":["../../src/commands/user-actionable.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE/C,eAAO,MAAM,4CAA4C,QAoDxD,CAAC;AAEF,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAqDhF"}
@@ -0,0 +1,95 @@
1
+ export const TRANSPARENT_ACTIONABLE_CONTROL_HELPER_SCRIPT = String.raw `
2
+ const isTransparentActionableControl = (element) => {
3
+ if (!isHTMLElementNode(element)) {
4
+ return false;
5
+ }
6
+
7
+ const tag = element.tagName?.toLowerCase?.() ?? '';
8
+ const role = (element.getAttribute?.('role') || '').trim().toLowerCase();
9
+ const isNativeControl =
10
+ tag === 'input' || tag === 'textarea' || tag === 'select' || element.isContentEditable;
11
+ const isInteractiveRole =
12
+ role === 'textbox' || role === 'combobox' || role === 'searchbox' || role === 'spinbutton';
13
+ if (!isNativeControl && !isInteractiveRole) {
14
+ return false;
15
+ }
16
+
17
+ const view = ownerWindowOf(element);
18
+ const style = view?.getComputedStyle?.(element);
19
+ if (
20
+ !style ||
21
+ style.display === 'none' ||
22
+ style.visibility === 'hidden' ||
23
+ style.visibility === 'collapse' ||
24
+ style.pointerEvents === 'none'
25
+ ) {
26
+ return false;
27
+ }
28
+
29
+ const rect = element.getBoundingClientRect();
30
+ if (rect.width <= 0 || rect.height <= 0) {
31
+ return false;
32
+ }
33
+
34
+ const documentNode = element.ownerDocument;
35
+ if (!documentNode?.elementFromPoint) {
36
+ return false;
37
+ }
38
+
39
+ const samplePoints = [
40
+ [rect.left + rect.width / 2, rect.top + rect.height / 2],
41
+ [Math.max(rect.left + 1, rect.left + rect.width * 0.25), rect.top + rect.height / 2],
42
+ [Math.min(rect.right - 1, rect.left + rect.width * 0.75), rect.top + rect.height / 2],
43
+ ];
44
+
45
+ return samplePoints.some(([x, y]) => {
46
+ const hit = documentNode.elementFromPoint(x, y);
47
+ return (
48
+ isHTMLElementNode(hit) &&
49
+ (hit === element || element.contains(hit) || hit.contains(element))
50
+ );
51
+ });
52
+ };
53
+ `;
54
+ export async function isLocatorUserActionable(locator) {
55
+ const visible = await locator.isVisible().catch(() => false);
56
+ if (visible) {
57
+ return true;
58
+ }
59
+ return locator
60
+ .evaluate((element) => {
61
+ if (!(element instanceof HTMLElement)) {
62
+ return false;
63
+ }
64
+ const tag = element.tagName.toLowerCase();
65
+ const role = (element.getAttribute('role') || '').trim().toLowerCase();
66
+ const isNativeControl = tag === 'input' || tag === 'textarea' || tag === 'select' || element.isContentEditable;
67
+ const isInteractiveRole = role === 'textbox' || role === 'combobox' || role === 'searchbox' || role === 'spinbutton';
68
+ if (!isNativeControl && !isInteractiveRole) {
69
+ return false;
70
+ }
71
+ const style = element.ownerDocument.defaultView?.getComputedStyle(element);
72
+ if (!style ||
73
+ style.display === 'none' ||
74
+ style.visibility === 'hidden' ||
75
+ style.visibility === 'collapse' ||
76
+ style.pointerEvents === 'none') {
77
+ return false;
78
+ }
79
+ const rect = element.getBoundingClientRect();
80
+ if (rect.width <= 0 || rect.height <= 0) {
81
+ return false;
82
+ }
83
+ const samplePoints = [
84
+ [rect.left + rect.width / 2, rect.top + rect.height / 2],
85
+ [Math.max(rect.left + 1, rect.left + rect.width * 0.25), rect.top + rect.height / 2],
86
+ [Math.min(rect.right - 1, rect.left + rect.width * 0.75), rect.top + rect.height / 2],
87
+ ];
88
+ return samplePoints.some(([x, y]) => {
89
+ const hit = element.ownerDocument.elementFromPoint(x, y);
90
+ return (hit instanceof HTMLElement &&
91
+ (hit === element || element.contains(hit) || hit.contains(element)));
92
+ });
93
+ })
94
+ .catch(() => false);
95
+ }
@@ -0,0 +1,29 @@
1
+ import type { TargetAcceptancePolicy, TargetAllowedAction, TargetAvailabilityState, TargetControlFamily, TargetStructure } from './runtime-state.js';
2
+ export type TargetStateFacts = Record<string, string | boolean | number>;
3
+ export type TargetSemanticsFacts = {
4
+ kind?: string;
5
+ role?: string;
6
+ label?: string;
7
+ displayLabel?: string;
8
+ interactionHint?: 'click';
9
+ text?: string;
10
+ placeholder?: string;
11
+ inputName?: string;
12
+ inputType?: string;
13
+ autocomplete?: string;
14
+ surfaceKind?: string;
15
+ controlsSurfaceSelector?: string;
16
+ states?: TargetStateFacts;
17
+ structure?: TargetStructure;
18
+ legacyMethod?: string;
19
+ };
20
+ export type ComparableValueType = 'phone' | 'card-number' | 'expiry' | 'cvc' | 'date';
21
+ export declare function inferComparableValueTypeFromFacts(facts: TargetSemanticsFacts): ComparableValueType | undefined;
22
+ export declare function isLikelyDateLikeLabel(value: string | undefined): boolean;
23
+ export declare function inferAllowedActionsFromFacts(facts: TargetSemanticsFacts): TargetAllowedAction[];
24
+ export declare function inferAvailabilityFromFacts(states?: TargetStateFacts, contextHint?: string, options?: {
25
+ readonlyInteractive?: boolean;
26
+ }): TargetAvailabilityState;
27
+ export declare function inferControlFamilyFromFacts(facts: TargetSemanticsFacts, allowedActions: ReadonlyArray<TargetAllowedAction>): TargetControlFamily | undefined;
28
+ export declare function inferAcceptancePolicyFromFacts(facts: TargetSemanticsFacts, allowedActions: ReadonlyArray<TargetAllowedAction>): TargetAcceptancePolicy | undefined;
29
+ //# sourceMappingURL=control-semantics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"control-semantics.d.ts","sourceRoot":"","sources":["../src/control-semantics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,sBAAsB,EACtB,mBAAmB,EACnB,uBAAuB,EACvB,mBAAmB,EACnB,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAE5B,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC,CAAC;AAEzE,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,aAAa,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AAyCtF,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,oBAAoB,GAC1B,mBAAmB,GAAG,SAAS,CA2CjC;AAsCD,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAYxE;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,oBAAoB,GAC1B,mBAAmB,EAAE,CAiFvB;AAED,wBAAgB,0BAA0B,CACxC,MAAM,CAAC,EAAE,gBAAgB,EACzB,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,GAAE;IACP,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC1B,GACL,uBAAuB,CAyBzB;AAED,wBAAgB,2BAA2B,CACzC,KAAK,EAAE,oBAAoB,EAC3B,cAAc,EAAE,aAAa,CAAC,mBAAmB,CAAC,GACjD,mBAAmB,GAAG,SAAS,CA0EjC;AAED,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,oBAAoB,EAC3B,cAAc,EAAE,aAAa,CAAC,mBAAmB,CAAC,GACjD,sBAAsB,GAAG,SAAS,CAqDpC"}