qa360 2.2.20 → 2.3.1
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/README.md +155 -262
- package/{cli/dist → dist}/commands/ai.js +1 -1
- package/{cli/dist → dist}/commands/coverage.js +1 -1
- package/{cli/dist → dist}/commands/crawl.d.ts +12 -1
- package/{cli/dist → dist}/commands/crawl.js +70 -9
- package/{cli/dist → dist}/commands/doctor.js +2 -2
- package/{cli/dist → dist}/commands/explain.js +2 -2
- package/{cli/dist → dist}/commands/flakiness.js +1 -1
- package/{cli/dist → dist}/commands/generate.js +1 -1
- package/{cli/dist → dist}/commands/history.js +1 -1
- package/{cli/dist → dist}/commands/monitor.js +3 -3
- package/{cli/dist → dist}/commands/ollama.js +1 -1
- package/{cli/dist → dist}/commands/pack.js +2 -2
- package/{cli/dist → dist}/commands/regression.js +1 -1
- package/{cli/dist → dist}/commands/repair.js +1 -1
- package/{cli/dist → dist}/commands/retry.js +1 -1
- package/{cli/dist → dist}/commands/run.d.ts +1 -1
- package/{cli/dist → dist}/commands/run.js +1 -1
- package/{cli/dist → dist}/commands/secrets.js +1 -1
- package/{cli/dist → dist}/commands/serve.js +1 -1
- package/{cli/dist → dist}/commands/slo.js +1 -1
- package/{cli/dist → dist}/commands/verify.js +1 -1
- package/{cli/dist → dist}/core/adapters/playwright-native-api.d.ts +2 -0
- package/{cli/dist → dist}/core/adapters/playwright-native-api.js +20 -1
- package/{cli/dist → dist}/core/adapters/playwright-ui.d.ts +21 -0
- package/dist/core/adapters/playwright-ui.js +2050 -0
- package/{cli/dist → dist}/core/ai/ollama-provider.js +15 -3
- package/{cli/dist → dist}/core/artifacts/ui-artifacts.js +24 -4
- package/dist/core/auth/backup-codes-provider.d.ts +91 -0
- package/dist/core/auth/backup-codes-provider.js +215 -0
- package/{cli/dist → dist}/core/auth/basic-auth-provider.d.ts +6 -0
- package/{cli/dist → dist}/core/auth/basic-auth-provider.js +24 -6
- package/dist/core/auth/digest-auth-provider.d.ts +116 -0
- package/dist/core/auth/digest-auth-provider.js +244 -0
- package/dist/core/auth/hcaptcha-handler.d.ts +103 -0
- package/dist/core/auth/hcaptcha-handler.js +288 -0
- package/{cli/dist → dist}/core/auth/index.d.ts +81 -4
- package/{cli/dist → dist}/core/auth/index.js +15 -1
- package/dist/core/auth/oauth-handler.d.ts +408 -0
- package/dist/core/auth/oauth-handler.js +636 -0
- package/{cli/dist → dist}/core/auth/oauth2-provider.d.ts +9 -0
- package/dist/core/auth/oauth2-provider.js +227 -0
- package/dist/core/auth/otp-provider.d.ts +93 -0
- package/dist/core/auth/otp-provider.js +288 -0
- package/dist/core/auth/recaptcha-handler.d.ts +119 -0
- package/dist/core/auth/recaptcha-handler.js +301 -0
- package/dist/core/auth/remember-me-handler.d.ts +142 -0
- package/dist/core/auth/remember-me-handler.js +255 -0
- package/dist/core/auth/saml-handler.d.ts +173 -0
- package/dist/core/auth/saml-handler.js +364 -0
- package/dist/core/auth/webauthn-handler.d.ts +182 -0
- package/dist/core/auth/webauthn-handler.js +310 -0
- package/dist/core/crawler/advanced-interactions.d.ts +342 -0
- package/dist/core/crawler/advanced-interactions.js +1069 -0
- package/dist/core/crawler/blob-url-download-handler.d.ts +145 -0
- package/dist/core/crawler/blob-url-download-handler.js +392 -0
- package/dist/core/crawler/consent-handler.d.ts +49 -0
- package/dist/core/crawler/consent-handler.js +258 -0
- package/dist/core/crawler/cookie-manager.d.ts +166 -0
- package/dist/core/crawler/cookie-manager.js +353 -0
- package/dist/core/crawler/coop-coep-handler.d.ts +136 -0
- package/dist/core/crawler/coop-coep-handler.js +338 -0
- package/dist/core/crawler/csp-handler.d.ts +151 -0
- package/dist/core/crawler/csp-handler.js +415 -0
- package/dist/core/crawler/download-handler.d.ts +155 -0
- package/dist/core/crawler/download-handler.js +370 -0
- package/dist/core/crawler/email-testing-handler.d.ts +214 -0
- package/dist/core/crawler/email-testing-handler.js +398 -0
- package/dist/core/crawler/error-tracking-handler.d.ts +177 -0
- package/dist/core/crawler/error-tracking-handler.js +378 -0
- package/dist/core/crawler/form-handler.d.ts +100 -0
- package/dist/core/crawler/form-handler.js +465 -0
- package/dist/core/crawler/framework-wait-handler.d.ts +96 -0
- package/dist/core/crawler/framework-wait-handler.js +464 -0
- package/dist/core/crawler/geolocation-handler.d.ts +112 -0
- package/dist/core/crawler/geolocation-handler.js +276 -0
- package/dist/core/crawler/index.d.ts +78 -0
- package/{cli/dist → dist}/core/crawler/index.js +74 -1
- package/dist/core/crawler/intelligent-selector-generator.d.ts +164 -0
- package/dist/core/crawler/intelligent-selector-generator.js +612 -0
- package/{cli/dist → dist}/core/crawler/journey-generator.js +44 -1
- package/{cli/dist → dist}/core/crawler/page-analyzer.d.ts +16 -1
- package/{cli/dist → dist}/core/crawler/page-analyzer.js +469 -17
- package/dist/core/crawler/permissions-handler.d.ts +112 -0
- package/dist/core/crawler/permissions-handler.js +236 -0
- package/dist/core/crawler/permissions-policy-handler.d.ts +113 -0
- package/dist/core/crawler/permissions-policy-handler.js +402 -0
- package/dist/core/crawler/presets.d.ts +100 -0
- package/dist/core/crawler/presets.js +887 -0
- package/dist/core/crawler/repl-debug-handler.d.ts +105 -0
- package/dist/core/crawler/repl-debug-handler.js +552 -0
- package/dist/core/crawler/reporting-api-handler.d.ts +212 -0
- package/dist/core/crawler/reporting-api-handler.js +344 -0
- package/{cli/dist → dist}/core/crawler/selector-generator.d.ts +9 -0
- package/{cli/dist → dist}/core/crawler/selector-generator.js +99 -23
- package/dist/core/crawler/site-profiler.d.ts +89 -0
- package/dist/core/crawler/site-profiler.js +290 -0
- package/dist/core/crawler/sourcemaps-handler.d.ts +144 -0
- package/dist/core/crawler/sourcemaps-handler.js +420 -0
- package/dist/core/crawler/stacked-modals-handler.d.ts +118 -0
- package/dist/core/crawler/stacked-modals-handler.js +429 -0
- package/dist/core/crawler/trusted-types-handler.d.ts +149 -0
- package/dist/core/crawler/trusted-types-handler.js +413 -0
- package/{cli/dist → dist}/core/crawler/types.d.ts +68 -2
- package/dist/core/crawler/wait-strategies.d.ts +108 -0
- package/dist/core/crawler/wait-strategies.js +399 -0
- package/dist/core/fixtures/factories.d.ts +180 -0
- package/dist/core/fixtures/factories.js +279 -0
- package/dist/core/fixtures/index.d.ts +6 -0
- package/dist/core/fixtures/index.js +6 -0
- package/{cli/dist → dist}/core/generation/crawler-pack-generator.d.ts +13 -3
- package/dist/core/generation/crawler-pack-generator.js +232 -0
- package/{cli/dist → dist}/core/generation/index.d.ts +2 -0
- package/{cli/dist → dist}/core/generation/index.js +2 -0
- package/{cli/dist → dist}/core/index.d.ts +2 -0
- package/{cli/dist → dist}/core/index.js +4 -0
- package/dist/core/network/index.d.ts +7 -0
- package/dist/core/network/index.js +7 -0
- package/dist/core/network/network-manager.d.ts +237 -0
- package/dist/core/network/network-manager.js +343 -0
- package/dist/core/network/network-simulator.d.ts +158 -0
- package/dist/core/network/network-simulator.js +261 -0
- package/{cli/dist → dist}/core/pack/validator.js +2 -2
- package/{cli/dist → dist}/core/pack-v2/migrator.d.ts +5 -0
- package/{cli/dist → dist}/core/pack-v2/migrator.js +81 -6
- package/{cli/dist → dist}/core/pack-v2/validator.js +4 -3
- package/{cli/dist → dist}/core/pom/base-page.js +1 -1
- package/{cli/dist → dist}/core/pom/loader.js +1 -1
- package/dist/core/reporting/index.d.ts +9 -0
- package/dist/core/reporting/index.js +10 -0
- package/dist/core/reporting/junit-reporter.d.ts +114 -0
- package/dist/core/reporting/junit-reporter.js +306 -0
- package/{cli/dist → dist}/core/runner/e2e-helpers.d.ts +1 -1
- package/{cli/dist → dist}/core/runner/e2e-helpers.js +2 -2
- package/{cli/dist → dist}/core/runner/phase3-runner.d.ts +3 -0
- package/{cli/dist → dist}/core/runner/phase3-runner.js +45 -14
- package/dist/core/sharding/test-sharding.d.ts +137 -0
- package/dist/core/sharding/test-sharding.js +233 -0
- package/dist/core/storage/cookie-manager.d.ts +160 -0
- package/dist/core/storage/cookie-manager.js +268 -0
- package/dist/core/storage/index.d.ts +7 -0
- package/dist/core/storage/index.js +7 -0
- package/dist/core/storage/storage-helpers.d.ts +138 -0
- package/dist/core/storage/storage-helpers.js +315 -0
- package/dist/core/test-helpers/index.d.ts +6 -0
- package/dist/core/test-helpers/index.js +6 -0
- package/dist/core/test-helpers/state-reset.d.ts +119 -0
- package/dist/core/test-helpers/state-reset.js +234 -0
- package/{cli/dist → dist}/core/types/pack-v1.d.ts +15 -2
- package/{cli/dist → dist}/core/types/pack-v2.d.ts +1 -1
- package/dist/core/upload/chunked-uploader.d.ts +150 -0
- package/dist/core/upload/chunked-uploader.js +289 -0
- package/dist/core/upload/index.d.ts +11 -0
- package/dist/core/upload/index.js +8 -0
- package/dist/core/upload/mime-validator.d.ts +119 -0
- package/dist/core/upload/mime-validator.js +373 -0
- package/dist/core/upload/presigned-uploader.d.ts +118 -0
- package/dist/core/upload/presigned-uploader.js +274 -0
- package/dist/core/utils/device-emulation.d.ts +194 -0
- package/dist/core/utils/device-emulation.js +380 -0
- package/dist/core/utils/index.d.ts +8 -0
- package/dist/core/utils/index.js +8 -0
- package/dist/core/utils/retry.d.ts +145 -0
- package/dist/core/utils/retry.js +242 -0
- package/dist/core/utils/smart-wait.d.ts +133 -0
- package/dist/core/utils/smart-wait.js +417 -0
- package/dist/core/visual/index.d.ts +7 -0
- package/dist/core/visual/index.js +7 -0
- package/dist/core/visual/pixel-diff.d.ts +87 -0
- package/dist/core/visual/pixel-diff.js +213 -0
- package/dist/core/visual/screenshot-helper.d.ts +130 -0
- package/dist/core/visual/screenshot-helper.js +223 -0
- package/{cli/dist → dist}/utils/config.d.ts +1 -1
- package/examples/README.md +160 -0
- package/examples/accessibility.yml +48 -0
- package/examples/api-basic.yml +27 -0
- package/examples/complete.yml +146 -0
- package/examples/crawler.yml +38 -0
- package/examples/fullstack.yml +78 -0
- package/examples/security.yml +58 -0
- package/examples/ui-advanced.yml +49 -0
- package/examples/ui-basic.yml +24 -0
- package/package.json +33 -67
- package/CHANGELOG.md +0 -262
- package/CONTRIBUTING.md +0 -273
- package/QUICK_START.md +0 -191
- package/cli/CHANGELOG.md +0 -84
- package/cli/LICENSE +0 -24
- package/cli/README.md +0 -222
- package/cli/dist/core/adapters/playwright-ui.js +0 -864
- package/cli/dist/core/auth/oauth2-provider.js +0 -114
- package/cli/dist/core/coverage/analyzer.d.ts +0 -101
- package/cli/dist/core/coverage/analyzer.js +0 -415
- package/cli/dist/core/coverage/collector.d.ts +0 -74
- package/cli/dist/core/coverage/collector.js +0 -459
- package/cli/dist/core/coverage/config.d.ts +0 -37
- package/cli/dist/core/coverage/config.js +0 -156
- package/cli/dist/core/coverage/index.d.ts +0 -11
- package/cli/dist/core/coverage/index.js +0 -15
- package/cli/dist/core/coverage/types.d.ts +0 -267
- package/cli/dist/core/coverage/types.js +0 -6
- package/cli/dist/core/coverage/vault.d.ts +0 -95
- package/cli/dist/core/coverage/vault.js +0 -405
- package/cli/dist/core/crawler/index.d.ts +0 -57
- package/cli/dist/core/fixtures/index.d.ts +0 -8
- package/cli/dist/core/fixtures/index.js +0 -8
- package/cli/dist/core/generation/crawler-pack-generator.js +0 -231
- package/cli/dist/core/reporting/index.d.ts +0 -6
- package/cli/dist/core/reporting/index.js +0 -6
- package/cli/dist/core/visual/index.d.ts +0 -6
- package/cli/dist/core/visual/index.js +0 -6
- package/cli/package.json +0 -76
- package/core/LICENSE +0 -24
- package/core/README.md +0 -64
- package/core/package.json +0 -81
- package/core/schemas/pack.schema.json +0 -236
- /package/{cli/bin → bin}/qa360.js +0 -0
- /package/{cli/dist → dist}/cli-minimal.d.ts +0 -0
- /package/{cli/dist → dist}/cli-minimal.js +0 -0
- /package/{cli/dist → dist}/commands/ai.d.ts +0 -0
- /package/{cli/dist → dist}/commands/ask.d.ts +0 -0
- /package/{cli/dist → dist}/commands/ask.js +0 -0
- /package/{cli/dist → dist}/commands/coverage.d.ts +0 -0
- /package/{cli/dist → dist}/commands/doctor.d.ts +0 -0
- /package/{cli/dist → dist}/commands/examples.d.ts +0 -0
- /package/{cli/dist → dist}/commands/examples.js +0 -0
- /package/{cli/dist → dist}/commands/explain.d.ts +0 -0
- /package/{cli/dist → dist}/commands/flakiness.d.ts +0 -0
- /package/{cli/dist → dist}/commands/generate.d.ts +0 -0
- /package/{cli/dist → dist}/commands/history.d.ts +0 -0
- /package/{cli/dist → dist}/commands/init.d.ts +0 -0
- /package/{cli/dist → dist}/commands/init.js +0 -0
- /package/{cli/dist → dist}/commands/monitor.d.ts +0 -0
- /package/{cli/dist → dist}/commands/ollama.d.ts +0 -0
- /package/{cli/dist → dist}/commands/pack.d.ts +0 -0
- /package/{cli/dist → dist}/commands/regression.d.ts +0 -0
- /package/{cli/dist → dist}/commands/repair.d.ts +0 -0
- /package/{cli/dist → dist}/commands/report.d.ts +0 -0
- /package/{cli/dist → dist}/commands/report.js +0 -0
- /package/{cli/dist → dist}/commands/retry.d.ts +0 -0
- /package/{cli/dist → dist}/commands/scan.d.ts +0 -0
- /package/{cli/dist → dist}/commands/scan.js +0 -0
- /package/{cli/dist → dist}/commands/secrets.d.ts +0 -0
- /package/{cli/dist → dist}/commands/serve.d.ts +0 -0
- /package/{cli/dist → dist}/commands/slo.d.ts +0 -0
- /package/{cli/dist → dist}/commands/verify.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/gitleaks-secrets.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/gitleaks-secrets.js +0 -0
- /package/{cli/dist → dist}/core/adapters/jest-adapter.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/jest-adapter.js +0 -0
- /package/{cli/dist → dist}/core/adapters/k6-perf.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/k6-perf.js +0 -0
- /package/{cli/dist → dist}/core/adapters/osv-deps.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/osv-deps.js +0 -0
- /package/{cli/dist → dist}/core/adapters/playwright-native-adapter.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/playwright-native-adapter.js +0 -0
- /package/{cli/dist → dist}/core/adapters/pytest-adapter.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/pytest-adapter.js +0 -0
- /package/{cli/dist → dist}/core/adapters/semgrep-sast.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/semgrep-sast.js +0 -0
- /package/{cli/dist → dist}/core/adapters/unit-test-types.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/unit-test-types.js +0 -0
- /package/{cli/dist → dist}/core/adapters/vitest-adapter.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/vitest-adapter.js +0 -0
- /package/{cli/dist → dist}/core/adapters/zap-dast.d.ts +0 -0
- /package/{cli/dist → dist}/core/adapters/zap-dast.js +0 -0
- /package/{cli/dist → dist}/core/ai/anthropic-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/ai/anthropic-provider.js +0 -0
- /package/{cli/dist → dist}/core/ai/deepseek-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/ai/deepseek-provider.js +0 -0
- /package/{cli/dist → dist}/core/ai/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/ai/index.js +0 -0
- /package/{cli/dist → dist}/core/ai/llm-client.d.ts +0 -0
- /package/{cli/dist → dist}/core/ai/llm-client.js +0 -0
- /package/{cli/dist → dist}/core/ai/mock-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/ai/mock-provider.js +0 -0
- /package/{cli/dist → dist}/core/ai/ollama-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/ai/openai-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/ai/openai-provider.js +0 -0
- /package/{cli/dist → dist}/core/ai/provider-factory.d.ts +0 -0
- /package/{cli/dist → dist}/core/ai/provider-factory.js +0 -0
- /package/{cli/dist → dist}/core/artifacts/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/artifacts/index.js +0 -0
- /package/{cli/dist → dist}/core/artifacts/ui-artifacts.d.ts +0 -0
- /package/{cli/dist → dist}/core/assertions/engine.d.ts +0 -0
- /package/{cli/dist → dist}/core/assertions/engine.js +0 -0
- /package/{cli/dist → dist}/core/assertions/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/assertions/index.js +0 -0
- /package/{cli/dist → dist}/core/assertions/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/assertions/types.js +0 -0
- /package/{cli/dist → dist}/core/auth/api-key-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/auth/api-key-provider.js +0 -0
- /package/{cli/dist → dist}/core/auth/aws-iam-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/auth/aws-iam-provider.js +0 -0
- /package/{cli/dist → dist}/core/auth/azure-ad-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/auth/azure-ad-provider.js +0 -0
- /package/{cli/dist → dist}/core/auth/gcp-adc-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/auth/gcp-adc-provider.js +0 -0
- /package/{cli/dist → dist}/core/auth/jwt-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/auth/jwt-provider.js +0 -0
- /package/{cli/dist → dist}/core/auth/manager.d.ts +0 -0
- /package/{cli/dist → dist}/core/auth/manager.js +0 -0
- /package/{cli/dist → dist}/core/auth/totp-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/auth/totp-provider.js +0 -0
- /package/{cli/dist → dist}/core/auth/ui-login-provider.d.ts +0 -0
- /package/{cli/dist → dist}/core/auth/ui-login-provider.js +0 -0
- /package/{cli/dist → dist}/core/cache/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/cache/index.js +0 -0
- /package/{cli/dist → dist}/core/cache/lru-cache.d.ts +0 -0
- /package/{cli/dist → dist}/core/cache/lru-cache.js +0 -0
- /package/{cli/dist/core → dist}/core/coverage/analyzer.d.ts +0 -0
- /package/{cli/dist/core → dist}/core/coverage/analyzer.js +0 -0
- /package/{cli/dist/core → dist}/core/coverage/collector.d.ts +0 -0
- /package/{cli/dist/core → dist}/core/coverage/collector.js +0 -0
- /package/{cli/dist/core → dist}/core/coverage/config.d.ts +0 -0
- /package/{cli/dist/core → dist}/core/coverage/config.js +0 -0
- /package/{cli/dist/core → dist}/core/coverage/index.d.ts +0 -0
- /package/{cli/dist/core → dist}/core/coverage/index.js +0 -0
- /package/{cli/dist/core → dist}/core/coverage/types.d.ts +0 -0
- /package/{cli/dist/core → dist}/core/coverage/types.js +0 -0
- /package/{cli/dist/core → dist}/core/coverage/vault.d.ts +0 -0
- /package/{cli/dist/core → dist}/core/coverage/vault.js +0 -0
- /package/{cli/dist → dist}/core/crawler/journey-generator.d.ts +0 -0
- /package/{cli/dist → dist}/core/crawler/types.js +0 -0
- /package/{cli/dist → dist}/core/dashboard/assets.d.ts +0 -0
- /package/{cli/dist → dist}/core/dashboard/assets.js +0 -0
- /package/{cli/dist → dist}/core/dashboard/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/dashboard/index.js +0 -0
- /package/{cli/dist → dist}/core/dashboard/server.d.ts +0 -0
- /package/{cli/dist → dist}/core/dashboard/server.js +0 -0
- /package/{cli/dist → dist}/core/dashboard/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/dashboard/types.js +0 -0
- /package/{cli/dist → dist}/core/discoverer/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/discoverer/index.js +0 -0
- /package/{cli/dist → dist}/core/fixtures/loader.d.ts +0 -0
- /package/{cli/dist → dist}/core/fixtures/loader.js +0 -0
- /package/{cli/dist → dist}/core/fixtures/resolver.d.ts +0 -0
- /package/{cli/dist → dist}/core/fixtures/resolver.js +0 -0
- /package/{cli/dist → dist}/core/fixtures/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/fixtures/types.js +0 -0
- /package/{cli/dist → dist}/core/flakiness/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/flakiness/index.js +0 -0
- /package/{cli/dist → dist}/core/generation/code-formatter.d.ts +0 -0
- /package/{cli/dist → dist}/core/generation/code-formatter.js +0 -0
- /package/{cli/dist → dist}/core/generation/code-generator.d.ts +0 -0
- /package/{cli/dist → dist}/core/generation/code-generator.js +0 -0
- /package/{cli/dist → dist}/core/generation/generator.d.ts +0 -0
- /package/{cli/dist → dist}/core/generation/generator.js +0 -0
- /package/{cli/dist → dist}/core/generation/pack-generator.d.ts +0 -0
- /package/{cli/dist → dist}/core/generation/pack-generator.js +0 -0
- /package/{cli/dist → dist}/core/generation/prompt-builder.d.ts +0 -0
- /package/{cli/dist → dist}/core/generation/prompt-builder.js +0 -0
- /package/{cli/dist → dist}/core/generation/source-analyzer.d.ts +0 -0
- /package/{cli/dist → dist}/core/generation/source-analyzer.js +0 -0
- /package/{cli/dist → dist}/core/generation/test-optimizer.d.ts +0 -0
- /package/{cli/dist → dist}/core/generation/test-optimizer.js +0 -0
- /package/{cli/dist → dist}/core/generation/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/generation/types.js +0 -0
- /package/{cli/dist → dist}/core/hooks/compose.d.ts +0 -0
- /package/{cli/dist → dist}/core/hooks/compose.js +0 -0
- /package/{cli/dist → dist}/core/hooks/runner.d.ts +0 -0
- /package/{cli/dist → dist}/core/hooks/runner.js +0 -0
- /package/{cli/dist → dist}/core/pack/migrator.d.ts +0 -0
- /package/{cli/dist → dist}/core/pack/migrator.js +0 -0
- /package/{cli/dist → dist}/core/pack/validator.d.ts +0 -0
- /package/{cli/dist → dist}/core/pack-v2/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/pack-v2/index.js +0 -0
- /package/{cli/dist → dist}/core/pack-v2/loader.d.ts +0 -0
- /package/{cli/dist → dist}/core/pack-v2/loader.js +0 -0
- /package/{cli/dist → dist}/core/pack-v2/validator.d.ts +0 -0
- /package/{cli/dist → dist}/core/parallel/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/parallel/index.js +0 -0
- /package/{cli/dist → dist}/core/parallel/parallel-runner.d.ts +0 -0
- /package/{cli/dist → dist}/core/parallel/parallel-runner.js +0 -0
- /package/{cli/dist → dist}/core/pom/base-page.d.ts +0 -0
- /package/{cli/dist → dist}/core/pom/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/pom/index.js +0 -0
- /package/{cli/dist → dist}/core/pom/loader.d.ts +0 -0
- /package/{cli/dist → dist}/core/pom/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/pom/types.js +0 -0
- /package/{cli/dist → dist}/core/proof/bundle.d.ts +0 -0
- /package/{cli/dist → dist}/core/proof/bundle.js +0 -0
- /package/{cli/dist → dist}/core/proof/canonicalize.d.ts +0 -0
- /package/{cli/dist → dist}/core/proof/canonicalize.js +0 -0
- /package/{cli/dist → dist}/core/proof/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/proof/index.js +0 -0
- /package/{cli/dist → dist}/core/proof/schema.d.ts +0 -0
- /package/{cli/dist → dist}/core/proof/schema.js +0 -0
- /package/{cli/dist → dist}/core/proof/signer.d.ts +0 -0
- /package/{cli/dist → dist}/core/proof/signer.js +0 -0
- /package/{cli/dist → dist}/core/proof/verifier.d.ts +0 -0
- /package/{cli/dist → dist}/core/proof/verifier.js +0 -0
- /package/{cli/dist → dist}/core/regression/detector.d.ts +0 -0
- /package/{cli/dist → dist}/core/regression/detector.js +0 -0
- /package/{cli/dist → dist}/core/regression/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/regression/index.js +0 -0
- /package/{cli/dist → dist}/core/regression/trend-analyzer.d.ts +0 -0
- /package/{cli/dist → dist}/core/regression/trend-analyzer.js +0 -0
- /package/{cli/dist → dist}/core/regression/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/regression/types.js +0 -0
- /package/{cli/dist → dist}/core/regression/vault.d.ts +0 -0
- /package/{cli/dist → dist}/core/regression/vault.js +0 -0
- /package/{cli/dist → dist}/core/repair/engine/fixer.d.ts +0 -0
- /package/{cli/dist → dist}/core/repair/engine/fixer.js +0 -0
- /package/{cli/dist → dist}/core/repair/engine/suggestion-engine.d.ts +0 -0
- /package/{cli/dist → dist}/core/repair/engine/suggestion-engine.js +0 -0
- /package/{cli/dist → dist}/core/repair/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/repair/index.js +0 -0
- /package/{cli/dist → dist}/core/repair/repairer.d.ts +0 -0
- /package/{cli/dist → dist}/core/repair/repairer.js +0 -0
- /package/{cli/dist → dist}/core/repair/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/repair/types.js +0 -0
- /package/{cli/dist → dist}/core/repair/utils/error-analyzer.d.ts +0 -0
- /package/{cli/dist → dist}/core/repair/utils/error-analyzer.js +0 -0
- /package/{cli/dist → dist}/core/reporting/html-reporter.d.ts +0 -0
- /package/{cli/dist → dist}/core/reporting/html-reporter.js +0 -0
- /package/{cli/dist → dist}/core/retry/flakiness-integration.d.ts +0 -0
- /package/{cli/dist → dist}/core/retry/flakiness-integration.js +0 -0
- /package/{cli/dist → dist}/core/retry/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/retry/index.js +0 -0
- /package/{cli/dist → dist}/core/retry/retry-engine.d.ts +0 -0
- /package/{cli/dist → dist}/core/retry/retry-engine.js +0 -0
- /package/{cli/dist → dist}/core/retry/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/retry/types.js +0 -0
- /package/{cli/dist → dist}/core/retry/vault.d.ts +0 -0
- /package/{cli/dist → dist}/core/retry/vault.js +0 -0
- /package/{cli/dist → dist}/core/schemas/pack.schema.json +0 -0
- /package/{cli/dist → dist}/core/secrets/crypto.d.ts +0 -0
- /package/{cli/dist → dist}/core/secrets/crypto.js +0 -0
- /package/{cli/dist → dist}/core/secrets/manager.d.ts +0 -0
- /package/{cli/dist → dist}/core/secrets/manager.js +0 -0
- /package/{cli/dist → dist}/core/security/redaction-patterns-extended.d.ts +0 -0
- /package/{cli/dist → dist}/core/security/redaction-patterns-extended.js +0 -0
- /package/{cli/dist → dist}/core/security/redactor.d.ts +0 -0
- /package/{cli/dist → dist}/core/security/redactor.js +0 -0
- /package/{cli/dist → dist}/core/self-healing/assertion-healer.d.ts +0 -0
- /package/{cli/dist → dist}/core/self-healing/assertion-healer.js +0 -0
- /package/{cli/dist → dist}/core/self-healing/engine.d.ts +0 -0
- /package/{cli/dist → dist}/core/self-healing/engine.js +0 -0
- /package/{cli/dist → dist}/core/self-healing/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/self-healing/index.js +0 -0
- /package/{cli/dist → dist}/core/self-healing/selector-healer.d.ts +0 -0
- /package/{cli/dist → dist}/core/self-healing/selector-healer.js +0 -0
- /package/{cli/dist → dist}/core/self-healing/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/self-healing/types.js +0 -0
- /package/{cli/dist → dist}/core/serve/diagnostics-collector.d.ts +0 -0
- /package/{cli/dist → dist}/core/serve/diagnostics-collector.js +0 -0
- /package/{cli/dist → dist}/core/serve/health-checker.d.ts +0 -0
- /package/{cli/dist → dist}/core/serve/health-checker.js +0 -0
- /package/{cli/dist → dist}/core/serve/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/serve/index.js +0 -0
- /package/{cli/dist → dist}/core/serve/metrics-collector.d.ts +0 -0
- /package/{cli/dist → dist}/core/serve/metrics-collector.js +0 -0
- /package/{cli/dist → dist}/core/serve/process-manager.d.ts +0 -0
- /package/{cli/dist → dist}/core/serve/process-manager.js +0 -0
- /package/{cli/dist → dist}/core/serve/server.d.ts +0 -0
- /package/{cli/dist → dist}/core/serve/server.js +0 -0
- /package/{cli/dist → dist}/core/slo/config.d.ts +0 -0
- /package/{cli/dist → dist}/core/slo/config.js +0 -0
- /package/{cli/dist → dist}/core/slo/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/slo/index.js +0 -0
- /package/{cli/dist → dist}/core/slo/sli-calculator.d.ts +0 -0
- /package/{cli/dist → dist}/core/slo/sli-calculator.js +0 -0
- /package/{cli/dist → dist}/core/slo/slo-tracker.d.ts +0 -0
- /package/{cli/dist → dist}/core/slo/slo-tracker.js +0 -0
- /package/{cli/dist → dist}/core/slo/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/slo/types.js +0 -0
- /package/{cli/dist → dist}/core/slo/vault.d.ts +0 -0
- /package/{cli/dist → dist}/core/slo/vault.js +0 -0
- /package/{cli/dist → dist}/core/tui/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/tui/index.js +0 -0
- /package/{cli/dist → dist}/core/tui/monitor.d.ts +0 -0
- /package/{cli/dist → dist}/core/tui/monitor.js +0 -0
- /package/{cli/dist → dist}/core/tui/renderer.d.ts +0 -0
- /package/{cli/dist → dist}/core/tui/renderer.js +0 -0
- /package/{cli/dist → dist}/core/tui/types.d.ts +0 -0
- /package/{cli/dist → dist}/core/tui/types.js +0 -0
- /package/{cli/dist → dist}/core/types/pack-v1.js +0 -0
- /package/{cli/dist → dist}/core/types/pack-v2.js +0 -0
- /package/{cli/dist → dist}/core/types/trust-score.d.ts +0 -0
- /package/{cli/dist → dist}/core/types/trust-score.js +0 -0
- /package/{cli/dist → dist}/core/vault/cas.d.ts +0 -0
- /package/{cli/dist → dist}/core/vault/cas.js +0 -0
- /package/{cli/dist → dist}/core/vault/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/vault/index.js +0 -0
- /package/{cli/dist → dist}/core/visual/visual-regression.d.ts +0 -0
- /package/{cli/dist → dist}/core/visual/visual-regression.js +0 -0
- /package/{cli/dist → dist}/core/watch/index.d.ts +0 -0
- /package/{cli/dist → dist}/core/watch/index.js +0 -0
- /package/{cli/dist → dist}/core/watch/watch-mode.d.ts +0 -0
- /package/{cli/dist → dist}/core/watch/watch-mode.js +0 -0
- /package/{cli/dist → dist}/generators/index.d.ts +0 -0
- /package/{cli/dist → dist}/generators/index.js +0 -0
- /package/{cli/dist → dist}/generators/json-reporter.d.ts +0 -0
- /package/{cli/dist → dist}/generators/json-reporter.js +0 -0
- /package/{cli/dist → dist}/generators/test-generator.d.ts +0 -0
- /package/{cli/dist → dist}/generators/test-generator.js +0 -0
- /package/{cli/dist → dist}/index.d.ts +0 -0
- /package/{cli/dist → dist}/index.js +0 -0
- /package/{cli/dist → dist}/scanners/dom-scanner.d.ts +0 -0
- /package/{cli/dist → dist}/scanners/dom-scanner.js +0 -0
- /package/{cli/dist → dist}/scanners/index.d.ts +0 -0
- /package/{cli/dist → dist}/scanners/index.js +0 -0
- /package/{cli/dist → dist}/schemas/pack.schema.json +0 -0
- /package/{cli/dist → dist}/types/scan.d.ts +0 -0
- /package/{cli/dist → dist}/types/scan.js +0 -0
- /package/{cli/dist → dist}/utils/config.js +0 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WebAuthn / Passkeys Handler
|
|
3
|
+
*
|
|
4
|
+
* P1 - Modern passwordless authentication
|
|
5
|
+
*
|
|
6
|
+
* Supports:
|
|
7
|
+
* - WebAuthn registration (credential creation)
|
|
8
|
+
* - WebAuthn authentication (assertion)
|
|
9
|
+
* - Passkeys (platform and cross-device)
|
|
10
|
+
* - Credential ID storage and lookup
|
|
11
|
+
*
|
|
12
|
+
* @see https://w3c.github.io/webauthn/
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* WebAuthn Handler class
|
|
16
|
+
*/
|
|
17
|
+
export class WebAuthnHandler {
|
|
18
|
+
config;
|
|
19
|
+
credentials = new Map();
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.config = {
|
|
22
|
+
rpId: config.rpId,
|
|
23
|
+
rpName: config.rpName,
|
|
24
|
+
origin: config.origin || `https://${config.rpId}`,
|
|
25
|
+
userVerification: config.userVerification || 'preferred',
|
|
26
|
+
attestation: config.attestation || 'none',
|
|
27
|
+
requireResidentKey: config.requireResidentKey || false,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Generate a random challenge for WebAuthn
|
|
32
|
+
*/
|
|
33
|
+
generateChallenge() {
|
|
34
|
+
const challenge = new Uint8Array(32);
|
|
35
|
+
crypto.getRandomValues(challenge);
|
|
36
|
+
return this.bufferToBase64(challenge);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Create registration options for WebAuthn navigator.credentials.create()
|
|
40
|
+
*/
|
|
41
|
+
createRegistrationOptions(user, excludeCredentials) {
|
|
42
|
+
const challenge = this.generateChallenge();
|
|
43
|
+
const userId = this.bufferToBase64(user.id);
|
|
44
|
+
const options = {
|
|
45
|
+
challenge,
|
|
46
|
+
rp: {
|
|
47
|
+
id: this.config.rpId,
|
|
48
|
+
name: this.config.rpName,
|
|
49
|
+
},
|
|
50
|
+
user: {
|
|
51
|
+
id: userId,
|
|
52
|
+
name: user.name,
|
|
53
|
+
displayName: user.displayName,
|
|
54
|
+
icon: user.icon,
|
|
55
|
+
},
|
|
56
|
+
pubKeyCredParams: [
|
|
57
|
+
{ type: 'public-key', alg: -7 }, // ES256
|
|
58
|
+
{ type: 'public-key', alg: -257 }, // RS256
|
|
59
|
+
{ type: 'public-key', alg: -37 }, // ES512
|
|
60
|
+
],
|
|
61
|
+
authenticatorSelection: {
|
|
62
|
+
requireResidentKey: this.config.requireResidentKey,
|
|
63
|
+
userVerification: this.config.userVerification,
|
|
64
|
+
},
|
|
65
|
+
attestation: this.config.attestation,
|
|
66
|
+
timeout: 60000,
|
|
67
|
+
};
|
|
68
|
+
// Exclude existing credentials
|
|
69
|
+
if (excludeCredentials && excludeCredentials.length > 0) {
|
|
70
|
+
options.excludeCredentials = excludeCredentials.map(id => ({
|
|
71
|
+
id: this.base64ToBuffer(id).toString(),
|
|
72
|
+
type: 'public-key',
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
return options;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Parse registration response from navigator.credentials.create()
|
|
79
|
+
*/
|
|
80
|
+
async parseRegistration(response) {
|
|
81
|
+
try {
|
|
82
|
+
// Convert response to parseable format
|
|
83
|
+
const credential = response;
|
|
84
|
+
if (!credential || !credential.response) {
|
|
85
|
+
return { success: false, error: 'Invalid credential response' };
|
|
86
|
+
}
|
|
87
|
+
const attestationResponse = credential.response;
|
|
88
|
+
// Decode client data JSON
|
|
89
|
+
const clientDataJSON = this.decoder.decode(attestationResponse.clientDataJSON);
|
|
90
|
+
const clientData = JSON.parse(clientDataJSON);
|
|
91
|
+
// Verify challenge matches (in production, you'd verify against stored challenge)
|
|
92
|
+
// Verify origin matches
|
|
93
|
+
if (clientData.origin !== this.config.origin) {
|
|
94
|
+
return { success: false, error: `Origin mismatch: expected ${this.config.origin}, got ${clientData.origin}` };
|
|
95
|
+
}
|
|
96
|
+
// Verify type
|
|
97
|
+
if (clientData.type !== 'webauthn.create') {
|
|
98
|
+
return { success: false, error: `Type mismatch: expected webauthn.create, got ${clientData.type}` };
|
|
99
|
+
}
|
|
100
|
+
// Extract credential ID and public key
|
|
101
|
+
const credentialIdBytes = new Uint8Array(credential.rawId || new ArrayBuffer(0));
|
|
102
|
+
const credentialId = this.bufferToBase64(credentialIdBytes);
|
|
103
|
+
// Parse attestation object to get public key
|
|
104
|
+
let publicKeyObject;
|
|
105
|
+
try {
|
|
106
|
+
const attestationObject = this.decoder.decode(attestationResponse.attestationObject);
|
|
107
|
+
// Simple CBOR parsing would go here - for now we extract what we can
|
|
108
|
+
publicKeyObject = this.extractPublicKeyFromAttestation(attestationObject);
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Fallback: try to get public key directly
|
|
112
|
+
if (attestationResponse.getPublicKey) {
|
|
113
|
+
publicKeyObject = this.bufferToBase64(new Uint8Array(attestationResponse.getPublicKey()));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const webAuthnCredential = {
|
|
117
|
+
id: credentialId,
|
|
118
|
+
publicKey: publicKeyObject || '',
|
|
119
|
+
counter: 0,
|
|
120
|
+
type: 'public-key',
|
|
121
|
+
};
|
|
122
|
+
// Store credential
|
|
123
|
+
this.credentials.set(credentialId, webAuthnCredential);
|
|
124
|
+
return {
|
|
125
|
+
success: true,
|
|
126
|
+
credential: webAuthnCredential,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
catch (e) {
|
|
130
|
+
return {
|
|
131
|
+
success: false,
|
|
132
|
+
error: e instanceof Error ? e.message : 'Unknown error',
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Create authentication options for WebAuthn navigator.credentials.get()
|
|
138
|
+
*/
|
|
139
|
+
createAuthenticationOptions(allowedCredentials) {
|
|
140
|
+
const challenge = this.generateChallenge();
|
|
141
|
+
const options = {
|
|
142
|
+
challenge,
|
|
143
|
+
rpId: this.config.rpId,
|
|
144
|
+
userVerification: this.config.userVerification,
|
|
145
|
+
timeout: 60000,
|
|
146
|
+
};
|
|
147
|
+
// Add allowed credentials if provided
|
|
148
|
+
if (allowedCredentials && allowedCredentials.length > 0) {
|
|
149
|
+
options.allowCredentials = allowedCredentials.map(id => ({
|
|
150
|
+
id: this.base64ToBuffer(id).toString(),
|
|
151
|
+
type: 'public-key',
|
|
152
|
+
}));
|
|
153
|
+
}
|
|
154
|
+
return options;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Parse authentication response from navigator.credentials.get()
|
|
158
|
+
*/
|
|
159
|
+
async parseAuthentication(response) {
|
|
160
|
+
try {
|
|
161
|
+
const credential = response;
|
|
162
|
+
if (!credential || !credential.response) {
|
|
163
|
+
return { success: false, error: 'Invalid credential response' };
|
|
164
|
+
}
|
|
165
|
+
const assertionResponse = credential.response;
|
|
166
|
+
// Decode client data JSON
|
|
167
|
+
const clientDataJSON = this.decoder.decode(assertionResponse.clientDataJSON);
|
|
168
|
+
const clientData = JSON.parse(clientDataJSON);
|
|
169
|
+
// Verify origin
|
|
170
|
+
if (clientData.origin !== this.config.origin) {
|
|
171
|
+
return { success: false, error: `Origin mismatch: expected ${this.config.origin}, got ${clientData.origin}` };
|
|
172
|
+
}
|
|
173
|
+
// Verify type
|
|
174
|
+
if (clientData.type !== 'webauthn.get') {
|
|
175
|
+
return { success: false, error: `Type mismatch: expected webauthn.get, got ${clientData.type}` };
|
|
176
|
+
}
|
|
177
|
+
const credentialId = this.bufferToBase64(new Uint8Array(credential.rawId));
|
|
178
|
+
// Verify credential exists
|
|
179
|
+
if (!this.credentials.has(credentialId)) {
|
|
180
|
+
return { success: false, error: 'Unknown credential' };
|
|
181
|
+
}
|
|
182
|
+
// Extract user handle
|
|
183
|
+
let userHandle;
|
|
184
|
+
if (assertionResponse.userHandle) {
|
|
185
|
+
userHandle = this.decoder.decode(assertionResponse.userHandle);
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
success: true,
|
|
189
|
+
credentialId,
|
|
190
|
+
userHandle,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
catch (e) {
|
|
194
|
+
return {
|
|
195
|
+
success: false,
|
|
196
|
+
error: e instanceof Error ? e.message : 'Unknown error',
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Get stored credential by ID
|
|
202
|
+
*/
|
|
203
|
+
getCredential(credentialId) {
|
|
204
|
+
return this.credentials.get(credentialId);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Get all stored credentials for a user
|
|
208
|
+
*/
|
|
209
|
+
getCredentials() {
|
|
210
|
+
return Array.from(this.credentials.values());
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Check if WebAuthn is supported in current browser
|
|
214
|
+
*/
|
|
215
|
+
isSupported() {
|
|
216
|
+
return typeof window !== 'undefined' &&
|
|
217
|
+
typeof window.PublicKeyCredential !== 'undefined';
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Check if platform authenticator is available
|
|
221
|
+
*/
|
|
222
|
+
async isPlatformAvailable() {
|
|
223
|
+
if (!this.isSupported())
|
|
224
|
+
return false;
|
|
225
|
+
try {
|
|
226
|
+
const available = await window.PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable?.();
|
|
227
|
+
return available === true;
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Check if conditional mediation (autofill) is supported
|
|
235
|
+
*/
|
|
236
|
+
isConditionalMediationSupported() {
|
|
237
|
+
if (!this.isSupported())
|
|
238
|
+
return false;
|
|
239
|
+
// Check for Conditional UI (WebAuthn Conditional UI)
|
|
240
|
+
return window.PublicKeyCredential.isConditionalMediationAvailable?.() === true;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Store credential externally
|
|
244
|
+
*/
|
|
245
|
+
storeCredential(credential) {
|
|
246
|
+
this.credentials.set(credential.id, credential);
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Remove credential
|
|
250
|
+
*/
|
|
251
|
+
removeCredential(credentialId) {
|
|
252
|
+
return this.credentials.delete(credentialId);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Clear all credentials
|
|
256
|
+
*/
|
|
257
|
+
clearCredentials() {
|
|
258
|
+
this.credentials.clear();
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Helper: Convert ArrayBuffer to Base64
|
|
262
|
+
*/
|
|
263
|
+
bufferToBase64(buffer) {
|
|
264
|
+
const bytes = new Uint8Array(buffer);
|
|
265
|
+
let binary = '';
|
|
266
|
+
for (let i = 0; i < bytes.byteLength; i++) {
|
|
267
|
+
binary += String.fromCharCode(bytes[i]);
|
|
268
|
+
}
|
|
269
|
+
return btoa(binary)
|
|
270
|
+
.replace(/\+/g, '-')
|
|
271
|
+
.replace(/\//g, '_')
|
|
272
|
+
.replace(/=/g, '');
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Helper: Convert Base64 to Uint8Array
|
|
276
|
+
*/
|
|
277
|
+
base64ToBuffer(base64) {
|
|
278
|
+
// Add padding if needed
|
|
279
|
+
const padded = base64 + '='.repeat((4 - base64.length % 4) % 4);
|
|
280
|
+
// Replace URL-safe chars
|
|
281
|
+
const standard = padded.replace(/-/g, '+').replace(/_/g, '/');
|
|
282
|
+
const binary = atob(standard);
|
|
283
|
+
const bytes = new Uint8Array(binary.length);
|
|
284
|
+
for (let i = 0; i < binary.length; i++) {
|
|
285
|
+
bytes[i] = binary.charCodeAt(i);
|
|
286
|
+
}
|
|
287
|
+
return bytes;
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Helper to extract public key from attestation object
|
|
291
|
+
* This is a simplified version - full CBOR parsing would be more complex
|
|
292
|
+
*/
|
|
293
|
+
extractPublicKeyFromAttestation(attestationObject) {
|
|
294
|
+
// In a real implementation, you'd parse CBOR properly
|
|
295
|
+
// For now, return a placeholder that can be overridden
|
|
296
|
+
if (typeof attestationObject === 'string') {
|
|
297
|
+
return attestationObject;
|
|
298
|
+
}
|
|
299
|
+
const bytes = new Uint8Array(attestationObject);
|
|
300
|
+
return this.bufferToBase64(bytes.slice(0, Math.min(65, bytes.length)));
|
|
301
|
+
}
|
|
302
|
+
decoder = new TextDecoder();
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Factory function to create WebAuthn handler
|
|
306
|
+
*/
|
|
307
|
+
export function createWebAuthnHandler(config) {
|
|
308
|
+
return new WebAuthnHandler(config);
|
|
309
|
+
}
|
|
310
|
+
export default WebAuthnHandler;
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QA360 Advanced Interactions Handler
|
|
3
|
+
*
|
|
4
|
+
* P0 Features for Enterprise-Grade Testing:
|
|
5
|
+
* - Shadow DOM support (auto-piercing)
|
|
6
|
+
* - Iframe handling (same-origin + cross-origin)
|
|
7
|
+
* - File upload/download
|
|
8
|
+
*
|
|
9
|
+
* @since 2.3.0
|
|
10
|
+
*/
|
|
11
|
+
import type { Page, Locator, Frame } from '@playwright/test';
|
|
12
|
+
/**
|
|
13
|
+
* Configuration for advanced interactions
|
|
14
|
+
*/
|
|
15
|
+
export interface AdvancedInteractionsOptions {
|
|
16
|
+
/** Maximum shadow DOM depth to pierce (default: 5) */
|
|
17
|
+
maxShadowDepth?: number;
|
|
18
|
+
/** Whether to automatically pierce shadow DOM (default: true) */
|
|
19
|
+
autoShadowPiercing?: boolean;
|
|
20
|
+
/** Whether to handle iframes (default: true) */
|
|
21
|
+
handleIframes?: boolean;
|
|
22
|
+
/** Timeout for frame operations (default: 5000ms) */
|
|
23
|
+
frameTimeout?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Element location result with context
|
|
27
|
+
*/
|
|
28
|
+
export interface ElementLocation {
|
|
29
|
+
/** The element locator */
|
|
30
|
+
locator: Locator;
|
|
31
|
+
/** Whether element is in shadow DOM */
|
|
32
|
+
isInShadowDom: boolean;
|
|
33
|
+
/** Shadow DOM depth (0 = not in shadow DOM) */
|
|
34
|
+
shadowDepth: number;
|
|
35
|
+
/** Nested shadow DOM depth (tracks shadow roots within shadow roots) */
|
|
36
|
+
nestedShadowDepth?: number;
|
|
37
|
+
/** Whether element is in iframe */
|
|
38
|
+
isInIframe: boolean;
|
|
39
|
+
/** Whether iframe is cross-origin (only meaningful if isInIframe is true) */
|
|
40
|
+
isCrossOrigin?: boolean;
|
|
41
|
+
/** Frame selector if in iframe */
|
|
42
|
+
frameSelector?: string;
|
|
43
|
+
/** The path taken to find the element */
|
|
44
|
+
path: string[];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* File upload result
|
|
48
|
+
*/
|
|
49
|
+
export interface FileUploadResult {
|
|
50
|
+
/** Whether upload succeeded */
|
|
51
|
+
success: boolean;
|
|
52
|
+
/** Number of files uploaded */
|
|
53
|
+
count: number;
|
|
54
|
+
/** File names uploaded */
|
|
55
|
+
fileNames: string[];
|
|
56
|
+
/** Error message if failed */
|
|
57
|
+
error?: string;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* File download result
|
|
61
|
+
*/
|
|
62
|
+
export interface FileDownloadResult {
|
|
63
|
+
/** Whether download was intercepted */
|
|
64
|
+
success: boolean;
|
|
65
|
+
/** Downloaded file path */
|
|
66
|
+
path?: string;
|
|
67
|
+
/** File name */
|
|
68
|
+
fileName?: string;
|
|
69
|
+
/** File size in bytes */
|
|
70
|
+
size?: number;
|
|
71
|
+
/** Error message if failed */
|
|
72
|
+
error?: string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Advanced Interactions Handler
|
|
76
|
+
*
|
|
77
|
+
* Handles complex DOM interactions that go beyond simple element selection.
|
|
78
|
+
*/
|
|
79
|
+
export declare class AdvancedInteractionsHandler {
|
|
80
|
+
private page;
|
|
81
|
+
private options;
|
|
82
|
+
private shadowRootCache;
|
|
83
|
+
private frameCache;
|
|
84
|
+
constructor(page: Page, options?: AdvancedInteractionsOptions);
|
|
85
|
+
/**
|
|
86
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
87
|
+
* SHADOW DOM SUPPORT
|
|
88
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
89
|
+
*/
|
|
90
|
+
/**
|
|
91
|
+
* Find an element with automatic shadow DOM piercing
|
|
92
|
+
*
|
|
93
|
+
* Attempts to find an element in the main DOM first,
|
|
94
|
+
* then recursively searches through shadow DOM trees.
|
|
95
|
+
*
|
|
96
|
+
* @param selector - CSS selector to search for
|
|
97
|
+
* @param options - Search options
|
|
98
|
+
* @returns Element location with context
|
|
99
|
+
*/
|
|
100
|
+
findWithShadowPiercing(selector: string, options?: {
|
|
101
|
+
timeout?: number;
|
|
102
|
+
maxDepth?: number;
|
|
103
|
+
}): Promise<ElementLocation | null>;
|
|
104
|
+
/**
|
|
105
|
+
* Recursively search for element in shadow DOM
|
|
106
|
+
* Supports nested shadow DOM (shadow roots within shadow roots)
|
|
107
|
+
*/
|
|
108
|
+
private searchInShadowDom;
|
|
109
|
+
/**
|
|
110
|
+
* Build a Playwright-compatible selector for shadow DOM elements
|
|
111
|
+
*
|
|
112
|
+
* Playwright supports shadow DOM piercing with >> >>
|
|
113
|
+
*/
|
|
114
|
+
private buildShadowDomSelector;
|
|
115
|
+
/**
|
|
116
|
+
* Click an element with shadow DOM support
|
|
117
|
+
*/
|
|
118
|
+
clickWithShadowPiercing(selector: string): Promise<boolean>;
|
|
119
|
+
/**
|
|
120
|
+
* Fill an input with shadow DOM support
|
|
121
|
+
*/
|
|
122
|
+
fillWithShadowPiercing(selector: string, value: string): Promise<boolean>;
|
|
123
|
+
/**
|
|
124
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
125
|
+
* IFRAME HANDLING
|
|
126
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
127
|
+
*/
|
|
128
|
+
/**
|
|
129
|
+
* Find an element within iframes
|
|
130
|
+
*
|
|
131
|
+
* Searches through same-origin iframes recursively.
|
|
132
|
+
*
|
|
133
|
+
* @param selector - CSS selector to search for
|
|
134
|
+
* @param options - Search options
|
|
135
|
+
* @returns Element location with iframe context
|
|
136
|
+
*/
|
|
137
|
+
findInIframes(selector: string, options?: {
|
|
138
|
+
timeout?: number;
|
|
139
|
+
maxDepth?: number;
|
|
140
|
+
allowCrossOrigin?: boolean;
|
|
141
|
+
}): Promise<ElementLocation | null>;
|
|
142
|
+
/**
|
|
143
|
+
* Find element in same-origin iframes (faster, direct frame access)
|
|
144
|
+
*/
|
|
145
|
+
private findInSameOriginIframes;
|
|
146
|
+
/**
|
|
147
|
+
* Find element in cross-origin iframes using frameLocator
|
|
148
|
+
*
|
|
149
|
+
* For cross-origin iframes, we cannot use frame.waitForSelector() due to SOP.
|
|
150
|
+
* Instead, we use Playwright's frameLocator which handles cross-origin transparently.
|
|
151
|
+
*/
|
|
152
|
+
private findInCrossOriginIframes;
|
|
153
|
+
/**
|
|
154
|
+
* Recursively search nested iframes
|
|
155
|
+
*/
|
|
156
|
+
private findInNestedFrames;
|
|
157
|
+
/**
|
|
158
|
+
* Get the selector for a frame
|
|
159
|
+
*/
|
|
160
|
+
private getFrameSelector;
|
|
161
|
+
/**
|
|
162
|
+
* Get the selector for an iframe element
|
|
163
|
+
* Used for cross-origin iframe handling where we have an ElementHandle
|
|
164
|
+
*/
|
|
165
|
+
private getFrameSelectorForElement;
|
|
166
|
+
/**
|
|
167
|
+
* Check if two URLs are same-origin
|
|
168
|
+
*/
|
|
169
|
+
private isSameOrigin;
|
|
170
|
+
/**
|
|
171
|
+
* Interact with element in iframe
|
|
172
|
+
*
|
|
173
|
+
* @param iframeSelector - Selector for the iframe
|
|
174
|
+
* @param elementSelector - Selector for element within iframe
|
|
175
|
+
* @param action - Action to perform
|
|
176
|
+
* @returns Action result
|
|
177
|
+
*/
|
|
178
|
+
interactInIframe(iframeSelector: string, elementSelector: string, action: (frame: Frame) => Promise<any>): Promise<any>;
|
|
179
|
+
/**
|
|
180
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
181
|
+
* FILE OPERATIONS
|
|
182
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
183
|
+
*/
|
|
184
|
+
/**
|
|
185
|
+
* Upload files to an input element
|
|
186
|
+
*
|
|
187
|
+
* @param selector - File input selector
|
|
188
|
+
* @param filePaths - Paths to files to upload
|
|
189
|
+
* @returns Upload result
|
|
190
|
+
*/
|
|
191
|
+
uploadFiles(selector: string, filePaths: string | string[]): Promise<FileUploadResult>;
|
|
192
|
+
/**
|
|
193
|
+
* Upload files to an input in shadow DOM
|
|
194
|
+
*/
|
|
195
|
+
private uploadFilesInShadowDom;
|
|
196
|
+
/**
|
|
197
|
+
* Handle file download with interception
|
|
198
|
+
*
|
|
199
|
+
* @param triggerSelector - Selector for element that triggers download
|
|
200
|
+
* @param options - Download options
|
|
201
|
+
* @returns Download result
|
|
202
|
+
*/
|
|
203
|
+
handleDownload(triggerSelector: string, options?: {
|
|
204
|
+
action?: 'click' | 'submit';
|
|
205
|
+
timeout?: number;
|
|
206
|
+
savePath?: string;
|
|
207
|
+
}): Promise<FileDownloadResult>;
|
|
208
|
+
/**
|
|
209
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
210
|
+
* COMBINED SEARCH (Shadow DOM + Iframes)
|
|
211
|
+
* ═══════════════════════════════════════════════════════════════════════════════
|
|
212
|
+
*/
|
|
213
|
+
/**
|
|
214
|
+
* Find element anywhere (normal DOM, shadow DOM, or iframes)
|
|
215
|
+
*
|
|
216
|
+
* This is the main entry point for finding elements that may be
|
|
217
|
+
* hidden in shadow DOM or inside iframes.
|
|
218
|
+
*
|
|
219
|
+
* @param selector - CSS selector
|
|
220
|
+
* @param options - Search options
|
|
221
|
+
* @returns Element location or null
|
|
222
|
+
*/
|
|
223
|
+
findElementAnywhere(selector: string, options?: {
|
|
224
|
+
timeout?: number;
|
|
225
|
+
}): Promise<ElementLocation | null>;
|
|
226
|
+
/**
|
|
227
|
+
* P0: Handle print dialog (window.print())
|
|
228
|
+
*
|
|
229
|
+
* Uses CDP to automatically dismiss or capture print dialogs.
|
|
230
|
+
*
|
|
231
|
+
* @param options - Print handling options
|
|
232
|
+
* @returns Promise that resolves when print dialog is handled
|
|
233
|
+
*/
|
|
234
|
+
handlePrintDialog(options?: {
|
|
235
|
+
/** Action to take: 'dismiss' to cancel, 'capture' to generate PDF */
|
|
236
|
+
action?: 'dismiss' | 'capture';
|
|
237
|
+
/** Output path for PDF (when action is 'capture') */
|
|
238
|
+
path?: string;
|
|
239
|
+
}): Promise<{
|
|
240
|
+
handled: boolean;
|
|
241
|
+
pdfPath?: string;
|
|
242
|
+
}>;
|
|
243
|
+
/**
|
|
244
|
+
* P0: Hover over an element
|
|
245
|
+
*
|
|
246
|
+
* Triggers hover state and waits for any visual changes.
|
|
247
|
+
* Supports elements in shadow DOM and iframes.
|
|
248
|
+
*
|
|
249
|
+
* @param selector - CSS selector for the element
|
|
250
|
+
* @param options - Hover options
|
|
251
|
+
* @returns Hover result
|
|
252
|
+
*/
|
|
253
|
+
hover(options: {
|
|
254
|
+
/** CSS selector for the element */
|
|
255
|
+
selector: string;
|
|
256
|
+
/** Whether to wait for animations after hover (default: true) */
|
|
257
|
+
waitForAnimation?: boolean;
|
|
258
|
+
/** Animation wait time in ms (default: 100) */
|
|
259
|
+
animationWait?: number;
|
|
260
|
+
/** Force hover even if element is not visible */
|
|
261
|
+
force?: boolean;
|
|
262
|
+
}): Promise<{
|
|
263
|
+
success: boolean;
|
|
264
|
+
error?: string;
|
|
265
|
+
}>;
|
|
266
|
+
/**
|
|
267
|
+
* P0: Drag and drop operation
|
|
268
|
+
*
|
|
269
|
+
* Drags an element and drops it onto a target element.
|
|
270
|
+
* Supports elements in shadow DOM and iframes.
|
|
271
|
+
*
|
|
272
|
+
* @param options - Drag and drop options
|
|
273
|
+
* @returns Drag result
|
|
274
|
+
*/
|
|
275
|
+
dragAndDrop(options: {
|
|
276
|
+
/** CSS selector for the source element to drag */
|
|
277
|
+
from: string;
|
|
278
|
+
/** CSS selector for the target element to drop on */
|
|
279
|
+
to: string;
|
|
280
|
+
/** Drop position relative to target (default: 'center') */
|
|
281
|
+
position?: 'top' | 'right' | 'bottom' | 'left' | 'center';
|
|
282
|
+
/** Whether to verify the drop was successful */
|
|
283
|
+
verifyDrop?: boolean;
|
|
284
|
+
}): Promise<{
|
|
285
|
+
success: boolean;
|
|
286
|
+
error?: string;
|
|
287
|
+
}>;
|
|
288
|
+
/**
|
|
289
|
+
* P0: Drag element to specific coordinates
|
|
290
|
+
*
|
|
291
|
+
* Drags an element from its current position to specific x, y coordinates.
|
|
292
|
+
*
|
|
293
|
+
* @param options - Drag to coordinates options
|
|
294
|
+
* @returns Drag result
|
|
295
|
+
*/
|
|
296
|
+
dragToCoordinates(options: {
|
|
297
|
+
/** CSS selector for the element to drag */
|
|
298
|
+
selector: string;
|
|
299
|
+
/** Target X coordinate */
|
|
300
|
+
x: number;
|
|
301
|
+
/** Target Y coordinate */
|
|
302
|
+
y: number;
|
|
303
|
+
/** Starting X coordinate (default: element center) */
|
|
304
|
+
fromX?: number;
|
|
305
|
+
/** Starting Y coordinate (default: element center) */
|
|
306
|
+
fromY?: number;
|
|
307
|
+
/** Number of steps for smooth drag (default: 10) */
|
|
308
|
+
steps?: number;
|
|
309
|
+
}): Promise<{
|
|
310
|
+
success: boolean;
|
|
311
|
+
error?: string;
|
|
312
|
+
}>;
|
|
313
|
+
/**
|
|
314
|
+
* P0: Multi-select drag (select multiple elements)
|
|
315
|
+
*
|
|
316
|
+
* Performs Ctrl+Click on multiple elements to select them.
|
|
317
|
+
*
|
|
318
|
+
* @param selectors - Array of CSS selectors to select
|
|
319
|
+
* @returns Selection result
|
|
320
|
+
*/
|
|
321
|
+
multiSelect(selectors: string[]): Promise<{
|
|
322
|
+
success: boolean;
|
|
323
|
+
selected: number;
|
|
324
|
+
errors: string[];
|
|
325
|
+
}>;
|
|
326
|
+
/**
|
|
327
|
+
* Get position offset for drop position
|
|
328
|
+
*/
|
|
329
|
+
private getPositionForDrop;
|
|
330
|
+
/**
|
|
331
|
+
* Sleep utility for waiting
|
|
332
|
+
*/
|
|
333
|
+
private sleep;
|
|
334
|
+
/**
|
|
335
|
+
* Clear caches
|
|
336
|
+
*/
|
|
337
|
+
clearCache(): void;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Factory function to create handler
|
|
341
|
+
*/
|
|
342
|
+
export declare function createAdvancedInteractionsHandler(page: Page, options?: AdvancedInteractionsOptions): AdvancedInteractionsHandler;
|