browxai 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +139 -0
- package/THIRD_PARTY_NOTICES.md +45 -0
- package/dist/cli/chrome.d.ts +1 -0
- package/dist/cli/chrome.js +130 -0
- package/dist/cli/command-registry.d.ts +15 -0
- package/dist/cli/command-registry.js +35 -0
- package/dist/cli/doctor-plugins.d.ts +18 -0
- package/dist/cli/doctor-plugins.js +338 -0
- package/dist/cli/doctor.d.ts +9 -0
- package/dist/cli/doctor.js +407 -0
- package/dist/cli/init.d.ts +1 -0
- package/dist/cli/init.js +200 -0
- package/dist/cli/register-commands.d.ts +1 -0
- package/dist/cli/register-commands.js +22 -0
- package/dist/cli/serve.d.ts +14 -0
- package/dist/cli/serve.js +151 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +129 -0
- package/dist/engine/adapters/adb.d.ts +72 -0
- package/dist/engine/adapters/adb.js +200 -0
- package/dist/engine/adapters/android-cdp.d.ts +54 -0
- package/dist/engine/adapters/android-cdp.js +110 -0
- package/dist/engine/adapters/android.engine.d.ts +1 -0
- package/dist/engine/adapters/android.engine.js +31 -0
- package/dist/engine/adapters/chromium.engine.d.ts +1 -0
- package/dist/engine/adapters/chromium.engine.js +44 -0
- package/dist/engine/adapters/firefox.engine.d.ts +1 -0
- package/dist/engine/adapters/firefox.engine.js +43 -0
- package/dist/engine/adapters/playwright-chromium.d.ts +43 -0
- package/dist/engine/adapters/playwright-chromium.js +56 -0
- package/dist/engine/adapters/playwright-firefox.d.ts +52 -0
- package/dist/engine/adapters/playwright-firefox.js +97 -0
- package/dist/engine/adapters/playwright-webkit.d.ts +40 -0
- package/dist/engine/adapters/playwright-webkit.js +79 -0
- package/dist/engine/adapters/safari/bidi-client.d.ts +46 -0
- package/dist/engine/adapters/safari/bidi-client.js +130 -0
- package/dist/engine/adapters/safari/launch.d.ts +56 -0
- package/dist/engine/adapters/safari/launch.js +104 -0
- package/dist/engine/adapters/safari/webdriver-client.d.ts +102 -0
- package/dist/engine/adapters/safari/webdriver-client.js +175 -0
- package/dist/engine/adapters/safari.engine.d.ts +1 -0
- package/dist/engine/adapters/safari.engine.js +52 -0
- package/dist/engine/adapters/safaridriver-hybrid.d.ts +56 -0
- package/dist/engine/adapters/safaridriver-hybrid.js +127 -0
- package/dist/engine/adapters/webkit.engine.d.ts +1 -0
- package/dist/engine/adapters/webkit.engine.js +47 -0
- package/dist/engine/capabilities.d.ts +53 -0
- package/dist/engine/capabilities.js +122 -0
- package/dist/engine/capability-registry.d.ts +9 -0
- package/dist/engine/capability-registry.js +20 -0
- package/dist/engine/index.d.ts +18 -0
- package/dist/engine/index.js +14 -0
- package/dist/engine/register-engines.d.ts +5 -0
- package/dist/engine/register-engines.js +16 -0
- package/dist/engine/registry.d.ts +145 -0
- package/dist/engine/registry.js +67 -0
- package/dist/engine/select.d.ts +48 -0
- package/dist/engine/select.js +128 -0
- package/dist/engine/session-cdp.d.ts +13 -0
- package/dist/engine/session-cdp.js +22 -0
- package/dist/engine/tool-gate.d.ts +19 -0
- package/dist/engine/tool-gate.js +226 -0
- package/dist/engine/types.d.ts +71 -0
- package/dist/engine/types.js +16 -0
- package/dist/helper/bridge.d.ts +48 -0
- package/dist/helper/bridge.js +200 -0
- package/dist/helper/browx-page.d.ts +1 -0
- package/dist/helper/browx-page.js +47 -0
- package/dist/helper/overlay-hide.d.ts +9 -0
- package/dist/helper/overlay-hide.js +49 -0
- package/dist/helper/stealth.d.ts +10 -0
- package/dist/helper/stealth.js +88 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +15 -0
- package/dist/page/a11y.d.ts +81 -0
- package/dist/page/a11y.js +219 -0
- package/dist/page/action-substrate.d.ts +64 -0
- package/dist/page/action-substrate.js +118 -0
- package/dist/page/actionresult-blocks.d.ts +99 -0
- package/dist/page/actionresult-blocks.js +144 -0
- package/dist/page/actionresult-shape.d.ts +48 -0
- package/dist/page/actionresult-shape.js +155 -0
- package/dist/page/actionresult-types.d.ts +368 -0
- package/dist/page/actionresult-types.js +4 -0
- package/dist/page/actionresult.d.ts +4 -0
- package/dist/page/actionresult.js +299 -0
- package/dist/page/actions-probe.d.ts +32 -0
- package/dist/page/actions-probe.js +294 -0
- package/dist/page/actions-scroll.d.ts +40 -0
- package/dist/page/actions-scroll.js +53 -0
- package/dist/page/actions.d.ts +132 -0
- package/dist/page/actions.js +453 -0
- package/dist/page/archive-assets.d.ts +39 -0
- package/dist/page/archive-assets.js +187 -0
- package/dist/page/archive.d.ts +47 -0
- package/dist/page/archive.js +349 -0
- package/dist/page/asset-export.d.ts +122 -0
- package/dist/page/asset-export.js +376 -0
- package/dist/page/await_network.d.ts +16 -0
- package/dist/page/await_network.js +23 -0
- package/dist/page/bbox.d.ts +37 -0
- package/dist/page/bbox.js +115 -0
- package/dist/page/canvas-capture.d.ts +82 -0
- package/dist/page/canvas-capture.js +257 -0
- package/dist/page/canvas-diff.d.ts +51 -0
- package/dist/page/canvas-diff.js +131 -0
- package/dist/page/canvas-gesture.d.ts +53 -0
- package/dist/page/canvas-gesture.js +167 -0
- package/dist/page/canvas-transform.d.ts +96 -0
- package/dist/page/canvas-transform.js +150 -0
- package/dist/page/canvas.d.ts +8 -0
- package/dist/page/canvas.js +50 -0
- package/dist/page/capture-substrate.d.ts +111 -0
- package/dist/page/capture-substrate.js +139 -0
- package/dist/page/clipboard.d.ts +25 -0
- package/dist/page/clipboard.js +50 -0
- package/dist/page/clock.d.ts +36 -0
- package/dist/page/clock.js +167 -0
- package/dist/page/compose.d.ts +55 -0
- package/dist/page/compose.js +169 -0
- package/dist/page/console.d.ts +39 -0
- package/dist/page/console.js +73 -0
- package/dist/page/coverage.d.ts +97 -0
- package/dist/page/coverage.js +280 -0
- package/dist/page/dom-export.d.ts +41 -0
- package/dist/page/dom-export.js +193 -0
- package/dist/page/dom-walk.d.ts +91 -0
- package/dist/page/dom-walk.js +267 -0
- package/dist/page/dom_diff.d.ts +48 -0
- package/dist/page/dom_diff.js +121 -0
- package/dist/page/downloads.d.ts +80 -0
- package/dist/page/downloads.js +244 -0
- package/dist/page/drop-files.d.ts +78 -0
- package/dist/page/drop-files.js +310 -0
- package/dist/page/element-export-discovery.d.ts +64 -0
- package/dist/page/element-export-discovery.js +346 -0
- package/dist/page/element-export.d.ts +46 -0
- package/dist/page/element-export.js +251 -0
- package/dist/page/emulation-substrate.d.ts +53 -0
- package/dist/page/emulation-substrate.js +87 -0
- package/dist/page/emulation.d.ts +60 -0
- package/dist/page/emulation.js +162 -0
- package/dist/page/export-playwright-script.d.ts +47 -0
- package/dist/page/export-playwright-script.js +304 -0
- package/dist/page/extract-resolve.d.ts +22 -0
- package/dist/page/extract-resolve.js +341 -0
- package/dist/page/extract-schema.d.ts +20 -0
- package/dist/page/extract-schema.js +200 -0
- package/dist/page/extract-types.d.ts +127 -0
- package/dist/page/extract-types.js +8 -0
- package/dist/page/extract-warnings.d.ts +8 -0
- package/dist/page/extract-warnings.js +56 -0
- package/dist/page/extract.d.ts +9 -0
- package/dist/page/extract.js +174 -0
- package/dist/page/fill-form.d.ts +58 -0
- package/dist/page/fill-form.js +261 -0
- package/dist/page/find.d.ts +158 -0
- package/dist/page/find.js +470 -0
- package/dist/page/frames.d.ts +45 -0
- package/dist/page/frames.js +133 -0
- package/dist/page/generate-locator.d.ts +57 -0
- package/dist/page/generate-locator.js +136 -0
- package/dist/page/gestures.d.ts +128 -0
- package/dist/page/gestures.js +198 -0
- package/dist/page/har.d.ts +91 -0
- package/dist/page/har.js +174 -0
- package/dist/page/heap.d.ts +97 -0
- package/dist/page/heap.js +285 -0
- package/dist/page/inspect.d.ts +34 -0
- package/dist/page/inspect.js +75 -0
- package/dist/page/layout-thrash.d.ts +34 -0
- package/dist/page/layout-thrash.js +232 -0
- package/dist/page/learning.d.ts +21 -0
- package/dist/page/learning.js +84 -0
- package/dist/page/locator.d.ts +54 -0
- package/dist/page/locator.js +142 -0
- package/dist/page/memory-diff.d.ts +48 -0
- package/dist/page/memory-diff.js +105 -0
- package/dist/page/network-mask.d.ts +8 -0
- package/dist/page/network-mask.js +18 -0
- package/dist/page/network-playwright.d.ts +96 -0
- package/dist/page/network-playwright.js +353 -0
- package/dist/page/network-substrate-select.d.ts +18 -0
- package/dist/page/network-substrate-select.js +32 -0
- package/dist/page/network-substrate.d.ts +109 -0
- package/dist/page/network-substrate.js +161 -0
- package/dist/page/network-ws.d.ts +46 -0
- package/dist/page/network-ws.js +113 -0
- package/dist/page/network.d.ts +194 -0
- package/dist/page/network.js +415 -0
- package/dist/page/overflow-detect.d.ts +102 -0
- package/dist/page/overflow-detect.js +449 -0
- package/dist/page/pdf.d.ts +69 -0
- package/dist/page/pdf.js +109 -0
- package/dist/page/perf-audit-analysers.d.ts +40 -0
- package/dist/page/perf-audit-analysers.js +369 -0
- package/dist/page/perf-audit-runner.d.ts +20 -0
- package/dist/page/perf-audit-runner.js +195 -0
- package/dist/page/perf-audit-types.d.ts +41 -0
- package/dist/page/perf-audit-types.js +5 -0
- package/dist/page/perf-audit.d.ts +37 -0
- package/dist/page/perf-audit.js +377 -0
- package/dist/page/perf.d.ts +127 -0
- package/dist/page/perf.js +373 -0
- package/dist/page/plan.d.ts +192 -0
- package/dist/page/plan.js +308 -0
- package/dist/page/point_probe.d.ts +46 -0
- package/dist/page/point_probe.js +99 -0
- package/dist/page/recording.d.ts +67 -0
- package/dist/page/recording.js +172 -0
- package/dist/page/refs.d.ts +92 -0
- package/dist/page/refs.js +134 -0
- package/dist/page/regions.d.ts +23 -0
- package/dist/page/regions.js +32 -0
- package/dist/page/routes.d.ts +40 -0
- package/dist/page/routes.js +87 -0
- package/dist/page/safari-actions.d.ts +12 -0
- package/dist/page/safari-actions.js +144 -0
- package/dist/page/sample.d.ts +64 -0
- package/dist/page/sample.js +216 -0
- package/dist/page/screenshot-on.d.ts +51 -0
- package/dist/page/screenshot-on.js +150 -0
- package/dist/page/screenshot-save.d.ts +36 -0
- package/dist/page/screenshot-save.js +53 -0
- package/dist/page/screenshot-schedule.d.ts +50 -0
- package/dist/page/screenshot-schedule.js +155 -0
- package/dist/page/script-substrate.d.ts +32 -0
- package/dist/page/script-substrate.js +47 -0
- package/dist/page/seed-random.d.ts +45 -0
- package/dist/page/seed-random.js +144 -0
- package/dist/page/set-of-marks.d.ts +96 -0
- package/dist/page/set-of-marks.js +245 -0
- package/dist/page/shadow.d.ts +136 -0
- package/dist/page/shadow.js +400 -0
- package/dist/page/shortcut.d.ts +50 -0
- package/dist/page/shortcut.js +147 -0
- package/dist/page/snapshot-substrate-safari.d.ts +30 -0
- package/dist/page/snapshot-substrate-safari.js +84 -0
- package/dist/page/snapshot-substrate-select.d.ts +24 -0
- package/dist/page/snapshot-substrate-select.js +34 -0
- package/dist/page/snapshot-substrate.d.ts +58 -0
- package/dist/page/snapshot-substrate.js +135 -0
- package/dist/page/snapshot.d.ts +24 -0
- package/dist/page/snapshot.js +162 -0
- package/dist/page/solve-captcha.d.ts +76 -0
- package/dist/page/solve-captcha.js +286 -0
- package/dist/page/storage-substrate-types.d.ts +221 -0
- package/dist/page/storage-substrate-types.js +6 -0
- package/dist/page/storage-substrate.d.ts +215 -0
- package/dist/page/storage-substrate.js +280 -0
- package/dist/page/structural.d.ts +9 -0
- package/dist/page/structural.js +152 -0
- package/dist/page/substrate-bundle-safari.d.ts +8 -0
- package/dist/page/substrate-bundle-safari.js +42 -0
- package/dist/page/substrate-bundle.d.ts +6 -0
- package/dist/page/substrate-bundle.js +53 -0
- package/dist/page/text_search.d.ts +44 -0
- package/dist/page/text_search.js +90 -0
- package/dist/page/upload.d.ts +28 -0
- package/dist/page/upload.js +62 -0
- package/dist/page/verify.d.ts +63 -0
- package/dist/page/verify.js +451 -0
- package/dist/page/video.d.ts +115 -0
- package/dist/page/video.js +169 -0
- package/dist/page/visibility.d.ts +22 -0
- package/dist/page/visibility.js +94 -0
- package/dist/page/watch.d.ts +29 -0
- package/dist/page/watch.js +99 -0
- package/dist/page/workers.d.ts +126 -0
- package/dist/page/workers.js +490 -0
- package/dist/page/ws-interactive.d.ts +82 -0
- package/dist/page/ws-interactive.js +318 -0
- package/dist/plugin/cli.d.ts +45 -0
- package/dist/plugin/cli.js +496 -0
- package/dist/plugin/command-registry.d.ts +9 -0
- package/dist/plugin/command-registry.js +23 -0
- package/dist/plugin/depgraph.d.ts +37 -0
- package/dist/plugin/depgraph.js +186 -0
- package/dist/plugin/manifest.d.ts +182 -0
- package/dist/plugin/manifest.js +219 -0
- package/dist/plugin/package-manager.d.ts +22 -0
- package/dist/plugin/package-manager.js +40 -0
- package/dist/plugin/resolver.d.ts +85 -0
- package/dist/plugin/resolver.js +166 -0
- package/dist/plugin/runtime.d.ts +77 -0
- package/dist/plugin/runtime.js +402 -0
- package/dist/plugin/types.d.ts +113 -0
- package/dist/plugin/types.js +4 -0
- package/dist/policy/confirm.d.ts +76 -0
- package/dist/policy/confirm.js +162 -0
- package/dist/policy/origin.d.ts +17 -0
- package/dist/policy/origin.js +79 -0
- package/dist/sdk/client.d.ts +21 -0
- package/dist/sdk/client.js +174 -0
- package/dist/sdk/index.d.ts +32 -0
- package/dist/sdk/index.js +61 -0
- package/dist/sdk/plugin-types.d.ts +33 -0
- package/dist/sdk/plugin-types.js +22 -0
- package/dist/sdk/registry.d.ts +17 -0
- package/dist/sdk/registry.js +94 -0
- package/dist/sdk/socket-transport.d.ts +20 -0
- package/dist/sdk/socket-transport.js +90 -0
- package/dist/sdk/tool-types.d.ts +634 -0
- package/dist/sdk/tool-types.js +28 -0
- package/dist/sdk/transport-in-process.d.ts +21 -0
- package/dist/sdk/transport-in-process.js +44 -0
- package/dist/sdk/transport-registry.d.ts +19 -0
- package/dist/sdk/transport-registry.js +31 -0
- package/dist/sdk/transport-socket.d.ts +12 -0
- package/dist/sdk/transport-socket.js +77 -0
- package/dist/sdk/transport-stdio-child.d.ts +10 -0
- package/dist/sdk/transport-stdio-child.js +47 -0
- package/dist/sdk/transport.d.ts +10 -0
- package/dist/sdk/transport.js +35 -0
- package/dist/sdk/types.d.ts +176 -0
- package/dist/sdk/types.js +10 -0
- package/dist/server.d.ts +33 -0
- package/dist/server.js +327 -0
- package/dist/session/artifacts.d.ts +52 -0
- package/dist/session/artifacts.js +177 -0
- package/dist/session/byob-attach.d.ts +26 -0
- package/dist/session/byob-attach.js +187 -0
- package/dist/session/byob.d.ts +8 -0
- package/dist/session/byob.js +20 -0
- package/dist/session/cache-storage.d.ts +100 -0
- package/dist/session/cache-storage.js +166 -0
- package/dist/session/device-emu.d.ts +149 -0
- package/dist/session/device-emu.js +545 -0
- package/dist/session/device.d.ts +14 -0
- package/dist/session/device.js +44 -0
- package/dist/session/dialog.d.ts +62 -0
- package/dist/session/dialog.js +164 -0
- package/dist/session/emulation.d.ts +69 -0
- package/dist/session/emulation.js +168 -0
- package/dist/session/extensions.d.ts +113 -0
- package/dist/session/extensions.js +237 -0
- package/dist/session/fs-picker.d.ts +144 -0
- package/dist/session/fs-picker.js +666 -0
- package/dist/session/idb-storage.d.ts +86 -0
- package/dist/session/idb-storage.js +229 -0
- package/dist/session/incognito.d.ts +3 -0
- package/dist/session/incognito.js +20 -0
- package/dist/session/launch-options.d.ts +41 -0
- package/dist/session/launch-options.js +200 -0
- package/dist/session/managed.d.ts +3 -0
- package/dist/session/managed.js +16 -0
- package/dist/session/metrics.d.ts +45 -0
- package/dist/session/metrics.js +75 -0
- package/dist/session/notification.d.ts +122 -0
- package/dist/session/notification.js +426 -0
- package/dist/session/permission.d.ts +144 -0
- package/dist/session/permission.js +600 -0
- package/dist/session/playwright-post-wire.d.ts +8 -0
- package/dist/session/playwright-post-wire.js +148 -0
- package/dist/session/policy-buffer.d.ts +21 -0
- package/dist/session/policy-buffer.js +47 -0
- package/dist/session/profile-snapshot.d.ts +11 -0
- package/dist/session/profile-snapshot.js +53 -0
- package/dist/session/registry.d.ts +365 -0
- package/dist/session/registry.js +98 -0
- package/dist/session/safari-post-wire.d.ts +8 -0
- package/dist/session/safari-post-wire.js +28 -0
- package/dist/session/safari-session.d.ts +10 -0
- package/dist/session/safari-session.js +39 -0
- package/dist/session/storage.d.ts +148 -0
- package/dist/session/storage.js +350 -0
- package/dist/session/types.d.ts +113 -0
- package/dist/session/types.js +5 -0
- package/dist/session/wedge.d.ts +15 -0
- package/dist/session/wedge.js +41 -0
- package/dist/tools/action-core-tools.d.ts +13 -0
- package/dist/tools/action-core-tools.js +156 -0
- package/dist/tools/action-form-tools.d.ts +12 -0
- package/dist/tools/action-form-tools.js +179 -0
- package/dist/tools/action-gesture-tools.d.ts +9 -0
- package/dist/tools/action-gesture-tools.js +115 -0
- package/dist/tools/action-history-tools.d.ts +8 -0
- package/dist/tools/action-history-tools.js +67 -0
- package/dist/tools/action-tool.d.ts +42 -0
- package/dist/tools/action-tool.js +58 -0
- package/dist/tools/action-tools.d.ts +20 -0
- package/dist/tools/action-tools.js +28 -0
- package/dist/tools/batch-act-tools.d.ts +10 -0
- package/dist/tools/batch-act-tools.js +276 -0
- package/dist/tools/batch-human-tools.d.ts +8 -0
- package/dist/tools/batch-human-tools.js +148 -0
- package/dist/tools/canvas-tools.d.ts +40 -0
- package/dist/tools/canvas-tools.js +368 -0
- package/dist/tools/capture-report-diagnostics-tools.d.ts +7 -0
- package/dist/tools/capture-report-diagnostics-tools.js +318 -0
- package/dist/tools/capture-report-element-export-tools.d.ts +8 -0
- package/dist/tools/capture-report-element-export-tools.js +197 -0
- package/dist/tools/capture-report-export-tools.d.ts +8 -0
- package/dist/tools/capture-report-export-tools.js +246 -0
- package/dist/tools/capture-report-marks-tools.d.ts +9 -0
- package/dist/tools/capture-report-marks-tools.js +221 -0
- package/dist/tools/capture-report-upload-tools.d.ts +8 -0
- package/dist/tools/capture-report-upload-tools.js +277 -0
- package/dist/tools/config-approval-tools.d.ts +8 -0
- package/dist/tools/config-approval-tools.js +166 -0
- package/dist/tools/deep-coverage-tools.d.ts +8 -0
- package/dist/tools/deep-coverage-tools.js +325 -0
- package/dist/tools/deep-determinism-tools.d.ts +8 -0
- package/dist/tools/deep-determinism-tools.js +276 -0
- package/dist/tools/deep-perf-tools.d.ts +19 -0
- package/dist/tools/deep-perf-tools.js +324 -0
- package/dist/tools/device-emulation-tools.d.ts +9 -0
- package/dist/tools/device-emulation-tools.js +137 -0
- package/dist/tools/extensions-batch-tools.d.ts +18 -0
- package/dist/tools/extensions-batch-tools.js +24 -0
- package/dist/tools/extensions-rebuild.d.ts +22 -0
- package/dist/tools/extensions-rebuild.js +208 -0
- package/dist/tools/extensions-tools.d.ts +2 -0
- package/dist/tools/extensions-tools.js +331 -0
- package/dist/tools/forms-fill-tools.d.ts +8 -0
- package/dist/tools/forms-fill-tools.js +109 -0
- package/dist/tools/forms-plan-tools.d.ts +7 -0
- package/dist/tools/forms-plan-tools.js +159 -0
- package/dist/tools/forms-recording-mode-tools.d.ts +8 -0
- package/dist/tools/forms-recording-mode-tools.js +71 -0
- package/dist/tools/forms-recording-tools.d.ts +14 -0
- package/dist/tools/forms-recording-tools.js +22 -0
- package/dist/tools/forms-refs-tools.d.ts +8 -0
- package/dist/tools/forms-refs-tools.js +90 -0
- package/dist/tools/gesture-coord-tools.d.ts +8 -0
- package/dist/tools/gesture-coord-tools.js +168 -0
- package/dist/tools/gesture-emulation-tools.d.ts +8 -0
- package/dist/tools/gesture-emulation-tools.js +135 -0
- package/dist/tools/gesture-network-tools.d.ts +17 -0
- package/dist/tools/gesture-network-tools.js +27 -0
- package/dist/tools/gesture-route-tools.d.ts +8 -0
- package/dist/tools/gesture-route-tools.js +142 -0
- package/dist/tools/gesture-websocket-tools.d.ts +8 -0
- package/dist/tools/gesture-websocket-tools.js +122 -0
- package/dist/tools/gesture-worker-tools.d.ts +9 -0
- package/dist/tools/gesture-worker-tools.js +200 -0
- package/dist/tools/host-build.d.ts +76 -0
- package/dist/tools/host-build.js +516 -0
- package/dist/tools/host.d.ts +287 -0
- package/dist/tools/host.js +1 -0
- package/dist/tools/input-tools.d.ts +10 -0
- package/dist/tools/input-tools.js +176 -0
- package/dist/tools/live-emulation-tools.d.ts +9 -0
- package/dist/tools/live-emulation-tools.js +353 -0
- package/dist/tools/plugin-runtime.d.ts +36 -0
- package/dist/tools/plugin-runtime.js +274 -0
- package/dist/tools/read-observe-buffer-tools.d.ts +9 -0
- package/dist/tools/read-observe-buffer-tools.js +385 -0
- package/dist/tools/read-observe-capture-tools.d.ts +12 -0
- package/dist/tools/read-observe-capture-tools.js +376 -0
- package/dist/tools/read-observe-dom-tools.d.ts +8 -0
- package/dist/tools/read-observe-dom-tools.js +308 -0
- package/dist/tools/read-observe-extract-tools.d.ts +8 -0
- package/dist/tools/read-observe-extract-tools.js +232 -0
- package/dist/tools/read-observe-verify-tools.d.ts +8 -0
- package/dist/tools/read-observe-verify-tools.js +316 -0
- package/dist/tools/schemas.d.ts +29 -0
- package/dist/tools/schemas.js +58 -0
- package/dist/tools/secrets-captcha-tools.d.ts +9 -0
- package/dist/tools/secrets-captcha-tools.js +231 -0
- package/dist/tools/session-dialog-permission-tools.d.ts +9 -0
- package/dist/tools/session-dialog-permission-tools.js +287 -0
- package/dist/tools/session-lifecycle-tools.d.ts +8 -0
- package/dist/tools/session-lifecycle-tools.js +314 -0
- package/dist/tools/session-notification-device-tools.d.ts +9 -0
- package/dist/tools/session-notification-device-tools.js +156 -0
- package/dist/tools/session-policy-tools.d.ts +16 -0
- package/dist/tools/session-policy-tools.js +22 -0
- package/dist/tools/session-registry.d.ts +28 -0
- package/dist/tools/session-registry.js +427 -0
- package/dist/tools/storage-artifact-har-video-tools.d.ts +8 -0
- package/dist/tools/storage-artifact-har-video-tools.js +311 -0
- package/dist/tools/storage-cache-idb-tools.d.ts +8 -0
- package/dist/tools/storage-cache-idb-tools.js +347 -0
- package/dist/tools/storage-state-cookies-tools.d.ts +8 -0
- package/dist/tools/storage-state-cookies-tools.js +223 -0
- package/dist/tools/storage-tools.d.ts +17 -0
- package/dist/tools/storage-tools.js +25 -0
- package/dist/tools/storage-web-auth-tools.d.ts +10 -0
- package/dist/tools/storage-web-auth-tools.js +230 -0
- package/dist/tools/tool-metadata.d.ts +8 -0
- package/dist/tools/tool-metadata.js +185 -0
- package/dist/util/batch.d.ts +83 -0
- package/dist/util/batch.js +191 -0
- package/dist/util/capabilities.d.ts +504 -0
- package/dist/util/capabilities.js +254 -0
- package/dist/util/config-store.d.ts +103 -0
- package/dist/util/config-store.js +206 -0
- package/dist/util/config.d.ts +11 -0
- package/dist/util/config.js +28 -0
- package/dist/util/credentials.d.ts +136 -0
- package/dist/util/credentials.js +622 -0
- package/dist/util/deadline.d.ts +22 -0
- package/dist/util/deadline.js +62 -0
- package/dist/util/diagnostics.d.ts +161 -0
- package/dist/util/diagnostics.js +579 -0
- package/dist/util/egress-sanitiser.d.ts +29 -0
- package/dist/util/egress-sanitiser.js +52 -0
- package/dist/util/failure.d.ts +8 -0
- package/dist/util/failure.js +50 -0
- package/dist/util/flake-check.d.ts +109 -0
- package/dist/util/flake-check.js +342 -0
- package/dist/util/invariant.d.ts +25 -0
- package/dist/util/invariant.js +66 -0
- package/dist/util/logging.d.ts +6 -0
- package/dist/util/logging.js +12 -0
- package/dist/util/predicates.d.ts +62 -0
- package/dist/util/predicates.js +340 -0
- package/dist/util/secrets.d.ts +104 -0
- package/dist/util/secrets.js +219 -0
- package/dist/util/tokens.d.ts +6 -0
- package/dist/util/tokens.js +24 -0
- package/dist/util/url-sanitizer.d.ts +19 -0
- package/dist/util/url-sanitizer.js +70 -0
- package/dist/util/version.d.ts +2 -0
- package/dist/util/version.js +21 -0
- package/dist/util/workspace.d.ts +7 -0
- package/dist/util/workspace.js +22 -0
- package/package.json +120 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
// DOM-walk fallback — .
|
|
2
|
+
//
|
|
3
|
+
// The 2026-05-13 target-app adoption found that `Accessibility.getFullAXTree` returns
|
|
4
|
+
// root-only on heavy SPAs whose markup is mostly `div`s with `data-testid`/`data-type`
|
|
5
|
+
// (legacy-React / Reflux). With nothing in the a11y tree, find() degrades to tier-5
|
|
6
|
+
// `low` and the curated surface is no better than grep. The fix is to walk the DOM
|
|
7
|
+
// directly for interactive / data-attribute-bearing elements when the a11y signal is
|
|
8
|
+
// thin, and combine the two sources into the snapshot tree.
|
|
9
|
+
//
|
|
10
|
+
// Implementation: run a single `Runtime.evaluate` in page context that returns a
|
|
11
|
+
// JSON array of { role, name, testId, testIdAttr, tag, id, structuralPath } for
|
|
12
|
+
// every visible element matching the interactive predicate set OR carrying any of
|
|
13
|
+
// the configured test attributes. Convert to A11yNode (leaf nodes — DOM walk
|
|
14
|
+
// doesn't produce children; the a11y tree is the structural source).
|
|
15
|
+
import { elementKey } from "./refs.js";
|
|
16
|
+
const DEFAULT_TEST_ATTRS = ["data-testid", "data-test", "data-cy", "data-qa"];
|
|
17
|
+
const DEFAULT_MAX = 500;
|
|
18
|
+
/**
|
|
19
|
+
* Run the in-page DOM-walk and return the discovered entries.
|
|
20
|
+
*
|
|
21
|
+
* Notes:
|
|
22
|
+
* - The script runs in page context — keep it ECMAScript-only (no TS).
|
|
23
|
+
* - Stringified function so we can pass it through `Runtime.evaluate` with
|
|
24
|
+
* `returnByValue: true`.
|
|
25
|
+
* - Visibility is checked at walk time (`getBoundingClientRect` non-zero + computed
|
|
26
|
+
* `visibility !== hidden` + `display !== none`). This intentionally skips offscreen
|
|
27
|
+
* elements (they wouldn't be clickable from the agent's POV right now).
|
|
28
|
+
*/
|
|
29
|
+
export async function runDomWalk(cdp, opts = {}) {
|
|
30
|
+
const testAttrs = opts.testAttributes ?? DEFAULT_TEST_ATTRS;
|
|
31
|
+
const max = opts.maxEntries ?? DEFAULT_MAX;
|
|
32
|
+
// Back-compat: `pierce: undefined` preserves pre-v0.5.0 behaviour
|
|
33
|
+
// (top-document walk only). `pierce: "open"` / `"closed"` opts into the
|
|
34
|
+
// shadow-aware walk that recurses through every open shadow root we can
|
|
35
|
+
// see from the page side. Closed shadow roots are platform-inaccessible
|
|
36
|
+
// here; the CDP path in src/page/shadow.ts covers them and adds the
|
|
37
|
+
// result via the merge layer.
|
|
38
|
+
const walkOpen = opts.pierce === "open" || opts.pierce === "closed";
|
|
39
|
+
const expr = `(${PAGE_SCRIPT})(${JSON.stringify(testAttrs)}, ${max}, ${walkOpen})`;
|
|
40
|
+
try {
|
|
41
|
+
const { result } = (await cdp.send("Runtime.evaluate", {
|
|
42
|
+
expression: expr,
|
|
43
|
+
returnByValue: true,
|
|
44
|
+
awaitPromise: false,
|
|
45
|
+
}));
|
|
46
|
+
return result.value ?? [];
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Frame-scoped DOM walk. Same `PAGE_SCRIPT`, but evaluated inside
|
|
54
|
+
* a Playwright `Frame` via `frame.evaluate(...)` instead of the top-level
|
|
55
|
+
* CDP `Runtime.evaluate`. Works transparently for both same-origin and
|
|
56
|
+
* cross-origin (OOPIF) child frames — Playwright's frame API spans both.
|
|
57
|
+
*
|
|
58
|
+
* Honours `pierce` the same way the top-level walk does: `"open"` / `"closed"`
|
|
59
|
+
* recurses into reachable open shadow roots inside the frame; `false` /
|
|
60
|
+
* undefined sticks to the frame's top document. Closed-shadow CDP harvesting
|
|
61
|
+
* is not run for child frames (the CDP path is rooted at the top target).
|
|
62
|
+
*/
|
|
63
|
+
export async function runDomWalkOnFrame(frame, opts = {}) {
|
|
64
|
+
const testAttrs = opts.testAttributes ?? DEFAULT_TEST_ATTRS;
|
|
65
|
+
const max = opts.maxEntries ?? DEFAULT_MAX;
|
|
66
|
+
const walkOpen = opts.pierce === "open" || opts.pierce === "closed";
|
|
67
|
+
try {
|
|
68
|
+
const raw = await frame.evaluate(({ script, attrs, cap, openShadow, }) => {
|
|
69
|
+
// The page-side `Function` constructor produces an untyped callable;
|
|
70
|
+
// annotate its precise call signature (the PAGE_SCRIPT IIFE returns
|
|
71
|
+
// `DomWalkEntry[]`) so the invocation result is typed, not `any`.
|
|
72
|
+
// eslint-disable-next-line @typescript-eslint/no-implied-eval
|
|
73
|
+
const run = new Function("attrs", "cap", "openShadow", `return (${script})(attrs, cap, openShadow)`);
|
|
74
|
+
return run(attrs, cap, openShadow);
|
|
75
|
+
}, { script: PAGE_SCRIPT, attrs: testAttrs, cap: max, openShadow: walkOpen });
|
|
76
|
+
return raw ?? [];
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Transport-agnostic DOM walk. Runs the SAME `PAGE_SCRIPT` via an injected
|
|
84
|
+
* `exec` that takes a function BODY + an args array and returns the value —
|
|
85
|
+
* exactly the WebDriver-Classic `execute/sync` shape (`{script, args}`). This is
|
|
86
|
+
* the seam the Safari snapshot substrate uses: Safari has neither
|
|
87
|
+
* CDP nor a Playwright Frame, but `safaridriver`'s `execute/sync` runs the script
|
|
88
|
+
* identically (the returned `DomWalkEntry` shape matches
|
|
89
|
+
* `frame.evaluate` byte-for-byte).
|
|
90
|
+
* `PAGE_SCRIPT` stays encapsulated here; callers pass only the transport.
|
|
91
|
+
*/
|
|
92
|
+
export async function runDomWalkViaExecute(exec, opts = {}) {
|
|
93
|
+
const testAttrs = opts.testAttributes ?? DEFAULT_TEST_ATTRS;
|
|
94
|
+
const max = opts.maxEntries ?? DEFAULT_MAX;
|
|
95
|
+
const walkOpen = opts.pierce === "open" || opts.pierce === "closed";
|
|
96
|
+
try {
|
|
97
|
+
const raw = await exec(`return (${PAGE_SCRIPT})(arguments[0], arguments[1], arguments[2])`, [
|
|
98
|
+
testAttrs,
|
|
99
|
+
max,
|
|
100
|
+
walkOpen,
|
|
101
|
+
]);
|
|
102
|
+
return raw ?? [];
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/** Build the page-side script. Returned as a stringified IIFE.
|
|
109
|
+
* `walkOpenShadow` — when true, the DOM-walk additionally recurses into every
|
|
110
|
+
* `Element.shadowRoot` (open mode) and runs the same predicate-match on its
|
|
111
|
+
* descendants. Closed shadow roots are platform-protected and unreachable from
|
|
112
|
+
* the page side; the CDP path in `src/page/shadow.ts` covers them. */
|
|
113
|
+
const PAGE_SCRIPT = `function(testAttrs, max, walkOpenShadow) {
|
|
114
|
+
var ATTR_INTERACTIVE_SEL = '[role],button,a[href],input,select,textarea,[onclick],[tabindex],[contenteditable="true"]';
|
|
115
|
+
var attrSel = testAttrs.map(function(a){ return '['+a+']'; }).join(',');
|
|
116
|
+
var sel = ATTR_INTERACTIVE_SEL + (attrSel ? ',' + attrSel : '');
|
|
117
|
+
// Collect matches from the top document AND, when walkOpenShadow is set,
|
|
118
|
+
// from every open shadow root we can reach. querySelectorAll does NOT
|
|
119
|
+
// pierce shadow boundaries by web-platform design, so we walk shadow
|
|
120
|
+
// roots explicitly.
|
|
121
|
+
var els = Array.prototype.slice.call(document.querySelectorAll(sel));
|
|
122
|
+
if (walkOpenShadow) {
|
|
123
|
+
var shadowHosts = [];
|
|
124
|
+
function collectHosts(root) {
|
|
125
|
+
var all = root.querySelectorAll('*');
|
|
126
|
+
for (var i = 0; i < all.length; i++) {
|
|
127
|
+
var sr = all[i].shadowRoot;
|
|
128
|
+
if (sr) shadowHosts.push(sr);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
collectHosts(document);
|
|
132
|
+
var seen = 0;
|
|
133
|
+
while (shadowHosts.length > seen) {
|
|
134
|
+
var sr2 = shadowHosts[seen++];
|
|
135
|
+
var matches = sr2.querySelectorAll(sel);
|
|
136
|
+
for (var j = 0; j < matches.length; j++) els.push(matches[j]);
|
|
137
|
+
collectHosts(sr2);
|
|
138
|
+
// Hard bound — a pathological page could embed thousands of nested
|
|
139
|
+
// shadow roots; cap the walk to keep snapshot latency predictable.
|
|
140
|
+
if (seen > 500) break;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function isVisible(el) {
|
|
145
|
+
if (!el.isConnected) return false;
|
|
146
|
+
var r = el.getBoundingClientRect();
|
|
147
|
+
if (r.width === 0 && r.height === 0) return false;
|
|
148
|
+
var cs = getComputedStyle(el);
|
|
149
|
+
return cs.visibility !== 'hidden' && cs.display !== 'none';
|
|
150
|
+
}
|
|
151
|
+
function structuralPath(el) {
|
|
152
|
+
var parts = [];
|
|
153
|
+
var n = el;
|
|
154
|
+
while (n && n.nodeType === 1 && n.tagName !== 'HTML') {
|
|
155
|
+
var tag = n.tagName.toLowerCase();
|
|
156
|
+
var role = n.getAttribute('role') || '';
|
|
157
|
+
var parent = n.parentElement;
|
|
158
|
+
var idx = parent ? Array.prototype.indexOf.call(parent.children, n) : 0;
|
|
159
|
+
parts.unshift(tag + (role ? '@' + role : '') + '[' + idx + ']');
|
|
160
|
+
n = parent;
|
|
161
|
+
}
|
|
162
|
+
return parts.join('/');
|
|
163
|
+
}
|
|
164
|
+
function cssPath(el) {
|
|
165
|
+
var parts = [];
|
|
166
|
+
var n = el;
|
|
167
|
+
while (n && n.nodeType === 1 && n.tagName !== 'HTML') {
|
|
168
|
+
var tag = n.tagName.toLowerCase();
|
|
169
|
+
var parent = n.parentElement;
|
|
170
|
+
if (!parent) { parts.unshift(tag); break; }
|
|
171
|
+
var idx = Array.prototype.indexOf.call(parent.children, n) + 1;
|
|
172
|
+
parts.unshift(tag + ':nth-child(' + idx + ')');
|
|
173
|
+
n = parent;
|
|
174
|
+
}
|
|
175
|
+
return parts.join(' > ');
|
|
176
|
+
}
|
|
177
|
+
function nameFor(el) {
|
|
178
|
+
var aria = el.getAttribute('aria-label');
|
|
179
|
+
if (aria) return aria.trim().slice(0, 120);
|
|
180
|
+
var lid = el.getAttribute('aria-labelledby');
|
|
181
|
+
if (lid) {
|
|
182
|
+
var parts = lid.split(/\\s+/).map(function(id){ var n = document.getElementById(id); return n ? (n.textContent || '') : ''; });
|
|
183
|
+
var s = parts.join(' ').trim();
|
|
184
|
+
if (s) return s.slice(0, 120);
|
|
185
|
+
}
|
|
186
|
+
if (el.tagName === 'INPUT') {
|
|
187
|
+
if (el.placeholder) return el.placeholder.trim().slice(0, 120);
|
|
188
|
+
if (el.value && el.type !== 'password') return String(el.value).trim().slice(0, 120);
|
|
189
|
+
}
|
|
190
|
+
var text = (el.textContent || '').replace(/\\s+/g, ' ').trim();
|
|
191
|
+
if (text && text.length <= 120) return text;
|
|
192
|
+
// title attribute as last-resort label source. Icon-only buttons
|
|
193
|
+
// commonly carry their visible label here when neither aria-label nor
|
|
194
|
+
// textContent (the icon's empty span) is set.
|
|
195
|
+
var title = el.getAttribute('title');
|
|
196
|
+
if (title) return title.trim().slice(0, 120);
|
|
197
|
+
return '';
|
|
198
|
+
}
|
|
199
|
+
function testIdFor(el) {
|
|
200
|
+
for (var i = 0; i < testAttrs.length; i++) {
|
|
201
|
+
var a = testAttrs[i];
|
|
202
|
+
var v = el.getAttribute(a);
|
|
203
|
+
if (v) return { attr: a, value: v };
|
|
204
|
+
}
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
var out = [];
|
|
208
|
+
for (var i = 0; i < els.length && out.length < max; i++) {
|
|
209
|
+
var el = els[i];
|
|
210
|
+
if (!isVisible(el)) continue;
|
|
211
|
+
var tag = el.tagName.toLowerCase();
|
|
212
|
+
var role = el.getAttribute('role') || tag;
|
|
213
|
+
var tid = testIdFor(el);
|
|
214
|
+
out.push({
|
|
215
|
+
role: role,
|
|
216
|
+
name: nameFor(el),
|
|
217
|
+
testId: tid ? tid.value : '',
|
|
218
|
+
testIdAttr: tid ? tid.attr : '',
|
|
219
|
+
tag: tag,
|
|
220
|
+
id: el.id || '',
|
|
221
|
+
structuralPath: structuralPath(el),
|
|
222
|
+
cssPath: cssPath(el)
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
return out;
|
|
226
|
+
}`;
|
|
227
|
+
export function mergeDomWalkIntoTree(root, entries, refs, opts = {}) {
|
|
228
|
+
let added = 0;
|
|
229
|
+
let combined = 0;
|
|
230
|
+
const { frameId, frame } = opts;
|
|
231
|
+
for (const e of entries) {
|
|
232
|
+
const name = e.name || undefined;
|
|
233
|
+
const testId = e.testId || undefined;
|
|
234
|
+
const testIdAttr = e.testIdAttr || undefined;
|
|
235
|
+
const key = elementKey({ role: e.role, name, path: e.structuralPath, testId, frameId });
|
|
236
|
+
const wasNew = !refs.hasKey(key);
|
|
237
|
+
const ref = refs.forKey(key);
|
|
238
|
+
refs.augmentLocator(ref, {
|
|
239
|
+
role: e.role,
|
|
240
|
+
name,
|
|
241
|
+
testId,
|
|
242
|
+
testIdAttr,
|
|
243
|
+
cssPath: e.cssPath,
|
|
244
|
+
source: wasNew ? "dom" : "both",
|
|
245
|
+
...(frameId ? { frameId } : {}),
|
|
246
|
+
});
|
|
247
|
+
if (frame)
|
|
248
|
+
refs.bindFrame(ref, frame);
|
|
249
|
+
const node = {
|
|
250
|
+
ref,
|
|
251
|
+
role: e.role,
|
|
252
|
+
name,
|
|
253
|
+
testId,
|
|
254
|
+
testIdAttr,
|
|
255
|
+
tag: e.tag,
|
|
256
|
+
id: e.id || undefined,
|
|
257
|
+
source: wasNew ? "dom" : "both",
|
|
258
|
+
children: [],
|
|
259
|
+
};
|
|
260
|
+
root.children.push(node);
|
|
261
|
+
if (wasNew)
|
|
262
|
+
added++;
|
|
263
|
+
else
|
|
264
|
+
combined++;
|
|
265
|
+
}
|
|
266
|
+
return { added, combined };
|
|
267
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { Page } from "playwright-core";
|
|
2
|
+
export interface DomNode {
|
|
3
|
+
tag: string;
|
|
4
|
+
testId?: string;
|
|
5
|
+
classes: string;
|
|
6
|
+
style: string;
|
|
7
|
+
attrs: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
/** keyed by a structural index path from the scope root, e.g. "0/2/1". */
|
|
10
|
+
export type DomMap = Record<string, DomNode>;
|
|
11
|
+
export declare function captureDomMap(page: Page, scopeSelector?: string): Promise<DomMap | null>;
|
|
12
|
+
export interface DomChange {
|
|
13
|
+
path: string;
|
|
14
|
+
tag: string;
|
|
15
|
+
testId?: string;
|
|
16
|
+
classDelta?: {
|
|
17
|
+
added: string[];
|
|
18
|
+
removed: string[];
|
|
19
|
+
};
|
|
20
|
+
styleDelta?: {
|
|
21
|
+
before: string;
|
|
22
|
+
after: string;
|
|
23
|
+
};
|
|
24
|
+
attrDelta?: Record<string, {
|
|
25
|
+
before?: string;
|
|
26
|
+
after?: string;
|
|
27
|
+
}>;
|
|
28
|
+
}
|
|
29
|
+
export interface DomDiff {
|
|
30
|
+
changed: DomChange[];
|
|
31
|
+
added: Array<{
|
|
32
|
+
path: string;
|
|
33
|
+
tag: string;
|
|
34
|
+
testId?: string;
|
|
35
|
+
}>;
|
|
36
|
+
removed: Array<{
|
|
37
|
+
path: string;
|
|
38
|
+
tag: string;
|
|
39
|
+
testId?: string;
|
|
40
|
+
}>;
|
|
41
|
+
counts: {
|
|
42
|
+
changed: number;
|
|
43
|
+
added: number;
|
|
44
|
+
removed: number;
|
|
45
|
+
};
|
|
46
|
+
note?: string;
|
|
47
|
+
}
|
|
48
|
+
export declare function diffDomMaps(before: DomMap | null, after: DomMap | null): DomDiff;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// Scoped DOM diff around an action.
|
|
2
|
+
//
|
|
3
|
+
// For selection-heavy UIs (timeline editors, kanban, custom toggles) the
|
|
4
|
+
// state change an agent must verify — "which clip became selected" — is
|
|
5
|
+
// expressed only as class / `aria-*` / `data-*` / inline-style changes, not
|
|
6
|
+
// visible text or accessibility-tree changes that snapshot/find would catch.
|
|
7
|
+
// `act_and_diff` captures a structural DOM map before and after one action
|
|
8
|
+
// and reports exactly which elements changed which of those fields.
|
|
9
|
+
const MAX_NODES = 3000;
|
|
10
|
+
// Fixed in-page snapshot — no agent JS. Walks the scope subtree, recording
|
|
11
|
+
// each element's class/style and only its aria-*/data-* attributes (the
|
|
12
|
+
// fields selection state hides in), keyed by structural index path.
|
|
13
|
+
//
|
|
14
|
+
// `page.evaluate(string)` treats the string as an *expression* (a
|
|
15
|
+
// `function(arg){…}` string is never called, args ignored) — so this is an
|
|
16
|
+
// arg-less IIFE with the scope selector interpolated as a JSON string literal.
|
|
17
|
+
function buildSnapScript(scopeSelector) {
|
|
18
|
+
return `(() => {
|
|
19
|
+
var scopeSel = ${JSON.stringify(scopeSelector)};
|
|
20
|
+
var root = scopeSel ? document.querySelector(scopeSel) : document.body;
|
|
21
|
+
if (!root) return null;
|
|
22
|
+
var out = {};
|
|
23
|
+
var count = 0;
|
|
24
|
+
function walk(el, path) {
|
|
25
|
+
if (count >= ${MAX_NODES}) return;
|
|
26
|
+
count++;
|
|
27
|
+
var attrs = {};
|
|
28
|
+
for (var i = 0; i < el.attributes.length; i++) {
|
|
29
|
+
var a = el.attributes[i];
|
|
30
|
+
if (a.name.indexOf('aria-') === 0 || a.name.indexOf('data-') === 0) attrs[a.name] = a.value;
|
|
31
|
+
}
|
|
32
|
+
out[path] = {
|
|
33
|
+
tag: el.tagName.toLowerCase(),
|
|
34
|
+
testId: el.getAttribute('data-testid') || undefined,
|
|
35
|
+
classes: el.getAttribute('class') || '',
|
|
36
|
+
style: el.getAttribute('style') || '',
|
|
37
|
+
attrs: attrs,
|
|
38
|
+
};
|
|
39
|
+
var k = 0;
|
|
40
|
+
for (var c = 0; c < el.children.length; c++) walk(el.children[c], path + '/' + (k++));
|
|
41
|
+
}
|
|
42
|
+
walk(root, '0');
|
|
43
|
+
return out;
|
|
44
|
+
})()`;
|
|
45
|
+
}
|
|
46
|
+
export async function captureDomMap(page, scopeSelector) {
|
|
47
|
+
return await page.evaluate(buildSnapScript(scopeSelector ?? null));
|
|
48
|
+
}
|
|
49
|
+
function tokens(s) {
|
|
50
|
+
return new Set(s.split(/\s+/).filter(Boolean));
|
|
51
|
+
}
|
|
52
|
+
/** Pure structural diff of two DOM maps. Exported for unit tests. */
|
|
53
|
+
/** Compute the per-attribute delta between two attribute maps, or null when
|
|
54
|
+
* nothing changed. */
|
|
55
|
+
function attrDeltaOf(b, a) {
|
|
56
|
+
const delta = {};
|
|
57
|
+
for (const k of new Set([...Object.keys(b), ...Object.keys(a)])) {
|
|
58
|
+
if (b[k] !== a[k])
|
|
59
|
+
delta[k] = { before: b[k], after: a[k] };
|
|
60
|
+
}
|
|
61
|
+
return Object.keys(delta).length ? delta : null;
|
|
62
|
+
}
|
|
63
|
+
/** Diff one node (present before AND after) into a `DomChange`, or null when it
|
|
64
|
+
* is unchanged across class / style / attribute dimensions. */
|
|
65
|
+
function diffNode(path, b, a) {
|
|
66
|
+
const change = { path, tag: a.tag, ...(a.testId ? { testId: a.testId } : {}) };
|
|
67
|
+
let dirty = false;
|
|
68
|
+
if (b.classes !== a.classes) {
|
|
69
|
+
const bt = tokens(b.classes);
|
|
70
|
+
const at = tokens(a.classes);
|
|
71
|
+
change.classDelta = {
|
|
72
|
+
added: [...at].filter((t) => !bt.has(t)),
|
|
73
|
+
removed: [...bt].filter((t) => !at.has(t)),
|
|
74
|
+
};
|
|
75
|
+
dirty = true;
|
|
76
|
+
}
|
|
77
|
+
if (b.style !== a.style) {
|
|
78
|
+
change.styleDelta = { before: b.style, after: a.style };
|
|
79
|
+
dirty = true;
|
|
80
|
+
}
|
|
81
|
+
const attrDelta = attrDeltaOf(b.attrs, a.attrs);
|
|
82
|
+
if (attrDelta) {
|
|
83
|
+
change.attrDelta = attrDelta;
|
|
84
|
+
dirty = true;
|
|
85
|
+
}
|
|
86
|
+
return dirty ? change : null;
|
|
87
|
+
}
|
|
88
|
+
export function diffDomMaps(before, after) {
|
|
89
|
+
const changed = [];
|
|
90
|
+
const added = [];
|
|
91
|
+
const removed = [];
|
|
92
|
+
if (!before || !after) {
|
|
93
|
+
return {
|
|
94
|
+
changed,
|
|
95
|
+
added,
|
|
96
|
+
removed,
|
|
97
|
+
counts: { changed: 0, added: 0, removed: 0 },
|
|
98
|
+
note: "scope did not resolve before and/or after the action — pass a `scope` selector that exists across the transition",
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
for (const [path, b] of Object.entries(before)) {
|
|
102
|
+
const a = after[path];
|
|
103
|
+
if (!a) {
|
|
104
|
+
removed.push({ path, tag: b.tag, ...(b.testId ? { testId: b.testId } : {}) });
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
const change = diffNode(path, b, a);
|
|
108
|
+
if (change)
|
|
109
|
+
changed.push(change);
|
|
110
|
+
}
|
|
111
|
+
for (const [path, a] of Object.entries(after)) {
|
|
112
|
+
if (!before[path])
|
|
113
|
+
added.push({ path, tag: a.tag, ...(a.testId ? { testId: a.testId } : {}) });
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
changed,
|
|
117
|
+
added,
|
|
118
|
+
removed,
|
|
119
|
+
counts: { changed: changed.length, added: added.length, removed: removed.length },
|
|
120
|
+
};
|
|
121
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { BrowserContext } from "playwright-core";
|
|
2
|
+
/** What lands on `ActionResult.downloads[]` and `download_get`. Workspace-rooted
|
|
3
|
+
* paths only; never absolute outside `$BROWX_WORKSPACE`. */
|
|
4
|
+
export interface CapturedDownload {
|
|
5
|
+
/** session-local monotonic id (`d1`, `d2`, …) — pass back to `download_get`. */
|
|
6
|
+
id: string;
|
|
7
|
+
/** filename the page suggested (sanitised; raw value kept too). */
|
|
8
|
+
suggestedFilename: string;
|
|
9
|
+
/** raw page-supplied filename pre-sanitisation, only present when sanitisation
|
|
10
|
+
* changed it. Useful when an agent wants to know the original (e.g. routing
|
|
11
|
+
* decisions) but the on-disk name diverged. */
|
|
12
|
+
rawSuggestedFilename?: string;
|
|
13
|
+
/** best-effort MIME type. Playwright doesn't expose the HTTP `Content-Type`
|
|
14
|
+
* on `Download`, so this is filename-extension-inferred. May be undefined. */
|
|
15
|
+
mimeType?: string;
|
|
16
|
+
/** size of the persisted file in bytes. 0 if the file vanished before we
|
|
17
|
+
* could stat it (best-effort). */
|
|
18
|
+
sizeBytes: number;
|
|
19
|
+
/** absolute on-disk path, ALWAYS rooted under `$BROWX_WORKSPACE/.downloads/`. */
|
|
20
|
+
path: string;
|
|
21
|
+
/** epoch-ms when the download fired. */
|
|
22
|
+
capturedAt: number;
|
|
23
|
+
}
|
|
24
|
+
/** Per-session download registry. One instance per SessionEntry. */
|
|
25
|
+
export declare class DownloadsRegistry {
|
|
26
|
+
/** Per-session storage dir: `$BROWX_WORKSPACE/.downloads/<sessionId>/`. */
|
|
27
|
+
readonly storageDir: string;
|
|
28
|
+
/** Toggled by the `downloads_capture` MCP tool. */
|
|
29
|
+
captureOn: boolean;
|
|
30
|
+
/** Active captures, keyed by id. Bounded to MAX_ENTRIES — oldest evicted. */
|
|
31
|
+
private entries;
|
|
32
|
+
private nextId;
|
|
33
|
+
/** Captures that have fired and are not yet sliced into an ActionResult. */
|
|
34
|
+
private pendingSince;
|
|
35
|
+
/** Max captures kept in memory + on disk per session before LRU-evicting
|
|
36
|
+
* the oldest. Prevents an unbounded download loop from filling the disk. */
|
|
37
|
+
private static MAX_ENTRIES;
|
|
38
|
+
constructor(
|
|
39
|
+
/** Per-session storage dir: `$BROWX_WORKSPACE/.downloads/<sessionId>/`. */
|
|
40
|
+
storageDir: string);
|
|
41
|
+
/** List all captured downloads for this session (most-recent first). */
|
|
42
|
+
list(): CapturedDownload[];
|
|
43
|
+
/** Look up a capture by id; undefined if not present. */
|
|
44
|
+
get(id: string): CapturedDownload | undefined;
|
|
45
|
+
/** Slice captures that fired after `tsMs` (action-window slice). Returns a
|
|
46
|
+
* snapshot of the captures so the action-window can include them on the
|
|
47
|
+
* ActionResult without exposing the live registry. */
|
|
48
|
+
since(tsMs: number): CapturedDownload[];
|
|
49
|
+
/** Record a capture. Caller has already persisted the file at `path`. */
|
|
50
|
+
record(record: Omit<CapturedDownload, "id">): CapturedDownload;
|
|
51
|
+
}
|
|
52
|
+
/** Sanitise a page-supplied filename for safe on-disk use. Rules (mirrors the
|
|
53
|
+
* workspace-escape posture in `upload.ts`):
|
|
54
|
+
* - strip path separators (`/`, `\`) and NUL/control bytes — collapses any
|
|
55
|
+
* traversal attempt to a flat filename.
|
|
56
|
+
* - reject leading dots so we never write to a hidden `.foo` file.
|
|
57
|
+
* - cap at 200 chars (leaves room for the `<id>-` prefix on filesystems
|
|
58
|
+
* with 255-byte name limits).
|
|
59
|
+
* - empty / all-stripped → fall back to `"download"`.
|
|
60
|
+
* Exported for unit tests. */
|
|
61
|
+
export declare function sanitiseFilename(raw: string): string;
|
|
62
|
+
/** Best-effort MIME type from a filename extension. Tiny built-in table; this
|
|
63
|
+
* is metadata only (we never reject on it), so an unknown extension just
|
|
64
|
+
* yields `undefined`. */
|
|
65
|
+
export declare function mimeTypeFromName(name: string): string | undefined;
|
|
66
|
+
/** Attach the Playwright `download` listener to a context. The listener fires
|
|
67
|
+
* for every download on every page in the context (now or later). When
|
|
68
|
+
* capture is OFF the artifact is silently deleted; when ON it's persisted and
|
|
69
|
+
* the registry records it. Errors during capture never propagate — they
|
|
70
|
+
* surface as warnings on the session's log only. */
|
|
71
|
+
export declare function attachDownloadCapture(context: BrowserContext, registry: DownloadsRegistry): void;
|
|
72
|
+
/** Read a captured download's bytes. Returns base64. Throws if the id is
|
|
73
|
+
* unknown or the file vanished. */
|
|
74
|
+
export declare function readCapturedBytes(reg: DownloadsRegistry, id: string): {
|
|
75
|
+
base64: string;
|
|
76
|
+
bytes: number;
|
|
77
|
+
path: string;
|
|
78
|
+
mimeType?: string;
|
|
79
|
+
suggestedFilename: string;
|
|
80
|
+
};
|