prose-qa 0.1.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 +570 -0
- package/dist/agent/bash.d.ts +52 -0
- package/dist/agent/bash.d.ts.map +1 -0
- package/dist/agent/bash.js +186 -0
- package/dist/agent/bash.js.map +1 -0
- package/dist/agent/bash.test.d.ts +2 -0
- package/dist/agent/bash.test.d.ts.map +1 -0
- package/dist/agent/bash.test.js +70 -0
- package/dist/agent/bash.test.js.map +1 -0
- package/dist/agent/llm-model.d.ts +5 -0
- package/dist/agent/llm-model.d.ts.map +1 -0
- package/dist/agent/llm-model.js +29 -0
- package/dist/agent/llm-model.js.map +1 -0
- package/dist/agent/llm-model.test.d.ts +2 -0
- package/dist/agent/llm-model.test.d.ts.map +1 -0
- package/dist/agent/llm-model.test.js +28 -0
- package/dist/agent/llm-model.test.js.map +1 -0
- package/dist/agent/prompt.d.ts +17 -0
- package/dist/agent/prompt.d.ts.map +1 -0
- package/dist/agent/prompt.js +97 -0
- package/dist/agent/prompt.js.map +1 -0
- package/dist/agent/prompt.test.d.ts +2 -0
- package/dist/agent/prompt.test.d.ts.map +1 -0
- package/dist/agent/prompt.test.js +124 -0
- package/dist/agent/prompt.test.js.map +1 -0
- package/dist/agent/provider-options.d.ts +8 -0
- package/dist/agent/provider-options.d.ts.map +1 -0
- package/dist/agent/provider-options.js +115 -0
- package/dist/agent/provider-options.js.map +1 -0
- package/dist/agent/provider-options.test.d.ts +2 -0
- package/dist/agent/provider-options.test.d.ts.map +1 -0
- package/dist/agent/provider-options.test.js +114 -0
- package/dist/agent/provider-options.test.js.map +1 -0
- package/dist/agent/runner.d.ts +27 -0
- package/dist/agent/runner.d.ts.map +1 -0
- package/dist/agent/runner.js +291 -0
- package/dist/agent/runner.js.map +1 -0
- package/dist/agent/verdict-retry-prompt.d.ts +3 -0
- package/dist/agent/verdict-retry-prompt.d.ts.map +1 -0
- package/dist/agent/verdict-retry-prompt.js +18 -0
- package/dist/agent/verdict-retry-prompt.js.map +1 -0
- package/dist/agent/verdict-retry-prompt.test.d.ts +2 -0
- package/dist/agent/verdict-retry-prompt.test.d.ts.map +1 -0
- package/dist/agent/verdict-retry-prompt.test.js +25 -0
- package/dist/agent/verdict-retry-prompt.test.js.map +1 -0
- package/dist/agent/verdict.d.ts +31 -0
- package/dist/agent/verdict.d.ts.map +1 -0
- package/dist/agent/verdict.js +123 -0
- package/dist/agent/verdict.js.map +1 -0
- package/dist/agent/verdict.test.d.ts +2 -0
- package/dist/agent/verdict.test.d.ts.map +1 -0
- package/dist/agent/verdict.test.js +156 -0
- package/dist/agent/verdict.test.js.map +1 -0
- package/dist/analyze/build-context.d.ts +58 -0
- package/dist/analyze/build-context.d.ts.map +1 -0
- package/dist/analyze/build-context.js +141 -0
- package/dist/analyze/build-context.js.map +1 -0
- package/dist/analyze/build-context.test.d.ts +2 -0
- package/dist/analyze/build-context.test.d.ts.map +1 -0
- package/dist/analyze/build-context.test.js +118 -0
- package/dist/analyze/build-context.test.js.map +1 -0
- package/dist/analyze/compare-runs.d.ts +49 -0
- package/dist/analyze/compare-runs.d.ts.map +1 -0
- package/dist/analyze/compare-runs.js +214 -0
- package/dist/analyze/compare-runs.js.map +1 -0
- package/dist/analyze/compare-runs.test.d.ts +2 -0
- package/dist/analyze/compare-runs.test.d.ts.map +1 -0
- package/dist/analyze/compare-runs.test.js +139 -0
- package/dist/analyze/compare-runs.test.js.map +1 -0
- package/dist/analyze/diff-hunks.d.ts +16 -0
- package/dist/analyze/diff-hunks.d.ts.map +1 -0
- package/dist/analyze/diff-hunks.js +287 -0
- package/dist/analyze/diff-hunks.js.map +1 -0
- package/dist/analyze/diff-hunks.test.d.ts +2 -0
- package/dist/analyze/diff-hunks.test.d.ts.map +1 -0
- package/dist/analyze/diff-hunks.test.js +54 -0
- package/dist/analyze/diff-hunks.test.js.map +1 -0
- package/dist/analyze/hunk-editor.d.ts +8 -0
- package/dist/analyze/hunk-editor.d.ts.map +1 -0
- package/dist/analyze/hunk-editor.js +129 -0
- package/dist/analyze/hunk-editor.js.map +1 -0
- package/dist/analyze/hunk-editor.test.d.ts +2 -0
- package/dist/analyze/hunk-editor.test.d.ts.map +1 -0
- package/dist/analyze/hunk-editor.test.js +48 -0
- package/dist/analyze/hunk-editor.test.js.map +1 -0
- package/dist/analyze/index.d.ts +23 -0
- package/dist/analyze/index.d.ts.map +1 -0
- package/dist/analyze/index.js +122 -0
- package/dist/analyze/index.js.map +1 -0
- package/dist/analyze/llm-fix.d.ts +11 -0
- package/dist/analyze/llm-fix.d.ts.map +1 -0
- package/dist/analyze/llm-fix.js +76 -0
- package/dist/analyze/llm-fix.js.map +1 -0
- package/dist/analyze/parse-proposal.d.ts +41 -0
- package/dist/analyze/parse-proposal.d.ts.map +1 -0
- package/dist/analyze/parse-proposal.js +53 -0
- package/dist/analyze/parse-proposal.js.map +1 -0
- package/dist/analyze/parse-proposal.test.d.ts +2 -0
- package/dist/analyze/parse-proposal.test.d.ts.map +1 -0
- package/dist/analyze/parse-proposal.test.js +40 -0
- package/dist/analyze/parse-proposal.test.js.map +1 -0
- package/dist/analyze/repl.d.ts +28 -0
- package/dist/analyze/repl.d.ts.map +1 -0
- package/dist/analyze/repl.js +284 -0
- package/dist/analyze/repl.js.map +1 -0
- package/dist/analyze/repl.test.d.ts +2 -0
- package/dist/analyze/repl.test.d.ts.map +1 -0
- package/dist/analyze/repl.test.js +101 -0
- package/dist/analyze/repl.test.js.map +1 -0
- package/dist/analyze/suggest.d.ts +5 -0
- package/dist/analyze/suggest.d.ts.map +1 -0
- package/dist/analyze/suggest.js +75 -0
- package/dist/analyze/suggest.js.map +1 -0
- package/dist/analyze/suggest.test.d.ts +2 -0
- package/dist/analyze/suggest.test.d.ts.map +1 -0
- package/dist/analyze/suggest.test.js +53 -0
- package/dist/analyze/suggest.test.js.map +1 -0
- package/dist/analyze/validate-markdown.d.ts +3 -0
- package/dist/analyze/validate-markdown.d.ts.map +1 -0
- package/dist/analyze/validate-markdown.js +25 -0
- package/dist/analyze/validate-markdown.js.map +1 -0
- package/dist/artifacts/policy.d.ts +9 -0
- package/dist/artifacts/policy.d.ts.map +1 -0
- package/dist/artifacts/policy.js +46 -0
- package/dist/artifacts/policy.js.map +1 -0
- package/dist/artifacts/policy.test.d.ts +2 -0
- package/dist/artifacts/policy.test.d.ts.map +1 -0
- package/dist/artifacts/policy.test.js +73 -0
- package/dist/artifacts/policy.test.js.map +1 -0
- package/dist/auth/resolve.d.ts +22 -0
- package/dist/auth/resolve.d.ts.map +1 -0
- package/dist/auth/resolve.js +148 -0
- package/dist/auth/resolve.js.map +1 -0
- package/dist/auth/store.d.ts +23 -0
- package/dist/auth/store.d.ts.map +1 -0
- package/dist/auth/store.js +103 -0
- package/dist/auth/store.js.map +1 -0
- package/dist/cache/generate.d.ts +8 -0
- package/dist/cache/generate.d.ts.map +1 -0
- package/dist/cache/generate.js +61 -0
- package/dist/cache/generate.js.map +1 -0
- package/dist/cache/hash.d.ts +5 -0
- package/dist/cache/hash.d.ts.map +1 -0
- package/dist/cache/hash.js +21 -0
- package/dist/cache/hash.js.map +1 -0
- package/dist/cache/hash.test.d.ts +2 -0
- package/dist/cache/hash.test.d.ts.map +1 -0
- package/dist/cache/hash.test.js +42 -0
- package/dist/cache/hash.test.js.map +1 -0
- package/dist/cache/resolve.d.ts +5 -0
- package/dist/cache/resolve.d.ts.map +1 -0
- package/dist/cache/resolve.js +8 -0
- package/dist/cache/resolve.js.map +1 -0
- package/dist/cache/store.d.ts +20 -0
- package/dist/cache/store.d.ts.map +1 -0
- package/dist/cache/store.js +90 -0
- package/dist/cache/store.js.map +1 -0
- package/dist/cache/store.test.d.ts +2 -0
- package/dist/cache/store.test.d.ts.map +1 -0
- package/dist/cache/store.test.js +101 -0
- package/dist/cache/store.test.js.map +1 -0
- package/dist/cli/analyze.d.ts +21 -0
- package/dist/cli/analyze.d.ts.map +1 -0
- package/dist/cli/analyze.js +148 -0
- package/dist/cli/analyze.js.map +1 -0
- package/dist/cli/concurrency.d.ts +17 -0
- package/dist/cli/concurrency.d.ts.map +1 -0
- package/dist/cli/concurrency.js +56 -0
- package/dist/cli/concurrency.js.map +1 -0
- package/dist/cli/concurrency.test.d.ts +2 -0
- package/dist/cli/concurrency.test.d.ts.map +1 -0
- package/dist/cli/concurrency.test.js +74 -0
- package/dist/cli/concurrency.test.js.map +1 -0
- package/dist/cli/config.d.ts +2 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +14 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/help.d.ts +23 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +458 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/help.test.d.ts +2 -0
- package/dist/cli/help.test.d.ts.map +1 -0
- package/dist/cli/help.test.js +41 -0
- package/dist/cli/help.test.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +300 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/mcp.d.ts +6 -0
- package/dist/cli/mcp.d.ts.map +1 -0
- package/dist/cli/mcp.js +17 -0
- package/dist/cli/mcp.js.map +1 -0
- package/dist/cli/record.d.ts +27 -0
- package/dist/cli/record.d.ts.map +1 -0
- package/dist/cli/record.js +244 -0
- package/dist/cli/record.js.map +1 -0
- package/dist/cli/run.d.ts +11 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +676 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/subprocess.d.ts +19 -0
- package/dist/cli/subprocess.d.ts.map +1 -0
- package/dist/cli/subprocess.js +142 -0
- package/dist/cli/subprocess.js.map +1 -0
- package/dist/cli/subprocess.test.d.ts +2 -0
- package/dist/cli/subprocess.test.d.ts.map +1 -0
- package/dist/cli/subprocess.test.js +76 -0
- package/dist/cli/subprocess.test.js.map +1 -0
- package/dist/cli/tags.d.ts +5 -0
- package/dist/cli/tags.d.ts.map +1 -0
- package/dist/cli/tags.js +33 -0
- package/dist/cli/tags.js.map +1 -0
- package/dist/cli/tags.test.d.ts +2 -0
- package/dist/cli/tags.test.d.ts.map +1 -0
- package/dist/cli/tags.test.js +31 -0
- package/dist/cli/tags.test.js.map +1 -0
- package/dist/config/env-vars.d.ts +2 -0
- package/dist/config/env-vars.d.ts.map +1 -0
- package/dist/config/env-vars.js +14 -0
- package/dist/config/env-vars.js.map +1 -0
- package/dist/config/env.d.ts +2 -0
- package/dist/config/env.d.ts.map +1 -0
- package/dist/config/env.js +9 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/lightpanda.d.ts +6 -0
- package/dist/config/lightpanda.d.ts.map +1 -0
- package/dist/config/lightpanda.js +38 -0
- package/dist/config/lightpanda.js.map +1 -0
- package/dist/config/lightpanda.test.d.ts +2 -0
- package/dist/config/lightpanda.test.d.ts.map +1 -0
- package/dist/config/lightpanda.test.js +46 -0
- package/dist/config/lightpanda.test.js.map +1 -0
- package/dist/config/load.d.ts +22 -0
- package/dist/config/load.d.ts.map +1 -0
- package/dist/config/load.js +242 -0
- package/dist/config/load.js.map +1 -0
- package/dist/config/load.test.d.ts +2 -0
- package/dist/config/load.test.d.ts.map +1 -0
- package/dist/config/load.test.js +86 -0
- package/dist/config/load.test.js.map +1 -0
- package/dist/config/set.d.ts +8 -0
- package/dist/config/set.d.ts.map +1 -0
- package/dist/config/set.js +93 -0
- package/dist/config/set.js.map +1 -0
- package/dist/config/set.test.d.ts +2 -0
- package/dist/config/set.test.d.ts.map +1 -0
- package/dist/config/set.test.js +98 -0
- package/dist/config/set.test.js.map +1 -0
- package/dist/healing/classify.d.ts +15 -0
- package/dist/healing/classify.d.ts.map +1 -0
- package/dist/healing/classify.js +209 -0
- package/dist/healing/classify.js.map +1 -0
- package/dist/healing/classify.test.d.ts +2 -0
- package/dist/healing/classify.test.d.ts.map +1 -0
- package/dist/healing/classify.test.js +167 -0
- package/dist/healing/classify.test.js.map +1 -0
- package/dist/healing/recovery-prompt.d.ts +3 -0
- package/dist/healing/recovery-prompt.d.ts.map +1 -0
- package/dist/healing/recovery-prompt.js +22 -0
- package/dist/healing/recovery-prompt.js.map +1 -0
- package/dist/mcp/inline-scenario.d.ts +13 -0
- package/dist/mcp/inline-scenario.d.ts.map +1 -0
- package/dist/mcp/inline-scenario.js +23 -0
- package/dist/mcp/inline-scenario.js.map +1 -0
- package/dist/mcp/server.d.ts +4 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +186 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/skill.d.ts +5 -0
- package/dist/mcp/skill.d.ts.map +1 -0
- package/dist/mcp/skill.js +38 -0
- package/dist/mcp/skill.js.map +1 -0
- package/dist/mcp/skill.test.d.ts +2 -0
- package/dist/mcp/skill.test.d.ts.map +1 -0
- package/dist/mcp/skill.test.js +18 -0
- package/dist/mcp/skill.test.js.map +1 -0
- package/dist/paths.d.ts +12 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +61 -0
- package/dist/paths.js.map +1 -0
- package/dist/prompt/load.d.ts +4 -0
- package/dist/prompt/load.d.ts.map +1 -0
- package/dist/prompt/load.js +19 -0
- package/dist/prompt/load.js.map +1 -0
- package/dist/recorder/bridge-process.d.ts +14 -0
- package/dist/recorder/bridge-process.d.ts.map +1 -0
- package/dist/recorder/bridge-process.js +133 -0
- package/dist/recorder/bridge-process.js.map +1 -0
- package/dist/recorder/bridge-process.test.d.ts +2 -0
- package/dist/recorder/bridge-process.test.d.ts.map +1 -0
- package/dist/recorder/bridge-process.test.js +36 -0
- package/dist/recorder/bridge-process.test.js.map +1 -0
- package/dist/recorder/bridge-worker.d.ts +2 -0
- package/dist/recorder/bridge-worker.d.ts.map +1 -0
- package/dist/recorder/bridge-worker.js +76 -0
- package/dist/recorder/bridge-worker.js.map +1 -0
- package/dist/recorder/bridge.d.ts +12 -0
- package/dist/recorder/bridge.d.ts.map +1 -0
- package/dist/recorder/bridge.js +61 -0
- package/dist/recorder/bridge.js.map +1 -0
- package/dist/recorder/bridge.test.d.ts +2 -0
- package/dist/recorder/bridge.test.d.ts.map +1 -0
- package/dist/recorder/bridge.test.js +21 -0
- package/dist/recorder/bridge.test.js.map +1 -0
- package/dist/recorder/enrich-event.d.ts +31 -0
- package/dist/recorder/enrich-event.d.ts.map +1 -0
- package/dist/recorder/enrich-event.js +91 -0
- package/dist/recorder/enrich-event.js.map +1 -0
- package/dist/recorder/events.d.ts +11 -0
- package/dist/recorder/events.d.ts.map +1 -0
- package/dist/recorder/events.js +42 -0
- package/dist/recorder/events.js.map +1 -0
- package/dist/recorder/events.test.d.ts +2 -0
- package/dist/recorder/events.test.d.ts.map +1 -0
- package/dist/recorder/events.test.js +40 -0
- package/dist/recorder/events.test.js.map +1 -0
- package/dist/recorder/generate-scenario.d.ts +16 -0
- package/dist/recorder/generate-scenario.d.ts.map +1 -0
- package/dist/recorder/generate-scenario.js +78 -0
- package/dist/recorder/generate-scenario.js.map +1 -0
- package/dist/recorder/in-page-helpers.d.ts +6 -0
- package/dist/recorder/in-page-helpers.d.ts.map +1 -0
- package/dist/recorder/in-page-helpers.js +238 -0
- package/dist/recorder/in-page-helpers.js.map +1 -0
- package/dist/recorder/in-page-helpers.test.d.ts +2 -0
- package/dist/recorder/in-page-helpers.test.d.ts.map +1 -0
- package/dist/recorder/in-page-helpers.test.js +186 -0
- package/dist/recorder/in-page-helpers.test.js.map +1 -0
- package/dist/recorder/page-script.d.ts +7 -0
- package/dist/recorder/page-script.d.ts.map +1 -0
- package/dist/recorder/page-script.js +132 -0
- package/dist/recorder/page-script.js.map +1 -0
- package/dist/recorder/redact.d.ts +8 -0
- package/dist/recorder/redact.d.ts.map +1 -0
- package/dist/recorder/redact.js +26 -0
- package/dist/recorder/redact.js.map +1 -0
- package/dist/recorder/redact.test.d.ts +2 -0
- package/dist/recorder/redact.test.d.ts.map +1 -0
- package/dist/recorder/redact.test.js +27 -0
- package/dist/recorder/redact.test.js.map +1 -0
- package/dist/recorder/session.d.ts +8 -0
- package/dist/recorder/session.d.ts.map +1 -0
- package/dist/recorder/session.js +28 -0
- package/dist/recorder/session.js.map +1 -0
- package/dist/recorder/snapshot-match.d.ts +22 -0
- package/dist/recorder/snapshot-match.d.ts.map +1 -0
- package/dist/recorder/snapshot-match.js +102 -0
- package/dist/recorder/snapshot-match.js.map +1 -0
- package/dist/recorder/snapshot-match.test.d.ts +2 -0
- package/dist/recorder/snapshot-match.test.d.ts.map +1 -0
- package/dist/recorder/snapshot-match.test.js +34 -0
- package/dist/recorder/snapshot-match.test.js.map +1 -0
- package/dist/redact/env-secrets.d.ts +14 -0
- package/dist/redact/env-secrets.d.ts.map +1 -0
- package/dist/redact/env-secrets.js +86 -0
- package/dist/redact/env-secrets.js.map +1 -0
- package/dist/redact/env-secrets.test.d.ts +2 -0
- package/dist/redact/env-secrets.test.d.ts.map +1 -0
- package/dist/redact/env-secrets.test.js +103 -0
- package/dist/redact/env-secrets.test.js.map +1 -0
- package/dist/reporter/export.d.ts +14 -0
- package/dist/reporter/export.d.ts.map +1 -0
- package/dist/reporter/export.js +53 -0
- package/dist/reporter/export.js.map +1 -0
- package/dist/reporter/export.test.d.ts +2 -0
- package/dist/reporter/export.test.d.ts.map +1 -0
- package/dist/reporter/export.test.js +100 -0
- package/dist/reporter/export.test.js.map +1 -0
- package/dist/reporter/index.d.ts +11 -0
- package/dist/reporter/index.d.ts.map +1 -0
- package/dist/reporter/index.js +161 -0
- package/dist/reporter/index.js.map +1 -0
- package/dist/reporter/index.test.d.ts +2 -0
- package/dist/reporter/index.test.d.ts.map +1 -0
- package/dist/reporter/index.test.js +61 -0
- package/dist/reporter/index.test.js.map +1 -0
- package/dist/scenarios/globs.d.ts +15 -0
- package/dist/scenarios/globs.d.ts.map +1 -0
- package/dist/scenarios/globs.js +48 -0
- package/dist/scenarios/globs.js.map +1 -0
- package/dist/scenarios/globs.test.d.ts +2 -0
- package/dist/scenarios/globs.test.d.ts.map +1 -0
- package/dist/scenarios/globs.test.js +53 -0
- package/dist/scenarios/globs.test.js.map +1 -0
- package/dist/scenarios/parser.d.ts +15 -0
- package/dist/scenarios/parser.d.ts.map +1 -0
- package/dist/scenarios/parser.js +278 -0
- package/dist/scenarios/parser.js.map +1 -0
- package/dist/scenarios/parser.test.d.ts +2 -0
- package/dist/scenarios/parser.test.d.ts.map +1 -0
- package/dist/scenarios/parser.test.js +373 -0
- package/dist/scenarios/parser.test.js.map +1 -0
- package/dist/skills/loader.d.ts +10 -0
- package/dist/skills/loader.d.ts.map +1 -0
- package/dist/skills/loader.js +98 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/types/config.d.ts +131 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +2 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/recorder.d.ts +71 -0
- package/dist/types/recorder.d.ts.map +1 -0
- package/dist/types/recorder.js +2 -0
- package/dist/types/recorder.js.map +1 -0
- package/dist/types/scenario.d.ts +41 -0
- package/dist/types/scenario.d.ts.map +1 -0
- package/dist/types/scenario.js +2 -0
- package/dist/types/scenario.js.map +1 -0
- package/dist/types/skill.d.ts +20 -0
- package/dist/types/skill.d.ts.map +1 -0
- package/dist/types/skill.js +13 -0
- package/dist/types/skill.js.map +1 -0
- package/dist/types/verdict.d.ts +82 -0
- package/dist/types/verdict.d.ts.map +1 -0
- package/dist/types/verdict.js +13 -0
- package/dist/types/verdict.js.map +1 -0
- package/package.json +75 -0
- package/pqa.config.ts +82 -0
- package/prompt/ANALYZE-FLAKY.md +62 -0
- package/prompt/ANALYZE.md +110 -0
- package/prompt/CACHE-HINTS.md +49 -0
- package/prompt/RECORD.md +114 -0
- package/prompt/SYSTEM.md +118 -0
- package/skills/agent-browser/SKILL.md +2438 -0
- package/skills/create-pqa-scenario/SKILL.md +273 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-side helpers embedded in the page recorder and Chrome extension.
|
|
3
|
+
* Keep this file free of Node imports — it is inlined into injected scripts.
|
|
4
|
+
*/
|
|
5
|
+
export function buildInPageRecorderHelpers() {
|
|
6
|
+
return `
|
|
7
|
+
const INTERACTIVE_ROLES = new Set([
|
|
8
|
+
"button", "link", "menuitem", "menuitemcheckbox", "menuitemradio",
|
|
9
|
+
"option", "tab", "combobox", "listbox", "checkbox", "radio", "switch",
|
|
10
|
+
"slider", "textbox", "searchbox", "spinbutton", "gridcell", "row",
|
|
11
|
+
"treeitem", "cell",
|
|
12
|
+
]);
|
|
13
|
+
const INTERACTIVE_TAGS = new Set([
|
|
14
|
+
"button", "a", "input", "select", "textarea", "summary", "label",
|
|
15
|
+
]);
|
|
16
|
+
const NON_INTERACTIVE_TAGS = new Set(["html", "body", "head"]);
|
|
17
|
+
|
|
18
|
+
function asElement(node) {
|
|
19
|
+
if (!node) return null;
|
|
20
|
+
if (node.nodeType === 1) return node;
|
|
21
|
+
if (node.nodeType === 3 && node.parentElement) return node.parentElement;
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function isHidden(el) {
|
|
26
|
+
if (!el || el.nodeType !== 1) return true;
|
|
27
|
+
if (el.getAttribute && el.getAttribute("aria-hidden") === "true") return true;
|
|
28
|
+
try {
|
|
29
|
+
const style = getComputedStyle(el);
|
|
30
|
+
if (
|
|
31
|
+
style.display === "none" ||
|
|
32
|
+
style.visibility === "hidden" ||
|
|
33
|
+
style.pointerEvents === "none"
|
|
34
|
+
) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
} catch (_) {}
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function implicitRole(el) {
|
|
42
|
+
const tag = el.tagName ? el.tagName.toLowerCase() : "";
|
|
43
|
+
if (tag === "a" && el.hasAttribute && el.hasAttribute("href")) return "link";
|
|
44
|
+
if (tag === "button") return "button";
|
|
45
|
+
if (tag === "select") return "combobox";
|
|
46
|
+
if (tag === "textarea") return "textbox";
|
|
47
|
+
if (tag === "input" && el.type) {
|
|
48
|
+
const type = String(el.type).toLowerCase();
|
|
49
|
+
if (type === "checkbox") return "checkbox";
|
|
50
|
+
if (type === "radio") return "radio";
|
|
51
|
+
if (type === "submit" || type === "button" || type === "reset") return "button";
|
|
52
|
+
if (type === "hidden") return null;
|
|
53
|
+
return "textbox";
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function isSnapshotInteractive(el) {
|
|
59
|
+
if (!el || el.nodeType !== 1 || isHidden(el)) return false;
|
|
60
|
+
const tag = el.tagName ? el.tagName.toLowerCase() : "";
|
|
61
|
+
if (NON_INTERACTIVE_TAGS.has(tag)) return false;
|
|
62
|
+
if (INTERACTIVE_TAGS.has(tag)) return true;
|
|
63
|
+
const role =
|
|
64
|
+
(el.getAttribute && el.getAttribute("role")?.toLowerCase()) ||
|
|
65
|
+
implicitRole(el);
|
|
66
|
+
if (role && INTERACTIVE_ROLES.has(role)) return true;
|
|
67
|
+
const hasPopup = el.getAttribute && el.getAttribute("aria-haspopup");
|
|
68
|
+
if (hasPopup && hasPopup !== "false") return true;
|
|
69
|
+
const tabindex = el.getAttribute && el.getAttribute("tabindex");
|
|
70
|
+
if (tabindex != null && String(tabindex) !== "-1") return true;
|
|
71
|
+
if (el.isContentEditable) return true;
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function pushCandidate(list, el) {
|
|
76
|
+
if (el && list.indexOf(el) === -1) list.push(el);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function containsPoint(el, x, y) {
|
|
80
|
+
if (!el || typeof el.getBoundingClientRect !== "function") return false;
|
|
81
|
+
const rect = el.getBoundingClientRect();
|
|
82
|
+
return (
|
|
83
|
+
x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function interactiveInSubtreeAtPoint(root, x, y) {
|
|
88
|
+
if (!root || !root.querySelectorAll) return null;
|
|
89
|
+
const nodes = root.querySelectorAll(
|
|
90
|
+
'button, a, input, select, textarea, [role], [tabindex]:not([tabindex="-1"]), [aria-haspopup]'
|
|
91
|
+
);
|
|
92
|
+
let best = null;
|
|
93
|
+
let bestArea = Infinity;
|
|
94
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
95
|
+
const node = nodes[i];
|
|
96
|
+
if (!isSnapshotInteractive(node) || !containsPoint(node, x, y)) continue;
|
|
97
|
+
const rect = node.getBoundingClientRect();
|
|
98
|
+
const area = rect.width * rect.height;
|
|
99
|
+
if (area < bestArea) {
|
|
100
|
+
best = node;
|
|
101
|
+
bestArea = area;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return best;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function resolveFromAncestorsAtPoint(start, x, y) {
|
|
108
|
+
let root = start;
|
|
109
|
+
while (root && root.nodeType === 1) {
|
|
110
|
+
const tag = root.tagName ? root.tagName.toLowerCase() : "";
|
|
111
|
+
if (tag !== "html" && tag !== "body") {
|
|
112
|
+
const hit = interactiveInSubtreeAtPoint(root, x, y);
|
|
113
|
+
if (hit) return hit;
|
|
114
|
+
}
|
|
115
|
+
root = root.parentElement;
|
|
116
|
+
}
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function findRelatedCombobox(start) {
|
|
121
|
+
let root = start;
|
|
122
|
+
while (root && root.nodeType === 1) {
|
|
123
|
+
const tag = root.tagName ? root.tagName.toLowerCase() : "";
|
|
124
|
+
if (tag === "html" || tag === "body") break;
|
|
125
|
+
if (root.querySelector) {
|
|
126
|
+
const combo = root.querySelector('[role="combobox"]');
|
|
127
|
+
if (combo && isSnapshotInteractive(combo)) return combo;
|
|
128
|
+
}
|
|
129
|
+
root = root.parentElement;
|
|
130
|
+
}
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function resolveClickTarget(ev) {
|
|
135
|
+
const path =
|
|
136
|
+
typeof ev.composedPath === "function" ? ev.composedPath() : [];
|
|
137
|
+
const candidates = [];
|
|
138
|
+
const x = ev.clientX;
|
|
139
|
+
const y = ev.clientY;
|
|
140
|
+
|
|
141
|
+
if (typeof document.elementFromPoint === "function") {
|
|
142
|
+
pushCandidate(candidates, asElement(document.elementFromPoint(x, y)));
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
let target = asElement(ev.target);
|
|
146
|
+
if (target) pushCandidate(candidates, target);
|
|
147
|
+
|
|
148
|
+
for (let i = 0; i < path.length; i++) {
|
|
149
|
+
pushCandidate(candidates, asElement(path[i]));
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
for (let c = 0; c < candidates.length; c++) {
|
|
153
|
+
let el = candidates[c];
|
|
154
|
+
while (el && el.nodeType === 1) {
|
|
155
|
+
const tag = el.tagName ? el.tagName.toLowerCase() : "";
|
|
156
|
+
if (tag === "html" || tag === "body") {
|
|
157
|
+
el = el.parentElement;
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
if (isSnapshotInteractive(el)) return el;
|
|
161
|
+
el = el.parentElement;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
for (let c = 0; c < candidates.length; c++) {
|
|
166
|
+
const hit = resolveFromAncestorsAtPoint(candidates[c], x, y);
|
|
167
|
+
if (hit) return hit;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
for (let c = 0; c < candidates.length; c++) {
|
|
171
|
+
const combo = findRelatedCombobox(candidates[c]);
|
|
172
|
+
if (combo) return combo;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function roleOf(el) {
|
|
179
|
+
if (!el || el.nodeType !== 1) return undefined;
|
|
180
|
+
const explicit = el.getAttribute && el.getAttribute("role");
|
|
181
|
+
if (explicit) return explicit.toLowerCase();
|
|
182
|
+
const implicit = implicitRole(el);
|
|
183
|
+
if (implicit) return implicit;
|
|
184
|
+
const tag = el.tagName ? el.tagName.toLowerCase() : "";
|
|
185
|
+
const map = {
|
|
186
|
+
a: "link",
|
|
187
|
+
button: "button",
|
|
188
|
+
input: "textbox",
|
|
189
|
+
select: "combobox",
|
|
190
|
+
textarea: "textbox",
|
|
191
|
+
label: "label",
|
|
192
|
+
};
|
|
193
|
+
return map[tag];
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function nameOf(el) {
|
|
197
|
+
if (!el || el.nodeType !== 1) return undefined;
|
|
198
|
+
const labelledBy =
|
|
199
|
+
el.getAttribute && el.getAttribute("aria-labelledby");
|
|
200
|
+
if (labelledBy) {
|
|
201
|
+
const parts = labelledBy
|
|
202
|
+
.split(/\\s+/)
|
|
203
|
+
.map((id) => document.getElementById(id))
|
|
204
|
+
.filter(Boolean)
|
|
205
|
+
.map((n) => (n.textContent || "").trim())
|
|
206
|
+
.filter(Boolean);
|
|
207
|
+
if (parts.length) return parts.join(" ").slice(0, 200);
|
|
208
|
+
}
|
|
209
|
+
const aria = el.getAttribute && el.getAttribute("aria-label");
|
|
210
|
+
if (aria) return aria.trim().slice(0, 200);
|
|
211
|
+
if (el.labels && el.labels[0])
|
|
212
|
+
return el.labels[0].textContent.trim().slice(0, 200);
|
|
213
|
+
if (el.id) {
|
|
214
|
+
const label = document.querySelector('label[for="' + el.id + '"]');
|
|
215
|
+
if (label) return label.textContent.trim().slice(0, 200);
|
|
216
|
+
}
|
|
217
|
+
const text = (el.innerText || el.textContent || "").trim();
|
|
218
|
+
if (text && text.length < 120) return text;
|
|
219
|
+
if (el.name) return el.name;
|
|
220
|
+
if (el.placeholder) return el.placeholder;
|
|
221
|
+
return undefined;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function labelOf(el) {
|
|
225
|
+
const n = nameOf(el);
|
|
226
|
+
if (n) return n;
|
|
227
|
+
const role = roleOf(el);
|
|
228
|
+
if (role) return role;
|
|
229
|
+
if (el && el.tagName) return el.tagName.toLowerCase();
|
|
230
|
+
return undefined;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function targetFromEvent(ev) {
|
|
234
|
+
return resolveClickTarget(ev);
|
|
235
|
+
}
|
|
236
|
+
`;
|
|
237
|
+
}
|
|
238
|
+
//# sourceMappingURL=in-page-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-page-helpers.js","sourceRoot":"","sources":["../../src/recorder/in-page-helpers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,0BAA0B;IACxC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsOR,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-page-helpers.test.d.ts","sourceRoot":"","sources":["../../src/recorder/in-page-helpers.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { createContext, runInContext } from "node:vm";
|
|
3
|
+
import { describe, it } from "node:test";
|
|
4
|
+
import { buildInPageRecorderHelpers } from "./in-page-helpers.js";
|
|
5
|
+
function el(tag, opts = {}) {
|
|
6
|
+
const node = {
|
|
7
|
+
nodeType: 1,
|
|
8
|
+
tagName: tag.toUpperCase(),
|
|
9
|
+
type: opts.type,
|
|
10
|
+
parentElement: opts.parent ?? null,
|
|
11
|
+
textContent: opts.text,
|
|
12
|
+
innerText: opts.text,
|
|
13
|
+
id: opts.id,
|
|
14
|
+
getAttribute(name) {
|
|
15
|
+
if (name === "role")
|
|
16
|
+
return opts.role ?? null;
|
|
17
|
+
if (name === "tabindex")
|
|
18
|
+
return opts.tabindex ?? null;
|
|
19
|
+
if (name === "aria-hidden")
|
|
20
|
+
return opts.ariaHidden ? "true" : null;
|
|
21
|
+
return null;
|
|
22
|
+
},
|
|
23
|
+
hasAttribute(name) {
|
|
24
|
+
return name === "href" && tag === "a";
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
return node;
|
|
28
|
+
}
|
|
29
|
+
function chain(...nodes) {
|
|
30
|
+
const first = nodes[0];
|
|
31
|
+
if (!first)
|
|
32
|
+
throw new Error("chain requires at least one node");
|
|
33
|
+
for (let i = 0; i < nodes.length - 1; i++) {
|
|
34
|
+
const current = nodes[i];
|
|
35
|
+
const parent = nodes[i + 1];
|
|
36
|
+
if (current && parent)
|
|
37
|
+
current.parentElement = parent;
|
|
38
|
+
}
|
|
39
|
+
return first;
|
|
40
|
+
}
|
|
41
|
+
function loadHelpers(document) {
|
|
42
|
+
const ctx = createContext({
|
|
43
|
+
document,
|
|
44
|
+
getComputedStyle: () => ({
|
|
45
|
+
display: "block",
|
|
46
|
+
visibility: "visible",
|
|
47
|
+
pointerEvents: "auto",
|
|
48
|
+
}),
|
|
49
|
+
});
|
|
50
|
+
runInContext(buildInPageRecorderHelpers(), ctx);
|
|
51
|
+
return ctx;
|
|
52
|
+
}
|
|
53
|
+
describe("in-page recorder target resolution", () => {
|
|
54
|
+
it("resolves body target via elementFromPoint to interactive ancestor", () => {
|
|
55
|
+
const body = el("body");
|
|
56
|
+
const wrapper = el("div", { parent: body });
|
|
57
|
+
const button = el("button", { parent: wrapper, text: "Filter" });
|
|
58
|
+
chain(button, wrapper, body);
|
|
59
|
+
const helpers = loadHelpers({
|
|
60
|
+
body,
|
|
61
|
+
documentElement: el("html"),
|
|
62
|
+
elementFromPoint: () => button,
|
|
63
|
+
getElementById: () => null,
|
|
64
|
+
querySelector: () => null,
|
|
65
|
+
});
|
|
66
|
+
const resolved = helpers.resolveClickTarget({
|
|
67
|
+
target: body,
|
|
68
|
+
clientX: 10,
|
|
69
|
+
clientY: 10,
|
|
70
|
+
composedPath: () => [body, wrapper, button],
|
|
71
|
+
});
|
|
72
|
+
assert.equal(resolved, button);
|
|
73
|
+
assert.equal(helpers.roleOf(button), "button");
|
|
74
|
+
assert.equal(helpers.nameOf(button), "Filter");
|
|
75
|
+
});
|
|
76
|
+
it("walks composedPath to first snapshot-interactive element", () => {
|
|
77
|
+
const body = el("body");
|
|
78
|
+
const helpers = loadHelpers({
|
|
79
|
+
body,
|
|
80
|
+
documentElement: el("html"),
|
|
81
|
+
elementFromPoint: () => null,
|
|
82
|
+
getElementById: () => null,
|
|
83
|
+
querySelector: () => null,
|
|
84
|
+
});
|
|
85
|
+
const span = el("span", { parent: body, text: "Paid" });
|
|
86
|
+
const option = el("li", { parent: body, role: "option", text: "Paid" });
|
|
87
|
+
chain(span, option, body);
|
|
88
|
+
const resolved = helpers.resolveClickTarget({
|
|
89
|
+
target: span,
|
|
90
|
+
clientX: 0,
|
|
91
|
+
clientY: 0,
|
|
92
|
+
composedPath: () => [span, option, body],
|
|
93
|
+
});
|
|
94
|
+
assert.equal(resolved, option);
|
|
95
|
+
assert.equal(helpers.roleOf(option), "option");
|
|
96
|
+
});
|
|
97
|
+
it("finds combobox sibling when click lands on a non-interactive wrapper (MUI Select)", () => {
|
|
98
|
+
const body = el("body");
|
|
99
|
+
const formControl = el("div", { parent: body });
|
|
100
|
+
const inputBase = el("div", { parent: formControl });
|
|
101
|
+
const outline = el("div", { parent: inputBase });
|
|
102
|
+
const combobox = el("div", {
|
|
103
|
+
parent: inputBase,
|
|
104
|
+
role: "combobox",
|
|
105
|
+
text: "Status",
|
|
106
|
+
tabindex: "0",
|
|
107
|
+
});
|
|
108
|
+
chain(outline, inputBase, formControl, body);
|
|
109
|
+
const helpers = loadHelpers({
|
|
110
|
+
body,
|
|
111
|
+
documentElement: el("html"),
|
|
112
|
+
elementFromPoint: () => outline,
|
|
113
|
+
getElementById: () => null,
|
|
114
|
+
querySelector: () => null,
|
|
115
|
+
});
|
|
116
|
+
combobox.getBoundingClientRect =
|
|
117
|
+
() => ({ left: 0, top: 0, right: 100, bottom: 30, width: 100, height: 30 });
|
|
118
|
+
outline.getBoundingClientRect =
|
|
119
|
+
() => ({ left: 0, top: 0, right: 100, bottom: 30, width: 100, height: 30 });
|
|
120
|
+
const withQuery = (node) => {
|
|
121
|
+
node.querySelectorAll =
|
|
122
|
+
() => [combobox];
|
|
123
|
+
};
|
|
124
|
+
withQuery(inputBase);
|
|
125
|
+
withQuery(formControl);
|
|
126
|
+
const resolved = helpers.resolveClickTarget({
|
|
127
|
+
target: outline,
|
|
128
|
+
clientX: 50,
|
|
129
|
+
clientY: 15,
|
|
130
|
+
composedPath: () => [outline, inputBase, formControl, body],
|
|
131
|
+
});
|
|
132
|
+
assert.equal(resolved, combobox);
|
|
133
|
+
assert.equal(helpers.roleOf(combobox), "combobox");
|
|
134
|
+
});
|
|
135
|
+
it("finds combobox when click is on a sibling icon (MUI Select chevron)", () => {
|
|
136
|
+
const body = el("body");
|
|
137
|
+
const inputBase = el("div", { parent: body });
|
|
138
|
+
const combobox = el("div", {
|
|
139
|
+
parent: inputBase,
|
|
140
|
+
role: "combobox",
|
|
141
|
+
text: "All",
|
|
142
|
+
tabindex: "0",
|
|
143
|
+
});
|
|
144
|
+
const icon = el("div", { parent: inputBase });
|
|
145
|
+
chain(icon, inputBase, body);
|
|
146
|
+
const helpers = loadHelpers({
|
|
147
|
+
body,
|
|
148
|
+
documentElement: el("html"),
|
|
149
|
+
elementFromPoint: () => icon,
|
|
150
|
+
getElementById: () => null,
|
|
151
|
+
querySelector: () => null,
|
|
152
|
+
});
|
|
153
|
+
combobox.getBoundingClientRect =
|
|
154
|
+
() => ({ left: 0, top: 0, right: 80, bottom: 30, width: 80, height: 30 });
|
|
155
|
+
icon.getBoundingClientRect =
|
|
156
|
+
() => ({ left: 200, top: 0, right: 230, bottom: 30, width: 30, height: 30 });
|
|
157
|
+
inputBase.querySelector = (sel) => sel.includes("combobox") ? combobox : null;
|
|
158
|
+
inputBase.querySelectorAll =
|
|
159
|
+
() => [combobox];
|
|
160
|
+
const resolved = helpers.resolveClickTarget({
|
|
161
|
+
target: icon,
|
|
162
|
+
clientX: 210,
|
|
163
|
+
clientY: 15,
|
|
164
|
+
composedPath: () => [icon, inputBase, body],
|
|
165
|
+
});
|
|
166
|
+
assert.equal(resolved, combobox);
|
|
167
|
+
});
|
|
168
|
+
it("returns null when only body/html is clicked with no interactive target", () => {
|
|
169
|
+
const body = el("body");
|
|
170
|
+
const helpers = loadHelpers({
|
|
171
|
+
body,
|
|
172
|
+
documentElement: el("html"),
|
|
173
|
+
elementFromPoint: () => null,
|
|
174
|
+
getElementById: () => null,
|
|
175
|
+
querySelector: () => null,
|
|
176
|
+
});
|
|
177
|
+
const resolved = helpers.resolveClickTarget({
|
|
178
|
+
target: body,
|
|
179
|
+
clientX: 0,
|
|
180
|
+
clientY: 0,
|
|
181
|
+
composedPath: () => [body],
|
|
182
|
+
});
|
|
183
|
+
assert.equal(resolved, null);
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
//# sourceMappingURL=in-page-helpers.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-page-helpers.test.js","sourceRoot":"","sources":["../../src/recorder/in-page-helpers.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-page recorder injected via agent-browser --init-script.
|
|
3
|
+
* Posts accessibility-oriented events to the local PQA bridge.
|
|
4
|
+
*/
|
|
5
|
+
export declare function buildPageRecorderScript(bridgeUrl: string): string;
|
|
6
|
+
export declare function writePageRecorderScript(bridgeUrl: string, destPath: string): string;
|
|
7
|
+
//# sourceMappingURL=page-script.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-script.d.ts","sourceRoot":"","sources":["../../src/recorder/page-script.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAuHjE;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,MAAM,CAIR"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { writeFileSync } from "node:fs";
|
|
2
|
+
import { buildInPageRecorderHelpers } from "./in-page-helpers.js";
|
|
3
|
+
/**
|
|
4
|
+
* In-page recorder injected via agent-browser --init-script.
|
|
5
|
+
* Posts accessibility-oriented events to the local PQA bridge.
|
|
6
|
+
*/
|
|
7
|
+
export function buildPageRecorderScript(bridgeUrl) {
|
|
8
|
+
const bridge = JSON.stringify(bridgeUrl);
|
|
9
|
+
const helpers = buildInPageRecorderHelpers();
|
|
10
|
+
return `(() => {
|
|
11
|
+
const BRIDGE = ${bridge};
|
|
12
|
+
const sentNav = new Set();
|
|
13
|
+
${helpers}
|
|
14
|
+
|
|
15
|
+
function post(payload) {
|
|
16
|
+
try {
|
|
17
|
+
fetch(BRIDGE + "/event", {
|
|
18
|
+
method: "POST",
|
|
19
|
+
headers: { "Content-Type": "application/json" },
|
|
20
|
+
body: JSON.stringify({ ...payload, ts: Date.now() }),
|
|
21
|
+
keepalive: true,
|
|
22
|
+
}).catch(() => {});
|
|
23
|
+
} catch (_) {}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function recordNavigate() {
|
|
27
|
+
const url = location.href;
|
|
28
|
+
if (sentNav.has(url)) return;
|
|
29
|
+
sentNav.add(url);
|
|
30
|
+
post({ type: "navigate", url });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let lastRecordedClickKey = "";
|
|
34
|
+
let lastRecordedClickAt = 0;
|
|
35
|
+
|
|
36
|
+
function recordClick(ev) {
|
|
37
|
+
if (typeof ev.button === "number" && ev.button !== 0) return;
|
|
38
|
+
const el = resolveClickTarget(ev);
|
|
39
|
+
if (!el) return;
|
|
40
|
+
const payload = {
|
|
41
|
+
type: "click",
|
|
42
|
+
role: roleOf(el),
|
|
43
|
+
name: nameOf(el),
|
|
44
|
+
label: labelOf(el),
|
|
45
|
+
clientX: ev.clientX,
|
|
46
|
+
clientY: ev.clientY,
|
|
47
|
+
};
|
|
48
|
+
const key = [payload.role, payload.name, payload.label].join("|");
|
|
49
|
+
const now = Date.now();
|
|
50
|
+
if (key === lastRecordedClickKey && now - lastRecordedClickAt < 500) return;
|
|
51
|
+
lastRecordedClickKey = key;
|
|
52
|
+
lastRecordedClickAt = now;
|
|
53
|
+
post(payload);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// MUI Select opens on mousedown + preventDefault(), which suppresses click.
|
|
57
|
+
document.addEventListener("mousedown", recordClick, true);
|
|
58
|
+
document.addEventListener("click", recordClick, true);
|
|
59
|
+
|
|
60
|
+
document.addEventListener(
|
|
61
|
+
"change",
|
|
62
|
+
(ev) => {
|
|
63
|
+
const el = targetFromEvent(ev) || asElement(ev.target);
|
|
64
|
+
if (!el) return;
|
|
65
|
+
const tag = el.tagName ? el.tagName.toLowerCase() : "";
|
|
66
|
+
if (tag === "select") {
|
|
67
|
+
const opt = el.selectedOptions && el.selectedOptions[0];
|
|
68
|
+
post({
|
|
69
|
+
type: "select",
|
|
70
|
+
name: nameOf(el),
|
|
71
|
+
value: opt ? (opt.textContent || opt.value || "").trim().slice(0, 200) : "",
|
|
72
|
+
clientX: ev.clientX,
|
|
73
|
+
clientY: ev.clientY,
|
|
74
|
+
});
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (tag === "input" || tag === "textarea") {
|
|
78
|
+
const type = (el.type || "").toLowerCase();
|
|
79
|
+
if (type === "password" || type === "file") {
|
|
80
|
+
post({
|
|
81
|
+
type: "fill",
|
|
82
|
+
role: roleOf(el),
|
|
83
|
+
name: nameOf(el),
|
|
84
|
+
value: "[REDACTED]",
|
|
85
|
+
clientX: ev.clientX,
|
|
86
|
+
clientY: ev.clientY,
|
|
87
|
+
});
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
post({
|
|
91
|
+
type: "fill",
|
|
92
|
+
role: roleOf(el),
|
|
93
|
+
name: nameOf(el),
|
|
94
|
+
value: String(el.value ?? "").slice(0, 500),
|
|
95
|
+
clientX: ev.clientX,
|
|
96
|
+
clientY: ev.clientY,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
true
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
document.addEventListener(
|
|
104
|
+
"submit",
|
|
105
|
+
() => {
|
|
106
|
+
post({ type: "submit" });
|
|
107
|
+
},
|
|
108
|
+
true
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
const pushState = history.pushState;
|
|
112
|
+
history.pushState = function () {
|
|
113
|
+
pushState.apply(this, arguments);
|
|
114
|
+
recordNavigate();
|
|
115
|
+
};
|
|
116
|
+
const replaceState = history.replaceState;
|
|
117
|
+
history.replaceState = function () {
|
|
118
|
+
replaceState.apply(this, arguments);
|
|
119
|
+
recordNavigate();
|
|
120
|
+
};
|
|
121
|
+
window.addEventListener("popstate", recordNavigate);
|
|
122
|
+
window.addEventListener("hashchange", recordNavigate);
|
|
123
|
+
|
|
124
|
+
recordNavigate();
|
|
125
|
+
})();`;
|
|
126
|
+
}
|
|
127
|
+
export function writePageRecorderScript(bridgeUrl, destPath) {
|
|
128
|
+
const content = buildPageRecorderScript(bridgeUrl);
|
|
129
|
+
writeFileSync(destPath, content, "utf-8");
|
|
130
|
+
return destPath;
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=page-script.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-script.js","sourceRoot":"","sources":["../../src/recorder/page-script.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAElE;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CAAC,SAAiB;IACvD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,0BAA0B,EAAE,CAAC;IAC7C,OAAO;mBACU,MAAM;;IAErB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAgHL,CAAC;AACP,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,SAAiB,EACjB,QAAgB;IAEhB,MAAM,OAAO,GAAG,uBAAuB,CAAC,SAAS,CAAC,CAAC;IACnD,aAAa,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC1C,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RecordEvent } from "../types/recorder.js";
|
|
2
|
+
export declare function isSensitiveFieldName(name?: string): boolean;
|
|
3
|
+
export declare function redactFillValue(value: string, fieldName?: string, sensitiveEnvVars?: string[]): {
|
|
4
|
+
value: string;
|
|
5
|
+
redacted: boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare function sanitizeRecordEvent(event: RecordEvent, sensitiveEnvVars?: string[]): RecordEvent;
|
|
8
|
+
//# sourceMappingURL=redact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../src/recorder/redact.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAa,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAKnE,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAG3D;AAED,wBAAgB,eAAe,CAC7B,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,EAClB,gBAAgB,GAAE,MAAM,EAAO,GAC9B;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAUtC;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,WAAW,EAClB,gBAAgB,GAAE,MAAM,EAAO,GAC9B,WAAW,CASb"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createEnvRedactor } from "../redact/env-secrets.js";
|
|
2
|
+
const PASSWORD_HINT = /password|passwd|secret|token|api[_-]?key|credential/i;
|
|
3
|
+
export function isSensitiveFieldName(name) {
|
|
4
|
+
if (!name)
|
|
5
|
+
return false;
|
|
6
|
+
return PASSWORD_HINT.test(name);
|
|
7
|
+
}
|
|
8
|
+
export function redactFillValue(value, fieldName, sensitiveEnvVars = []) {
|
|
9
|
+
if (isSensitiveFieldName(fieldName)) {
|
|
10
|
+
return { value: "[REDACTED]", redacted: true };
|
|
11
|
+
}
|
|
12
|
+
const redactor = createEnvRedactor(process.env, sensitiveEnvVars);
|
|
13
|
+
const redacted = redactor.redact(value);
|
|
14
|
+
if (redacted !== value) {
|
|
15
|
+
return { value: redacted, redacted: true };
|
|
16
|
+
}
|
|
17
|
+
return { value, redacted: false };
|
|
18
|
+
}
|
|
19
|
+
export function sanitizeRecordEvent(event, sensitiveEnvVars = []) {
|
|
20
|
+
if (event.type !== "fill")
|
|
21
|
+
return event;
|
|
22
|
+
const fill = event;
|
|
23
|
+
const { value, redacted } = redactFillValue(fill.value, fill.name, sensitiveEnvVars);
|
|
24
|
+
return { ...fill, value, redacted: redacted || fill.redacted };
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=redact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.js","sourceRoot":"","sources":["../../src/recorder/redact.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAG7D,MAAM,aAAa,GACjB,sDAAsD,CAAC;AAEzD,MAAM,UAAU,oBAAoB,CAAC,IAAa;IAChD,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACxB,OAAO,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,KAAa,EACb,SAAkB,EAClB,mBAA6B,EAAE;IAE/B,IAAI,oBAAoB,CAAC,SAAS,CAAC,EAAE,CAAC;QACpC,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACjD,CAAC;IACD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;IAClE,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACxC,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;QACvB,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IAC7C,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,mBAAmB,CACjC,KAAkB,EAClB,mBAA6B,EAAE;IAE/B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,MAAM,IAAI,GAAG,KAAkB,CAAC;IAChC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,eAAe,CACzC,IAAI,CAAC,KAAK,EACV,IAAI,CAAC,IAAI,EACT,gBAAgB,CACjB,CAAC;IACF,OAAO,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.test.d.ts","sourceRoot":"","sources":["../../src/recorder/redact.test.ts"],"names":[],"mappings":""}
|