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,280 @@
|
|
|
1
|
+
// Coverage — capability split: `coverage_start` is `action` (arms CDP state
|
|
2
|
+
// on the target); `coverage_stop` is `read` (pure stop + parse, no file
|
|
3
|
+
// written, no further mutation past releasing the in-flight state).
|
|
4
|
+
//
|
|
5
|
+
// "Half of this CSS file is dead — which selectors?" + "We ship 200KB of JS
|
|
6
|
+
// but boot only uses 30KB — what's unused?" have no diagnostic surface in
|
|
7
|
+
// the existing perf primitives (`perf_audit` consumes coverage *output*; the
|
|
8
|
+
// production of that output is here). Wraps two CDP primitives in lockstep:
|
|
9
|
+
//
|
|
10
|
+
// - `Profiler.startPreciseCoverage` — per-script byte-level use counts.
|
|
11
|
+
// - `CSS.startRuleUsageTracking` — per-stylesheet rule-level use
|
|
12
|
+
// counts (which selectors fired).
|
|
13
|
+
//
|
|
14
|
+
// Lifecycle:
|
|
15
|
+
// - coverage_start({session?}) → enables both trackers on this session's
|
|
16
|
+
// CDP target. Idempotent restart: a fresh
|
|
17
|
+
// `coverage_start` while one is already
|
|
18
|
+
// running cleanly stops the in-flight pair
|
|
19
|
+
// and starts new.
|
|
20
|
+
// - coverage_stop({session?}) → stops both trackers, fetches the buffered
|
|
21
|
+
// results (Profiler.takePreciseCoverage +
|
|
22
|
+
// CSS.takeCoverageDelta), parses into the
|
|
23
|
+
// structured shape the agent reads, and
|
|
24
|
+
// surfaces it. Composes inside `perf_audit`
|
|
25
|
+
// when the audit window spans them.
|
|
26
|
+
//
|
|
27
|
+
// Both shapes are surfaced as `usagePercent` so the agent can scan a table
|
|
28
|
+
// of "delete me first" candidates without bringing a calculator. JS scripts
|
|
29
|
+
// with `usagePercent < 100` and CSS files with `usagePercent < 100` indicate
|
|
30
|
+
// dead code. The audit's `unused-code` category uses a 30% floor (anything
|
|
31
|
+
// below that is "obviously dead, fix first").
|
|
32
|
+
const MAX_DEAD_RANGES_PER_SCRIPT = 50;
|
|
33
|
+
/** Per-session coverage tracker. One instance per SessionEntry; the
|
|
34
|
+
* underlying CDP coverage is per-target. */
|
|
35
|
+
export class CoverageTrackerState {
|
|
36
|
+
running = false;
|
|
37
|
+
startedAt = 0;
|
|
38
|
+
/** Snapshot of `getAllStyleSheets()` taken at `start` so `stop` can map
|
|
39
|
+
* styleSheetId → URL + total length without a second CDP roundtrip. */
|
|
40
|
+
cssHeaders = new Map();
|
|
41
|
+
/** CSS.styleSheetAdded event handler — kept for cleanup. */
|
|
42
|
+
onStyleSheetAdded = null;
|
|
43
|
+
isRunning() {
|
|
44
|
+
return this.running;
|
|
45
|
+
}
|
|
46
|
+
/** Start both Profiler + CSS coverage on `cdp`. Returns `{restarted}` —
|
|
47
|
+
* if an instance was already running, it is cleanly stopped (results
|
|
48
|
+
* discarded) and a fresh one begins. */
|
|
49
|
+
async start(cdp) {
|
|
50
|
+
let restarted = false;
|
|
51
|
+
if (this.running) {
|
|
52
|
+
restarted = true;
|
|
53
|
+
await this.stopInternal(cdp).catch(() => undefined);
|
|
54
|
+
}
|
|
55
|
+
this.cssHeaders = new Map();
|
|
56
|
+
// Enable + start profiler precise coverage. `detailed:true` gives us
|
|
57
|
+
// per-function block ranges (we use them to compute used bytes); other
|
|
58
|
+
// params keep CPU profiling off — we just want coverage.
|
|
59
|
+
await cdp.send("Profiler.enable").catch(() => undefined);
|
|
60
|
+
await cdp.send("Profiler.startPreciseCoverage", {
|
|
61
|
+
callCount: false,
|
|
62
|
+
detailed: true,
|
|
63
|
+
allowTriggeredUpdates: false,
|
|
64
|
+
});
|
|
65
|
+
// Enable + start CSS rule usage tracking. Capture pre-existing
|
|
66
|
+
// stylesheets via styleSheetAdded events while tracking is on (the CDP
|
|
67
|
+
// event stream is the way to get the URL + length mapping for
|
|
68
|
+
// styleSheetId; calling `CSS.getStyleSheetText` per id would be slow).
|
|
69
|
+
await cdp.send("DOM.enable").catch(() => undefined);
|
|
70
|
+
await cdp.send("CSS.enable").catch(() => undefined);
|
|
71
|
+
const onAdded = (e) => {
|
|
72
|
+
if (e?.header?.styleSheetId)
|
|
73
|
+
this.cssHeaders.set(e.header.styleSheetId, e.header);
|
|
74
|
+
};
|
|
75
|
+
cdp.on("CSS.styleSheetAdded", onAdded);
|
|
76
|
+
this.onStyleSheetAdded = onAdded;
|
|
77
|
+
await cdp.send("CSS.startRuleUsageTracking");
|
|
78
|
+
this.running = true;
|
|
79
|
+
this.startedAt = Date.now();
|
|
80
|
+
return { startedAt: this.startedAt, restarted };
|
|
81
|
+
}
|
|
82
|
+
/** Stop both trackers, fetch + parse the results. Safe to call when no
|
|
83
|
+
* coverage is running — returns an empty report with `notRunning:true`. */
|
|
84
|
+
async stop(cdp) {
|
|
85
|
+
if (!this.running) {
|
|
86
|
+
return { jsCoverage: [], cssCoverage: [], durationMs: 0, notRunning: true };
|
|
87
|
+
}
|
|
88
|
+
const durationMs = Date.now() - this.startedAt;
|
|
89
|
+
let jsRaw = {};
|
|
90
|
+
let cssRaw = {};
|
|
91
|
+
try {
|
|
92
|
+
jsRaw = await cdp.send("Profiler.takePreciseCoverage");
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
jsRaw = { result: [] };
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
cssRaw = await cdp.send("CSS.stopRuleUsageTracking");
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
cssRaw = { ruleUsage: [] };
|
|
102
|
+
}
|
|
103
|
+
await this.stopInternal(cdp);
|
|
104
|
+
return {
|
|
105
|
+
jsCoverage: parseJsCoverage(jsRaw.result ?? []),
|
|
106
|
+
cssCoverage: parseCssCoverage(cssRaw.ruleUsage ?? [], this.cssHeaders),
|
|
107
|
+
durationMs,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/** Force-clean teardown for session close. */
|
|
111
|
+
async closeIfRunning(cdp) {
|
|
112
|
+
if (!this.running)
|
|
113
|
+
return;
|
|
114
|
+
await this.stopInternal(cdp).catch(() => undefined);
|
|
115
|
+
}
|
|
116
|
+
async stopInternal(cdp) {
|
|
117
|
+
try {
|
|
118
|
+
await cdp.send("Profiler.stopPreciseCoverage").catch(() => undefined);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
/* best-effort */
|
|
122
|
+
}
|
|
123
|
+
if (this.onStyleSheetAdded) {
|
|
124
|
+
try {
|
|
125
|
+
cdp.off("CSS.styleSheetAdded", this.onStyleSheetAdded);
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
/* best-effort */
|
|
129
|
+
}
|
|
130
|
+
this.onStyleSheetAdded = null;
|
|
131
|
+
}
|
|
132
|
+
this.running = false;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/** Parse the `Profiler.takePreciseCoverage` result into per-script entries.
|
|
136
|
+
* Exported for unit tests against a synthetic CDP payload.
|
|
137
|
+
*
|
|
138
|
+
* V8 coverage shape: each script has multiple `functions` entries. The
|
|
139
|
+
* first is the synthetic "outer" anonymous wrapper covering the whole
|
|
140
|
+
* script — its count is the script-level execution counter and tells us
|
|
141
|
+
* nothing about which bytes ran. The remaining entries are real functions
|
|
142
|
+
* (or block-coverage subranges within them). The way DevTools' Coverage
|
|
143
|
+
* panel computes "used":
|
|
144
|
+
* - For each function, if its first (root) range has count:0, the entire
|
|
145
|
+
* function body is dead.
|
|
146
|
+
* - Otherwise, the function ran; if `isBlockCoverage:true`, sub-ranges
|
|
147
|
+
* with count:0 are dead blocks within the live function.
|
|
148
|
+
* We follow the same algorithm: aggregate per-function dead ranges, then
|
|
149
|
+
* total used = script length - sum of dead ranges. */
|
|
150
|
+
/** The script's total byte span = the largest `endOffset` across all ranges. */
|
|
151
|
+
function scriptTotalSpan(s) {
|
|
152
|
+
let total = 0;
|
|
153
|
+
for (const fn of s.functions ?? []) {
|
|
154
|
+
for (const r of fn.ranges ?? []) {
|
|
155
|
+
if (typeof r.endOffset === "number" && r.endOffset > total)
|
|
156
|
+
total = r.endOffset;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return total;
|
|
160
|
+
}
|
|
161
|
+
/** Collect dead (count:0) byte ranges. The first range in each `ranges[]` is the
|
|
162
|
+
* function body; subsequent ranges are sub-blocks (when isBlockCoverage:true). */
|
|
163
|
+
function collectDeadRanges(s) {
|
|
164
|
+
const deadRanges = [];
|
|
165
|
+
for (const fn of s.functions ?? []) {
|
|
166
|
+
const ranges = fn.ranges ?? [];
|
|
167
|
+
if (ranges.length === 0)
|
|
168
|
+
continue;
|
|
169
|
+
const root = ranges[0];
|
|
170
|
+
if (typeof root.startOffset !== "number" || typeof root.endOffset !== "number")
|
|
171
|
+
continue;
|
|
172
|
+
if (root.count === 0) {
|
|
173
|
+
deadRanges.push([root.startOffset, root.endOffset]); // whole body dead
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
for (let i = 1; i < ranges.length; i++) {
|
|
177
|
+
const r = ranges[i];
|
|
178
|
+
if (r.count === 0 && typeof r.startOffset === "number" && typeof r.endOffset === "number") {
|
|
179
|
+
deadRanges.push([r.startOffset, r.endOffset]);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return deadRanges;
|
|
184
|
+
}
|
|
185
|
+
/** Merge overlapping (sorted-by-start) ranges into a minimal disjoint set. */
|
|
186
|
+
function mergeRanges(ranges) {
|
|
187
|
+
const sorted = [...ranges].sort((a, b) => a[0] - b[0]);
|
|
188
|
+
const merged = [];
|
|
189
|
+
let dStart = -1;
|
|
190
|
+
let dEnd = -1;
|
|
191
|
+
for (const [s, e] of sorted) {
|
|
192
|
+
if (s > dEnd) {
|
|
193
|
+
if (dEnd > dStart)
|
|
194
|
+
merged.push([dStart, dEnd]);
|
|
195
|
+
dStart = s;
|
|
196
|
+
dEnd = e;
|
|
197
|
+
}
|
|
198
|
+
else if (e > dEnd) {
|
|
199
|
+
dEnd = e;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (dEnd > dStart)
|
|
203
|
+
merged.push([dStart, dEnd]);
|
|
204
|
+
return merged;
|
|
205
|
+
}
|
|
206
|
+
function parseScriptCoverage(s) {
|
|
207
|
+
const url = typeof s.url === "string" ? s.url : "";
|
|
208
|
+
if (!url)
|
|
209
|
+
return null;
|
|
210
|
+
const total = scriptTotalSpan(s);
|
|
211
|
+
const mergedDead = mergeRanges(collectDeadRanges(s));
|
|
212
|
+
const deadBytes = mergedDead.reduce((sum, [s3, e3]) => sum + (e3 - s3), 0);
|
|
213
|
+
const used = Math.max(0, total - deadBytes);
|
|
214
|
+
const usagePercent = total === 0 ? 100 : Math.round((used / total) * 10000) / 100;
|
|
215
|
+
const dead = mergedDead
|
|
216
|
+
.slice(0, MAX_DEAD_RANGES_PER_SCRIPT)
|
|
217
|
+
.map(([s5, e5]) => ({ start: s5, end: e5 }));
|
|
218
|
+
const entry = { url, totalBytes: total, usedBytes: used, usagePercent };
|
|
219
|
+
if (dead.length > 0)
|
|
220
|
+
entry.deadRanges = dead;
|
|
221
|
+
return entry;
|
|
222
|
+
}
|
|
223
|
+
export function parseJsCoverage(scripts) {
|
|
224
|
+
const out = [];
|
|
225
|
+
for (const s of scripts) {
|
|
226
|
+
const entry = parseScriptCoverage(s);
|
|
227
|
+
if (entry)
|
|
228
|
+
out.push(entry);
|
|
229
|
+
}
|
|
230
|
+
return out;
|
|
231
|
+
}
|
|
232
|
+
/** Parse `CSS.stopRuleUsageTracking` output into per-stylesheet entries.
|
|
233
|
+
* Exported for unit tests against synthetic CDP payloads. */
|
|
234
|
+
export function parseCssCoverage(ruleUsage, headers) {
|
|
235
|
+
// Group by styleSheetId. Each entry: url + total span + used+dead ranges.
|
|
236
|
+
const byId = new Map();
|
|
237
|
+
for (const r of ruleUsage) {
|
|
238
|
+
const id = r.styleSheetId;
|
|
239
|
+
if (!id)
|
|
240
|
+
continue;
|
|
241
|
+
let g = byId.get(id);
|
|
242
|
+
if (!g) {
|
|
243
|
+
g = { used: [], dead: [], maxEnd: 0 };
|
|
244
|
+
byId.set(id, g);
|
|
245
|
+
}
|
|
246
|
+
if (r.endOffset > g.maxEnd)
|
|
247
|
+
g.maxEnd = r.endOffset;
|
|
248
|
+
if (r.used)
|
|
249
|
+
g.used.push([r.startOffset, r.endOffset]);
|
|
250
|
+
else
|
|
251
|
+
g.dead.push([r.startOffset, r.endOffset]);
|
|
252
|
+
}
|
|
253
|
+
const out = [];
|
|
254
|
+
for (const [id, g] of byId) {
|
|
255
|
+
const hdr = headers.get(id);
|
|
256
|
+
// Prefer the explicit header length when available; CDP sometimes
|
|
257
|
+
// reports 0 for inline stylesheets without sourceURL — fall back to
|
|
258
|
+
// the maxEnd observation from the rule-usage stream.
|
|
259
|
+
const total = hdr?.length && hdr.length > 0 ? hdr.length : g.maxEnd;
|
|
260
|
+
let usedBytes = 0;
|
|
261
|
+
for (const [s, e] of g.used)
|
|
262
|
+
usedBytes += Math.max(0, e - s);
|
|
263
|
+
const usagePercent = total === 0 ? 100 : Math.round((usedBytes / total) * 10000) / 100;
|
|
264
|
+
const entry = {
|
|
265
|
+
url: hdr?.sourceURL || `inline:${id}`,
|
|
266
|
+
totalBytes: total,
|
|
267
|
+
usedBytes,
|
|
268
|
+
usedRules: g.used.length,
|
|
269
|
+
totalRules: g.used.length + g.dead.length,
|
|
270
|
+
usagePercent,
|
|
271
|
+
};
|
|
272
|
+
if (g.dead.length > 0) {
|
|
273
|
+
entry.deadRules = g.dead
|
|
274
|
+
.slice(0, MAX_DEAD_RANGES_PER_SCRIPT)
|
|
275
|
+
.map(([s, e]) => ({ start: s, end: e }));
|
|
276
|
+
}
|
|
277
|
+
out.push(entry);
|
|
278
|
+
}
|
|
279
|
+
return out;
|
|
280
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export type DomExportFormat = "html" | "jsonl";
|
|
2
|
+
export interface DomExportArgs {
|
|
3
|
+
/** Output format. Default `"html"`. */
|
|
4
|
+
format?: DomExportFormat;
|
|
5
|
+
/** Walk open shadow roots when serialising. Default `true`. Closed
|
|
6
|
+
* shadow roots are inaccessible (web-platform constraint). */
|
|
7
|
+
includeShadow?: boolean;
|
|
8
|
+
/** Workspace-rooted output path. Default
|
|
9
|
+
* `dom-dumps/<sessionId>-<ISO>.{html|jsonl}`. Rejected if it escapes
|
|
10
|
+
* $BROWX_WORKSPACE. */
|
|
11
|
+
path?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface DomExportResult {
|
|
14
|
+
ok: true;
|
|
15
|
+
format: DomExportFormat;
|
|
16
|
+
/** Absolute, workspace-rooted output path. */
|
|
17
|
+
path: string;
|
|
18
|
+
/** Size on disk, in bytes. */
|
|
19
|
+
sizeBytes: number;
|
|
20
|
+
/** Total DOM nodes walked. For `html` mode, derived from a single
|
|
21
|
+
* page-side count; for `jsonl` mode, the line count. */
|
|
22
|
+
nodeCount: number;
|
|
23
|
+
/** Count of open shadow roots descended into during the walk. Zero
|
|
24
|
+
* for `html` mode (shadow content is inaccessible to `outerHTML` —
|
|
25
|
+
* see the warning). */
|
|
26
|
+
shadowRootCount: number;
|
|
27
|
+
/** Non-fatal advisories. Always carries the secrets-masking caveat;
|
|
28
|
+
* also surfaces the closed-shadow + outerHTML-loses-shadow gaps. */
|
|
29
|
+
warnings: string[];
|
|
30
|
+
}
|
|
31
|
+
/** Workspace-relative default — namespaced under `dom-dumps/`. */
|
|
32
|
+
export declare function defaultDomExportPath(sessionId: string, format: DomExportFormat): string;
|
|
33
|
+
/** Thin adapter — `Page.evaluate(fn, args)`. Keeps the unit tests
|
|
34
|
+
* trivial: a stub that returns whatever `PageWalkResult` it was
|
|
35
|
+
* programmed with. `evaluate` takes a real function (Playwright
|
|
36
|
+
* serializes it + invokes in-page with arg) — passing a stringified
|
|
37
|
+
* arrow expression returns the function value uncalled. */
|
|
38
|
+
export interface DomExportPage {
|
|
39
|
+
evaluate<T, Arg>(fn: (arg: Arg) => T | Promise<T>, args?: Arg): Promise<T>;
|
|
40
|
+
}
|
|
41
|
+
export declare function domExport(page: DomExportPage, workspaceRoot: string, sessionId: string, args?: DomExportArgs): Promise<DomExportResult>;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/// <reference lib="dom" />
|
|
2
|
+
// `dom_export` — full DOM dump.
|
|
3
|
+
//
|
|
4
|
+
// Two formats:
|
|
5
|
+
//
|
|
6
|
+
// - `html` (default) — `document.documentElement.outerHTML` written
|
|
7
|
+
// verbatim to a workspace-rooted `.html` file. The agent has already
|
|
8
|
+
// stabilized the page (`navigate` + any settle) — the tool does NOT
|
|
9
|
+
// inject its own wait, same posture as `page_archive`.
|
|
10
|
+
//
|
|
11
|
+
// - `jsonl` — one JSON object per line, depth-first walk:
|
|
12
|
+
// `{tag, role?, attrs, text?, ref?, depth}`
|
|
13
|
+
// A grep-friendly serialization for the cases where the agent needs
|
|
14
|
+
// to scan structure without parsing HTML. `attrs` is a flat
|
|
15
|
+
// attribute-name → value map; `text` is set only for nodes whose
|
|
16
|
+
// direct text content is non-empty (whitespace-trimmed); `ref` echoes
|
|
17
|
+
// the stable `eN` ref when the node was discovered as part of a prior
|
|
18
|
+
// `snapshot()` / `find()` (otherwise omitted — refs aren't minted
|
|
19
|
+
// during the dump itself).
|
|
20
|
+
//
|
|
21
|
+
// Shadow-DOM traversal (default ON, `includeShadow:true`):
|
|
22
|
+
// The walker descends into every open shadow root (`Element.shadowRoot`
|
|
23
|
+
// when not null). Closed shadow roots are inaccessible by web-platform
|
|
24
|
+
// design — `shadowRoot` returns null and the tree behind them is
|
|
25
|
+
// genuinely unreachable. The result envelope surfaces the limitation
|
|
26
|
+
// via `warnings[]` when the document is detected to have HTML content
|
|
27
|
+
// that hints at custom elements (best-effort heuristic).
|
|
28
|
+
//
|
|
29
|
+
// Secrets-masking interplay (DELIBERATE GAP):
|
|
30
|
+
// Same gap as `page_archive` / `element_export`. The dump is faithful;
|
|
31
|
+
// running egress masking over it would corrupt inline JSON state blobs.
|
|
32
|
+
// The `warnings[]` array always carries the caveat as its first entry.
|
|
33
|
+
import { resolve as resolvePath, dirname } from "node:path";
|
|
34
|
+
import { mkdirSync, writeFileSync, statSync } from "node:fs";
|
|
35
|
+
import { resolveWorkspacePath } from "../session/storage.js";
|
|
36
|
+
/** Workspace-relative default — namespaced under `dom-dumps/`. */
|
|
37
|
+
export function defaultDomExportPath(sessionId, format) {
|
|
38
|
+
const safe = sessionId.replace(/[^A-Za-z0-9._-]/g, "_") || "default";
|
|
39
|
+
const ts = new Date().toISOString().replace(/[:.]/g, "-");
|
|
40
|
+
const ext = format === "jsonl" ? ".jsonl" : ".html";
|
|
41
|
+
return `dom-dumps/${safe}-${ts}${ext}`;
|
|
42
|
+
}
|
|
43
|
+
/** Page-side walk function — returns either a single string (html mode)
|
|
44
|
+
* or an array of JSONL-ready objects (jsonl mode). One round-trip per
|
|
45
|
+
* invocation; the dump is bounded by the page's DOM size, no per-node
|
|
46
|
+
* evaluate.
|
|
47
|
+
*
|
|
48
|
+
* Passed as a real function literal (NOT a stringified expression) so
|
|
49
|
+
* Playwright's `Page.evaluate(fn, arg)` path serializes the source and
|
|
50
|
+
* invokes in-page with the arg — a stringified `(args) => {...}` would
|
|
51
|
+
* evaluate to the function value uncalled, which CDP can't serialize. */
|
|
52
|
+
const PAGE_WALK_FN = (args) => {
|
|
53
|
+
const mode = args.mode;
|
|
54
|
+
const includeShadow = args.includeShadow;
|
|
55
|
+
let hasCustomElements = false;
|
|
56
|
+
try {
|
|
57
|
+
const all = document.querySelectorAll("*");
|
|
58
|
+
for (let i = 0; i < all.length && i < 500; i++) {
|
|
59
|
+
if (all[i].tagName && all[i].tagName.indexOf("-") !== -1) {
|
|
60
|
+
hasCustomElements = true;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// best-effort: querySelectorAll can throw on hostile/torn-down documents
|
|
67
|
+
}
|
|
68
|
+
if (mode === "html") {
|
|
69
|
+
const html = document.documentElement ? document.documentElement.outerHTML : "";
|
|
70
|
+
let count = 0;
|
|
71
|
+
try {
|
|
72
|
+
count = document.querySelectorAll("*").length;
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// best-effort: leave count=0 if querySelectorAll throws
|
|
76
|
+
}
|
|
77
|
+
return { html, nodeCount: count, shadowRootCount: 0, hasCustomElements };
|
|
78
|
+
}
|
|
79
|
+
const nodes = [];
|
|
80
|
+
let shadowRoots = 0;
|
|
81
|
+
function attrsOf(el) {
|
|
82
|
+
const a = {};
|
|
83
|
+
const atts = el.attributes;
|
|
84
|
+
if (!atts)
|
|
85
|
+
return a;
|
|
86
|
+
for (let i = 0; i < atts.length; i++) {
|
|
87
|
+
a[atts[i].name] = atts[i].value;
|
|
88
|
+
}
|
|
89
|
+
return a;
|
|
90
|
+
}
|
|
91
|
+
function directText(el) {
|
|
92
|
+
let t = "";
|
|
93
|
+
const kids = el.childNodes;
|
|
94
|
+
for (let i = 0; i < kids.length; i++) {
|
|
95
|
+
if (kids[i].nodeType === 3)
|
|
96
|
+
t += kids[i].nodeValue || "";
|
|
97
|
+
}
|
|
98
|
+
return t.replace(/\s+/g, " ").trim();
|
|
99
|
+
}
|
|
100
|
+
function visit(node, depth) {
|
|
101
|
+
if (!node || node.nodeType !== 1)
|
|
102
|
+
return;
|
|
103
|
+
const entry = {
|
|
104
|
+
tag: (node.tagName || "").toLowerCase(),
|
|
105
|
+
attrs: attrsOf(node),
|
|
106
|
+
depth,
|
|
107
|
+
};
|
|
108
|
+
const role = node.getAttribute("role");
|
|
109
|
+
if (role)
|
|
110
|
+
entry.role = role;
|
|
111
|
+
const txt = directText(node);
|
|
112
|
+
if (txt)
|
|
113
|
+
entry.text = txt;
|
|
114
|
+
const refAttr = node.getAttribute("data-browx-ref") || "";
|
|
115
|
+
if (refAttr)
|
|
116
|
+
entry.ref = refAttr;
|
|
117
|
+
nodes.push(entry);
|
|
118
|
+
if (includeShadow && node.shadowRoot) {
|
|
119
|
+
shadowRoots++;
|
|
120
|
+
const sKids = node.shadowRoot.children;
|
|
121
|
+
for (let j = 0; j < sKids.length; j++)
|
|
122
|
+
visit(sKids[j], depth + 1);
|
|
123
|
+
}
|
|
124
|
+
const kids = node.children;
|
|
125
|
+
for (let k = 0; k < kids.length; k++)
|
|
126
|
+
visit(kids[k], depth + 1);
|
|
127
|
+
}
|
|
128
|
+
if (document.documentElement)
|
|
129
|
+
visit(document.documentElement, 0);
|
|
130
|
+
return {
|
|
131
|
+
nodes,
|
|
132
|
+
nodeCount: nodes.length,
|
|
133
|
+
shadowRootCount: shadowRoots,
|
|
134
|
+
hasCustomElements,
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
export async function domExport(page, workspaceRoot, sessionId, args = {}) {
|
|
138
|
+
const format = args.format ?? "html";
|
|
139
|
+
const includeShadow = args.includeShadow ?? true;
|
|
140
|
+
const relPath = args.path ?? defaultDomExportPath(sessionId, format);
|
|
141
|
+
const resolved = resolveWorkspacePath(workspaceRoot, relPath, "dom_export");
|
|
142
|
+
const walked = await page.evaluate(PAGE_WALK_FN, {
|
|
143
|
+
mode: format,
|
|
144
|
+
includeShadow,
|
|
145
|
+
});
|
|
146
|
+
const warnings = [
|
|
147
|
+
"dom_export output is UNMASKED — secrets-masking would corrupt the dump (literal-substring substitution breaks inline JSON / CSS / binary bytes). Treat the dump as sensitive material, same posture as page_archive / dump_storage_state.",
|
|
148
|
+
];
|
|
149
|
+
// Workspace-rooted by construction — `resolved` ⊆ BROWX_WORKSPACE.
|
|
150
|
+
mkdirSync(dirname(resolved), { recursive: true });
|
|
151
|
+
let sizeBytes = 0;
|
|
152
|
+
let nodeCount = walked.nodeCount;
|
|
153
|
+
const shadowRootCount = walked.shadowRootCount;
|
|
154
|
+
if (format === "html") {
|
|
155
|
+
const html = walked.html ?? "";
|
|
156
|
+
// workspace-rooted: resolved ⊆ BROWX_WORKSPACE (resolveWorkspacePath above).
|
|
157
|
+
writeFileSync(resolved, html, "utf8");
|
|
158
|
+
sizeBytes = statSync(resolved).size;
|
|
159
|
+
// `outerHTML` does not serialise shadow-DOM content (open OR closed),
|
|
160
|
+
// even though open shadow roots are programmatically reachable. The
|
|
161
|
+
// gap is intrinsic to the platform serializer; surface it so the
|
|
162
|
+
// adopter doesn't wonder where the Web Component's interior went.
|
|
163
|
+
if (walked.hasCustomElements || includeShadow) {
|
|
164
|
+
warnings.push("html mode: `documentElement.outerHTML` does NOT include shadow-DOM content (open OR closed) — " +
|
|
165
|
+
'the platform serializer omits shadow trees. For shadow content, use `format:"jsonl"` with `includeShadow:true` (default).');
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
// jsonl — one JSON object per line.
|
|
170
|
+
const lines = [];
|
|
171
|
+
for (const n of walked.nodes ?? []) {
|
|
172
|
+
lines.push(JSON.stringify(n));
|
|
173
|
+
}
|
|
174
|
+
const body = lines.join("\n") + (lines.length > 0 ? "\n" : "");
|
|
175
|
+
// workspace-rooted: resolved ⊆ BROWX_WORKSPACE (resolveWorkspacePath above).
|
|
176
|
+
writeFileSync(resolved, body, "utf8");
|
|
177
|
+
sizeBytes = statSync(resolved).size;
|
|
178
|
+
nodeCount = lines.length;
|
|
179
|
+
}
|
|
180
|
+
if (walked.hasCustomElements) {
|
|
181
|
+
warnings.push("Document uses custom elements. Closed shadow roots are inaccessible by web-platform design — " +
|
|
182
|
+
"any tree behind a closed root is genuinely unreachable from this dump.");
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
ok: true,
|
|
186
|
+
format,
|
|
187
|
+
path: resolvePath(resolved),
|
|
188
|
+
sizeBytes,
|
|
189
|
+
nodeCount,
|
|
190
|
+
shadowRootCount,
|
|
191
|
+
warnings,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { CDPSession, Frame } from "playwright-core";
|
|
2
|
+
import { RefRegistry } from "./refs.js";
|
|
3
|
+
import type { A11yNode } from "./a11y.js";
|
|
4
|
+
export interface DomWalkEntry {
|
|
5
|
+
role: string;
|
|
6
|
+
name: string;
|
|
7
|
+
testId: string;
|
|
8
|
+
testIdAttr: string;
|
|
9
|
+
tag: string;
|
|
10
|
+
id: string;
|
|
11
|
+
structuralPath: string;
|
|
12
|
+
/** Valid CSS selector built from the `:nth-child` chain at walk time.
|
|
13
|
+
* Used as the locator for refs whose role is a bare tag (`td`, `div`,
|
|
14
|
+
* generic) where `getByRole` would be ambiguous or wrong. */
|
|
15
|
+
cssPath: string;
|
|
16
|
+
}
|
|
17
|
+
export interface DomWalkOptions {
|
|
18
|
+
/** Attributes treated as "test ids" (tier-1 selectorHint candidates). */
|
|
19
|
+
testAttributes?: string[];
|
|
20
|
+
/** Hard cap on returned entries (sanity bound; the JS side already caps). */
|
|
21
|
+
maxEntries?: number;
|
|
22
|
+
/** shadow DOM piercing.
|
|
23
|
+
* - `"open"` (the implicit default — preserves pre-v0.5.0 behaviour;
|
|
24
|
+
* the page-side walk recurses into every `Element.shadowRoot` it sees,
|
|
25
|
+
* same as `querySelectorAll` semantics on open roots).
|
|
26
|
+
* - `"closed"` — additionally invokes the CDP `DOM.getDocument(
|
|
27
|
+
* {pierce:true})` path and harvests interactive / test-attr-bearing
|
|
28
|
+
* elements that live inside closed shadow roots. Best-effort; falls
|
|
29
|
+
* back to open-only when CDP refuses pierce.
|
|
30
|
+
* - `false` — no shadow recursion. Equivalent to walking only the top
|
|
31
|
+
* document's children.
|
|
32
|
+
*/
|
|
33
|
+
pierce?: "open" | "closed" | false;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Run the in-page DOM-walk and return the discovered entries.
|
|
37
|
+
*
|
|
38
|
+
* Notes:
|
|
39
|
+
* - The script runs in page context — keep it ECMAScript-only (no TS).
|
|
40
|
+
* - Stringified function so we can pass it through `Runtime.evaluate` with
|
|
41
|
+
* `returnByValue: true`.
|
|
42
|
+
* - Visibility is checked at walk time (`getBoundingClientRect` non-zero + computed
|
|
43
|
+
* `visibility !== hidden` + `display !== none`). This intentionally skips offscreen
|
|
44
|
+
* elements (they wouldn't be clickable from the agent's POV right now).
|
|
45
|
+
*/
|
|
46
|
+
export declare function runDomWalk(cdp: CDPSession, opts?: DomWalkOptions): Promise<DomWalkEntry[]>;
|
|
47
|
+
/**
|
|
48
|
+
* Frame-scoped DOM walk. Same `PAGE_SCRIPT`, but evaluated inside
|
|
49
|
+
* a Playwright `Frame` via `frame.evaluate(...)` instead of the top-level
|
|
50
|
+
* CDP `Runtime.evaluate`. Works transparently for both same-origin and
|
|
51
|
+
* cross-origin (OOPIF) child frames — Playwright's frame API spans both.
|
|
52
|
+
*
|
|
53
|
+
* Honours `pierce` the same way the top-level walk does: `"open"` / `"closed"`
|
|
54
|
+
* recurses into reachable open shadow roots inside the frame; `false` /
|
|
55
|
+
* undefined sticks to the frame's top document. Closed-shadow CDP harvesting
|
|
56
|
+
* is not run for child frames (the CDP path is rooted at the top target).
|
|
57
|
+
*/
|
|
58
|
+
export declare function runDomWalkOnFrame(frame: Frame, opts?: DomWalkOptions): Promise<DomWalkEntry[]>;
|
|
59
|
+
/**
|
|
60
|
+
* Transport-agnostic DOM walk. Runs the SAME `PAGE_SCRIPT` via an injected
|
|
61
|
+
* `exec` that takes a function BODY + an args array and returns the value —
|
|
62
|
+
* exactly the WebDriver-Classic `execute/sync` shape (`{script, args}`). This is
|
|
63
|
+
* the seam the Safari snapshot substrate uses: Safari has neither
|
|
64
|
+
* CDP nor a Playwright Frame, but `safaridriver`'s `execute/sync` runs the script
|
|
65
|
+
* identically (the returned `DomWalkEntry` shape matches
|
|
66
|
+
* `frame.evaluate` byte-for-byte).
|
|
67
|
+
* `PAGE_SCRIPT` stays encapsulated here; callers pass only the transport.
|
|
68
|
+
*/
|
|
69
|
+
export declare function runDomWalkViaExecute(exec: (scriptBody: string, args: unknown[]) => Promise<unknown>, opts?: DomWalkOptions): Promise<DomWalkEntry[]>;
|
|
70
|
+
/**
|
|
71
|
+
* Convert DOM-walk entries to A11yNode leaves and add them as children of `root`,
|
|
72
|
+
* minting refs through the same `RefRegistry` so the IDs are stable across snapshots
|
|
73
|
+
* (and round-trip with the a11y nodes' refs when both paths see the same element).
|
|
74
|
+
*
|
|
75
|
+
* Returns the count of *new* nodes added (i.e. nodes whose stable key wasn't already
|
|
76
|
+
* present in the registry) so the caller can emit a low-content warning.
|
|
77
|
+
*/
|
|
78
|
+
export interface MergeOptions {
|
|
79
|
+
/** when set, refs minted here are namespaced to this frame
|
|
80
|
+
* (via `elementKey`'s `frameId`) so two iframes with identical markup
|
|
81
|
+
* don't collide on the same ref. */
|
|
82
|
+
frameId?: string;
|
|
83
|
+
/** when set, refs minted here are bound to this Frame on the
|
|
84
|
+
* registry so action-time `locatorFor` routes through `frame.locator(...)`
|
|
85
|
+
* instead of `page.locator(...)`. */
|
|
86
|
+
frame?: Frame;
|
|
87
|
+
}
|
|
88
|
+
export declare function mergeDomWalkIntoTree(root: A11yNode, entries: DomWalkEntry[], refs: RefRegistry, opts?: MergeOptions): {
|
|
89
|
+
added: number;
|
|
90
|
+
combined: number;
|
|
91
|
+
};
|