qa360 2.3.0 → 2.3.2
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/ask.js +49 -22
- package/{cli/dist → dist}/commands/coverage.js +17 -4
- package/{cli/dist → dist}/commands/crawl.js +2 -2
- 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 +12 -5
- 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 +14 -6
- 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 +5 -1
- package/{cli/dist → dist}/commands/run.js +87 -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.d.ts +4 -0
- package/{cli/dist → dist}/core/ai/ollama-provider.js +41 -8
- 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}/index.js +2 -3
- package/{cli/dist → dist}/utils/config.d.ts +1 -1
- package/{cli/dist → dist}/utils/config.js +36 -3
- 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 -330
- 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 -105
- package/core/package.json +0 -90
- 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/coverage.d.ts +0 -0
- /package/{cli/dist → dist}/commands/crawl.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/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}/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
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QA360 Device Emulation Module
|
|
3
|
+
*
|
|
4
|
+
* P0: Mobile and tablet device emulation
|
|
5
|
+
* - Predefined device profiles
|
|
6
|
+
* - Viewport resizing
|
|
7
|
+
* - User agent emulation
|
|
8
|
+
* - Touch/Mouse interaction switching
|
|
9
|
+
* - Device pixel ratio handling
|
|
10
|
+
* - Orientation (portrait/landscape)
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Device Emulation Helper
|
|
14
|
+
*/
|
|
15
|
+
export class DeviceEmulator {
|
|
16
|
+
page;
|
|
17
|
+
static profiles = {
|
|
18
|
+
// Desktop profiles
|
|
19
|
+
'desktop-1920x1080': {
|
|
20
|
+
name: 'Desktop 1920x1080',
|
|
21
|
+
width: 1920,
|
|
22
|
+
height: 1080,
|
|
23
|
+
deviceScaleFactor: 1,
|
|
24
|
+
isMobile: false,
|
|
25
|
+
hasTouch: false,
|
|
26
|
+
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
27
|
+
category: 'desktop',
|
|
28
|
+
},
|
|
29
|
+
'desktop-1366x768': {
|
|
30
|
+
name: 'Desktop 1366x768',
|
|
31
|
+
width: 1366,
|
|
32
|
+
height: 768,
|
|
33
|
+
deviceScaleFactor: 1,
|
|
34
|
+
isMobile: false,
|
|
35
|
+
hasTouch: false,
|
|
36
|
+
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
37
|
+
category: 'desktop',
|
|
38
|
+
},
|
|
39
|
+
'macbook-16': {
|
|
40
|
+
name: 'MacBook Pro 16"',
|
|
41
|
+
width: 1536,
|
|
42
|
+
height: 960,
|
|
43
|
+
deviceScaleFactor: 2,
|
|
44
|
+
isMobile: false,
|
|
45
|
+
hasTouch: false,
|
|
46
|
+
userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
47
|
+
category: 'desktop',
|
|
48
|
+
},
|
|
49
|
+
// Tablet profiles
|
|
50
|
+
'ipad-pro': {
|
|
51
|
+
name: 'iPad Pro 12.9"',
|
|
52
|
+
width: 1024,
|
|
53
|
+
height: 1366,
|
|
54
|
+
deviceScaleFactor: 2,
|
|
55
|
+
isMobile: true,
|
|
56
|
+
hasTouch: true,
|
|
57
|
+
userAgent: 'Mozilla/5.0 (iPad; CPU OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1',
|
|
58
|
+
category: 'tablet',
|
|
59
|
+
},
|
|
60
|
+
'ipad': {
|
|
61
|
+
name: 'iPad',
|
|
62
|
+
width: 768,
|
|
63
|
+
height: 1024,
|
|
64
|
+
deviceScaleFactor: 2,
|
|
65
|
+
isMobile: true,
|
|
66
|
+
hasTouch: true,
|
|
67
|
+
userAgent: 'Mozilla/5.0 (iPad; CPU OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1',
|
|
68
|
+
category: 'tablet',
|
|
69
|
+
},
|
|
70
|
+
'ipad-mini': {
|
|
71
|
+
name: 'iPad Mini',
|
|
72
|
+
width: 768,
|
|
73
|
+
height: 1024,
|
|
74
|
+
deviceScaleFactor: 2,
|
|
75
|
+
isMobile: true,
|
|
76
|
+
hasTouch: true,
|
|
77
|
+
userAgent: 'Mozilla/5.0 (iPad; CPU OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1',
|
|
78
|
+
category: 'tablet',
|
|
79
|
+
},
|
|
80
|
+
'surface-pro': {
|
|
81
|
+
name: 'Surface Pro',
|
|
82
|
+
width: 912,
|
|
83
|
+
height: 1368,
|
|
84
|
+
deviceScaleFactor: 2,
|
|
85
|
+
isMobile: false,
|
|
86
|
+
hasTouch: true,
|
|
87
|
+
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
88
|
+
category: 'tablet',
|
|
89
|
+
},
|
|
90
|
+
// Mobile profiles
|
|
91
|
+
'iphone-15-pro-max': {
|
|
92
|
+
name: 'iPhone 15 Pro Max',
|
|
93
|
+
width: 430,
|
|
94
|
+
height: 932,
|
|
95
|
+
deviceScaleFactor: 3,
|
|
96
|
+
isMobile: true,
|
|
97
|
+
hasTouch: true,
|
|
98
|
+
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1',
|
|
99
|
+
category: 'mobile',
|
|
100
|
+
},
|
|
101
|
+
'iphone-15-pro': {
|
|
102
|
+
name: 'iPhone 15 Pro',
|
|
103
|
+
width: 393,
|
|
104
|
+
height: 852,
|
|
105
|
+
deviceScaleFactor: 3,
|
|
106
|
+
isMobile: true,
|
|
107
|
+
hasTouch: true,
|
|
108
|
+
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1',
|
|
109
|
+
category: 'mobile',
|
|
110
|
+
},
|
|
111
|
+
'iphone-se': {
|
|
112
|
+
name: 'iPhone SE',
|
|
113
|
+
width: 375,
|
|
114
|
+
height: 667,
|
|
115
|
+
deviceScaleFactor: 2,
|
|
116
|
+
isMobile: true,
|
|
117
|
+
hasTouch: true,
|
|
118
|
+
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1',
|
|
119
|
+
category: 'mobile',
|
|
120
|
+
},
|
|
121
|
+
'pixel-7-pro': {
|
|
122
|
+
name: 'Google Pixel 7 Pro',
|
|
123
|
+
width: 412,
|
|
124
|
+
height: 915,
|
|
125
|
+
deviceScaleFactor: 2.625,
|
|
126
|
+
isMobile: true,
|
|
127
|
+
hasTouch: true,
|
|
128
|
+
userAgent: 'Mozilla/5.0 (Linux; Android 14) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36',
|
|
129
|
+
category: 'mobile',
|
|
130
|
+
},
|
|
131
|
+
'samsung-s23': {
|
|
132
|
+
name: 'Samsung Galaxy S23',
|
|
133
|
+
width: 360,
|
|
134
|
+
height: 780,
|
|
135
|
+
deviceScaleFactor: 3,
|
|
136
|
+
isMobile: true,
|
|
137
|
+
hasTouch: true,
|
|
138
|
+
userAgent: 'Mozilla/5.0 (Linux; Android 14) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Mobile Safari/537.36',
|
|
139
|
+
category: 'mobile',
|
|
140
|
+
},
|
|
141
|
+
};
|
|
142
|
+
constructor(page) {
|
|
143
|
+
this.page = page;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get all available device profiles
|
|
147
|
+
*/
|
|
148
|
+
static getProfiles() {
|
|
149
|
+
return { ...DeviceEmulator.profiles };
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Get a specific device profile
|
|
153
|
+
*/
|
|
154
|
+
static getProfile(name) {
|
|
155
|
+
return DeviceEmulator.profiles[name];
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get all profiles by category
|
|
159
|
+
*/
|
|
160
|
+
static getProfilesByCategory(category) {
|
|
161
|
+
return Object.values(DeviceEmulator.profiles).filter((p) => p.category === category);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Emulate a device by name
|
|
165
|
+
*/
|
|
166
|
+
async emulate(device) {
|
|
167
|
+
const profile = DeviceEmulator.getProfile(device);
|
|
168
|
+
if (!profile) {
|
|
169
|
+
throw new Error(`Unknown device profile: ${device}`);
|
|
170
|
+
}
|
|
171
|
+
await this.emulateProfile(profile);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Emulate a device profile
|
|
175
|
+
*/
|
|
176
|
+
async emulateProfile(profile) {
|
|
177
|
+
const viewport = {
|
|
178
|
+
width: profile.width,
|
|
179
|
+
height: profile.height,
|
|
180
|
+
deviceScaleFactor: profile.deviceScaleFactor,
|
|
181
|
+
isMobile: profile.isMobile,
|
|
182
|
+
hasTouch: profile.hasTouch,
|
|
183
|
+
};
|
|
184
|
+
await this.page.setViewportSize(viewport);
|
|
185
|
+
await this.page.emulateMedia({ media: 'screen' });
|
|
186
|
+
// Set user agent via extra HTTP headers (works for new contexts)
|
|
187
|
+
// For page-level emulation, we need to use CDP or reload with new UA
|
|
188
|
+
const context = this.page.context();
|
|
189
|
+
await context.setExtraHTTPHeaders({
|
|
190
|
+
'User-Agent': profile.userAgent,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Set viewport size
|
|
195
|
+
*/
|
|
196
|
+
async setViewport(width, height, options = {}) {
|
|
197
|
+
const viewport = {
|
|
198
|
+
width,
|
|
199
|
+
height,
|
|
200
|
+
deviceScaleFactor: options.deviceScaleFactor ?? 1,
|
|
201
|
+
isMobile: options.isMobile ?? false,
|
|
202
|
+
hasTouch: options.hasTouch ?? false,
|
|
203
|
+
};
|
|
204
|
+
await this.page.setViewportSize(viewport);
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Set viewport to predefined dimensions
|
|
208
|
+
*/
|
|
209
|
+
async desktop() {
|
|
210
|
+
await this.setViewport(1920, 1080);
|
|
211
|
+
await this.page.emulateMedia({ media: 'screen' });
|
|
212
|
+
}
|
|
213
|
+
async tablet() {
|
|
214
|
+
await this.setViewport(768, 1024, { isMobile: false, hasTouch: true });
|
|
215
|
+
await this.page.emulateMedia({ media: 'screen' });
|
|
216
|
+
}
|
|
217
|
+
async mobile() {
|
|
218
|
+
await this.setViewport(375, 667, { isMobile: true, hasTouch: true, deviceScaleFactor: 2 });
|
|
219
|
+
await this.page.emulateMedia({ media: 'screen' });
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Set screen orientation
|
|
223
|
+
*/
|
|
224
|
+
async setOrientation(orientation) {
|
|
225
|
+
const current = this.page.viewportSize();
|
|
226
|
+
if (!current)
|
|
227
|
+
return;
|
|
228
|
+
if (orientation === 'landscape' && current.width < current.height) {
|
|
229
|
+
await this.setViewport(current.height, current.width);
|
|
230
|
+
}
|
|
231
|
+
else if (orientation === 'portrait' && current.width > current.height) {
|
|
232
|
+
await this.setViewport(current.height, current.width);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Rotate device (swap width and height)
|
|
237
|
+
*/
|
|
238
|
+
async rotate() {
|
|
239
|
+
const current = this.page.viewportSize();
|
|
240
|
+
if (!current)
|
|
241
|
+
return;
|
|
242
|
+
await this.setViewport(current.height, current.width);
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Set device pixel ratio
|
|
246
|
+
*/
|
|
247
|
+
async setDeviceScaleFactor(dpr) {
|
|
248
|
+
const current = this.page.viewportSize();
|
|
249
|
+
if (!current)
|
|
250
|
+
return;
|
|
251
|
+
// Note: deviceScaleFactor must be set via context, not page
|
|
252
|
+
// This is a simplified version - for full support, recreate context with new viewport
|
|
253
|
+
await this.page.setViewportSize({
|
|
254
|
+
width: current.width,
|
|
255
|
+
height: current.height,
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Enable/disable touch emulation
|
|
260
|
+
*/
|
|
261
|
+
async setTouch(enabled) {
|
|
262
|
+
const current = this.page.viewportSize();
|
|
263
|
+
if (!current)
|
|
264
|
+
return;
|
|
265
|
+
// Note: hasTouch must be set via context, not page
|
|
266
|
+
// This is a simplified version - for full support, recreate context with new viewport
|
|
267
|
+
await this.page.setViewportSize({
|
|
268
|
+
width: current.width,
|
|
269
|
+
height: current.height,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Get current viewport info
|
|
274
|
+
*/
|
|
275
|
+
async getViewport() {
|
|
276
|
+
return this.page.viewportSize();
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Test at multiple viewport sizes (responsive testing)
|
|
280
|
+
*/
|
|
281
|
+
async testAtSizes(sizes, testFn) {
|
|
282
|
+
const results = [];
|
|
283
|
+
for (const size of sizes) {
|
|
284
|
+
try {
|
|
285
|
+
await this.setViewport(size.width, size.height);
|
|
286
|
+
await testFn();
|
|
287
|
+
results.push({ size, passed: true });
|
|
288
|
+
}
|
|
289
|
+
catch (error) {
|
|
290
|
+
results.push({
|
|
291
|
+
size,
|
|
292
|
+
passed: false,
|
|
293
|
+
error: error,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return results;
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* Test at multiple breakpoints (common responsive sizes)
|
|
301
|
+
*/
|
|
302
|
+
async testResponsive(testFn) {
|
|
303
|
+
const breakpoints = [
|
|
304
|
+
{ name: 'mobile', width: 375, height: 667 },
|
|
305
|
+
{ name: 'tablet', width: 768, height: 1024 },
|
|
306
|
+
{ name: 'desktop', width: 1920, height: 1080 },
|
|
307
|
+
];
|
|
308
|
+
const results = [];
|
|
309
|
+
for (const bp of breakpoints) {
|
|
310
|
+
try {
|
|
311
|
+
await this.setViewport(bp.width, bp.height);
|
|
312
|
+
await testFn();
|
|
313
|
+
results.push({ breakpoint: bp.name, passed: true });
|
|
314
|
+
}
|
|
315
|
+
catch (error) {
|
|
316
|
+
results.push({
|
|
317
|
+
breakpoint: bp.name,
|
|
318
|
+
passed: false,
|
|
319
|
+
error: error,
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return results;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Test on multiple device profiles
|
|
327
|
+
*/
|
|
328
|
+
async testOnDevices(devices, testFn) {
|
|
329
|
+
const results = [];
|
|
330
|
+
for (const device of devices) {
|
|
331
|
+
try {
|
|
332
|
+
await this.emulate(device);
|
|
333
|
+
await testFn();
|
|
334
|
+
results.push({ device, passed: true });
|
|
335
|
+
}
|
|
336
|
+
catch (error) {
|
|
337
|
+
results.push({
|
|
338
|
+
device,
|
|
339
|
+
passed: false,
|
|
340
|
+
error: error,
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
return results;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Convenience function to create device emulator
|
|
349
|
+
*/
|
|
350
|
+
export function device(page) {
|
|
351
|
+
return new DeviceEmulator(page);
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Common viewport presets
|
|
355
|
+
*/
|
|
356
|
+
export const Viewport = {
|
|
357
|
+
// Desktop
|
|
358
|
+
'desktop-xl': { width: 2560, height: 1440 },
|
|
359
|
+
'desktop-lg': { width: 1920, height: 1080 },
|
|
360
|
+
'desktop-md': { width: 1366, height: 768 },
|
|
361
|
+
'desktop-sm': { width: 1024, height: 768 },
|
|
362
|
+
// Tablet
|
|
363
|
+
'tablet-lg': { width: 1024, height: 1366 },
|
|
364
|
+
'tablet-md': { width: 768, height: 1024 },
|
|
365
|
+
'tablet-sm': { width: 600, height: 960 },
|
|
366
|
+
// Mobile
|
|
367
|
+
'mobile-lg': { width: 428, height: 926 },
|
|
368
|
+
'mobile-md': { width: 390, height: 844 },
|
|
369
|
+
'mobile-sm': { width: 375, height: 667 },
|
|
370
|
+
'mobile-xs': { width: 320, height: 568 },
|
|
371
|
+
};
|
|
372
|
+
/**
|
|
373
|
+
* Common device lists
|
|
374
|
+
*/
|
|
375
|
+
export const Devices = {
|
|
376
|
+
desktop: ['desktop-1920x1080', 'desktop-1366x768', 'macbook-16'],
|
|
377
|
+
tablet: ['ipad-pro', 'ipad', 'ipad-mini', 'surface-pro'],
|
|
378
|
+
mobile: ['iphone-15-pro-max', 'iphone-15-pro', 'iphone-se', 'pixel-7-pro', 'samsung-s23'],
|
|
379
|
+
popular: ['desktop-1920x1080', 'ipad', 'iphone-15-pro', 'pixel-7-pro'],
|
|
380
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QA360 Utility Modules
|
|
3
|
+
*
|
|
4
|
+
* P0: Helper utilities for testing
|
|
5
|
+
*/
|
|
6
|
+
export { Retry, retry, RetryIf, RetryConfig, RetryError, type RetryOptions, type RetryResult, } from './retry.js';
|
|
7
|
+
export { SmartWait, smartWait, waitForVisible, waitForHidden, waitForText, type SmartWaitOptions, type ElementState, type StabilityResult, } from './smart-wait.js';
|
|
8
|
+
export { DeviceEmulator, device, Viewport, Devices, type ViewportConfig, type DeviceProfile, type Orientation, } from './device-emulation.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QA360 Utility Modules
|
|
3
|
+
*
|
|
4
|
+
* P0: Helper utilities for testing
|
|
5
|
+
*/
|
|
6
|
+
export { Retry, retry, RetryIf, RetryConfig, RetryError, } from './retry.js';
|
|
7
|
+
export { SmartWait, smartWait, waitForVisible, waitForHidden, waitForText, } from './smart-wait.js';
|
|
8
|
+
export { DeviceEmulator, device, Viewport, Devices, } from './device-emulation.js';
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* QA360 Retry Module
|
|
3
|
+
*
|
|
4
|
+
* P0: Auto-retry logic for failed actions
|
|
5
|
+
* - Configurable retry attempts and delays
|
|
6
|
+
* - Exponential backoff support
|
|
7
|
+
* - Jitter for avoiding thundering herd
|
|
8
|
+
* - Retry condition predicates
|
|
9
|
+
* - Timeout support
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Retry options
|
|
13
|
+
*/
|
|
14
|
+
export interface RetryOptions {
|
|
15
|
+
/** Maximum number of retry attempts (default: 3) */
|
|
16
|
+
maxAttempts?: number;
|
|
17
|
+
/** Initial delay between retries in ms (default: 1000) */
|
|
18
|
+
delay?: number;
|
|
19
|
+
/** Multiplier for exponential backoff (default: 2) */
|
|
20
|
+
backoffMultiplier?: number;
|
|
21
|
+
/** Maximum delay between retries in ms (default: 30000) */
|
|
22
|
+
maxDelay?: number;
|
|
23
|
+
/** Whether to add jitter to delay (default: true) */
|
|
24
|
+
jitter?: boolean;
|
|
25
|
+
/** Function to determine if error is retryable (default: retry all errors) */
|
|
26
|
+
retryIf?: (error: unknown) => boolean;
|
|
27
|
+
/** Function to call before each retry */
|
|
28
|
+
onRetry?: (error: unknown, attempt: number) => void | Promise<void>;
|
|
29
|
+
/** Overall timeout in ms (default: no timeout) */
|
|
30
|
+
timeout?: number;
|
|
31
|
+
/** Whether to throw last error or aggregate (default: throw last) */
|
|
32
|
+
throwLast?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Retry result
|
|
36
|
+
*/
|
|
37
|
+
export interface RetryResult<T> {
|
|
38
|
+
/** Whether the operation succeeded */
|
|
39
|
+
success: boolean;
|
|
40
|
+
/** The result value if successful */
|
|
41
|
+
value?: T;
|
|
42
|
+
/** The error if failed */
|
|
43
|
+
error?: Error;
|
|
44
|
+
/** Number of attempts made */
|
|
45
|
+
attempts: number;
|
|
46
|
+
/** Total time elapsed in ms */
|
|
47
|
+
elapsed: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Aggregate error from multiple retry attempts
|
|
51
|
+
*/
|
|
52
|
+
export declare class RetryError extends Error {
|
|
53
|
+
errors: Error[];
|
|
54
|
+
constructor(errors: Error[], message?: string);
|
|
55
|
+
/**
|
|
56
|
+
* Get all error messages
|
|
57
|
+
*/
|
|
58
|
+
get messages(): string[];
|
|
59
|
+
/**
|
|
60
|
+
* Get formatted error summary
|
|
61
|
+
*/
|
|
62
|
+
get summary(): string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Retry Helper
|
|
66
|
+
*/
|
|
67
|
+
export declare class Retry {
|
|
68
|
+
/**
|
|
69
|
+
* Retry an async function with configurable options
|
|
70
|
+
*/
|
|
71
|
+
static try<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
72
|
+
/**
|
|
73
|
+
* Retry with result returned
|
|
74
|
+
*/
|
|
75
|
+
static withResult<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<RetryResult<T>>;
|
|
76
|
+
/**
|
|
77
|
+
* Retry until a condition is met
|
|
78
|
+
*/
|
|
79
|
+
static until(condition: () => boolean | Promise<boolean>, options?: RetryOptions): Promise<void>;
|
|
80
|
+
/**
|
|
81
|
+
* Retry while a condition is true
|
|
82
|
+
*/
|
|
83
|
+
static while(condition: () => boolean | Promise<boolean>, fn: () => Promise<void>, options?: RetryOptions): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Add jitter to delay (±25%)
|
|
86
|
+
*/
|
|
87
|
+
private static addJitter;
|
|
88
|
+
/**
|
|
89
|
+
* Sleep utility
|
|
90
|
+
*/
|
|
91
|
+
private static sleep;
|
|
92
|
+
/**
|
|
93
|
+
* Add timeout to a promise
|
|
94
|
+
*/
|
|
95
|
+
private static withTimeout;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Convenience function for retry
|
|
99
|
+
*/
|
|
100
|
+
export declare function retry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
101
|
+
/**
|
|
102
|
+
* Common retry predicates
|
|
103
|
+
*/
|
|
104
|
+
export declare const RetryIf: {
|
|
105
|
+
/** Retry on network errors */
|
|
106
|
+
networkError: (error: unknown) => boolean;
|
|
107
|
+
/** Retry on 5xx errors */
|
|
108
|
+
serverError: (error: unknown) => boolean;
|
|
109
|
+
/** Retry on specific error messages */
|
|
110
|
+
message: (...messages: string[]) => (error: unknown) => boolean;
|
|
111
|
+
/** Retry on specific error types */
|
|
112
|
+
errorType: (...types: Array<new (...args: unknown[]) => Error>) => (error: unknown) => boolean;
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Common retry configurations
|
|
116
|
+
*/
|
|
117
|
+
export declare const RetryConfig: {
|
|
118
|
+
/** Quick retries for transient failures */
|
|
119
|
+
quick: {
|
|
120
|
+
maxAttempts: number;
|
|
121
|
+
delay: number;
|
|
122
|
+
backoffMultiplier: number;
|
|
123
|
+
};
|
|
124
|
+
/** Standard retries */
|
|
125
|
+
standard: {
|
|
126
|
+
maxAttempts: number;
|
|
127
|
+
delay: number;
|
|
128
|
+
backoffMultiplier: number;
|
|
129
|
+
};
|
|
130
|
+
/** Persistent retries for resilient operations */
|
|
131
|
+
persistent: {
|
|
132
|
+
maxAttempts: number;
|
|
133
|
+
delay: number;
|
|
134
|
+
backoffMultiplier: number;
|
|
135
|
+
maxDelay: number;
|
|
136
|
+
};
|
|
137
|
+
/** Network retries with exponential backoff */
|
|
138
|
+
network: {
|
|
139
|
+
maxAttempts: number;
|
|
140
|
+
delay: number;
|
|
141
|
+
backoffMultiplier: number;
|
|
142
|
+
maxDelay: number;
|
|
143
|
+
retryIf: (error: unknown) => boolean;
|
|
144
|
+
};
|
|
145
|
+
};
|