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
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OAuth2 Authentication Provider
|
|
3
|
-
*
|
|
4
|
-
* Handles OAuth2 authentication with support for:
|
|
5
|
-
* - Client credentials grant
|
|
6
|
-
* - Password grant (resource owner)
|
|
7
|
-
* - Authorization code grant (requires pre-issued code)
|
|
8
|
-
*/
|
|
9
|
-
import { authCache, createCacheKey } from './index.js';
|
|
10
|
-
export class OAuth2Provider {
|
|
11
|
-
type = 'oauth2';
|
|
12
|
-
async authenticate(config) {
|
|
13
|
-
const cacheKey = this.getCacheKey(config);
|
|
14
|
-
// Check cache first
|
|
15
|
-
if (config.cache?.enabled !== false) {
|
|
16
|
-
const cached = authCache.get(cacheKey);
|
|
17
|
-
if (cached) {
|
|
18
|
-
return { success: true, credentials: cached };
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
// Prepare token request based on grant type
|
|
22
|
-
const grantType = config.grant_type || 'client_credentials';
|
|
23
|
-
const body = {
|
|
24
|
-
grant_type: grantType,
|
|
25
|
-
client_id: config.client_id,
|
|
26
|
-
};
|
|
27
|
-
// Add client secret for most grants (except some implicit flows)
|
|
28
|
-
if (config.client_secret) {
|
|
29
|
-
body.client_secret = config.client_secret;
|
|
30
|
-
}
|
|
31
|
-
// Grant-specific parameters
|
|
32
|
-
if (grantType === 'password') {
|
|
33
|
-
if (!config.username || !config.password) {
|
|
34
|
-
return {
|
|
35
|
-
success: false,
|
|
36
|
-
error: 'Username and password required for password grant'
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
body.username = config.username;
|
|
40
|
-
body.password = config.password;
|
|
41
|
-
}
|
|
42
|
-
if (config.scopes && config.scopes.length > 0) {
|
|
43
|
-
body.scope = config.scopes.join(' ');
|
|
44
|
-
}
|
|
45
|
-
try {
|
|
46
|
-
const response = await fetch(config.token_url, {
|
|
47
|
-
method: 'POST',
|
|
48
|
-
headers: {
|
|
49
|
-
'Content-Type': 'application/x-www-form-urlencoded',
|
|
50
|
-
},
|
|
51
|
-
body: new URLSearchParams(body).toString(),
|
|
52
|
-
});
|
|
53
|
-
if (!response.ok) {
|
|
54
|
-
const error = await response.text().catch(() => 'Unknown error');
|
|
55
|
-
return {
|
|
56
|
-
success: false,
|
|
57
|
-
error: `OAuth2 token request failed: ${response.status} ${error}`
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
const data = await response.json();
|
|
61
|
-
const token = data.access_token;
|
|
62
|
-
if (!token) {
|
|
63
|
-
return {
|
|
64
|
-
success: false,
|
|
65
|
-
error: 'No access_token in OAuth2 response'
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
const credentials = {
|
|
69
|
-
type: 'oauth2',
|
|
70
|
-
headers: {
|
|
71
|
-
'Authorization': `Bearer ${token}`
|
|
72
|
-
}
|
|
73
|
-
};
|
|
74
|
-
// Calculate expiration
|
|
75
|
-
let expiresAt;
|
|
76
|
-
if (data.expires_in) {
|
|
77
|
-
expiresAt = Date.now() + data.expires_in * 1000;
|
|
78
|
-
}
|
|
79
|
-
// Cache if enabled
|
|
80
|
-
if (config.cache?.enabled !== false) {
|
|
81
|
-
const ttl = config.cache?.ttl || data.expires_in || 3600;
|
|
82
|
-
authCache.set(cacheKey, credentials, ttl);
|
|
83
|
-
}
|
|
84
|
-
return {
|
|
85
|
-
success: true,
|
|
86
|
-
credentials,
|
|
87
|
-
expiresAt
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
catch (error) {
|
|
91
|
-
return {
|
|
92
|
-
success: false,
|
|
93
|
-
error: `OAuth2 request failed: ${error.message}`
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
async refresh(config) {
|
|
98
|
-
// For OAuth2, refresh is typically the same as authenticate
|
|
99
|
-
// unless we have a refresh token (which we don't store currently)
|
|
100
|
-
return this.authenticate(config);
|
|
101
|
-
}
|
|
102
|
-
clear(config) {
|
|
103
|
-
const key = this.getCacheKey(config);
|
|
104
|
-
authCache.clear(key);
|
|
105
|
-
return Promise.resolve();
|
|
106
|
-
}
|
|
107
|
-
async validate(config) {
|
|
108
|
-
const key = this.getCacheKey(config);
|
|
109
|
-
return authCache.has(key);
|
|
110
|
-
}
|
|
111
|
-
getCacheKey(config) {
|
|
112
|
-
return createCacheKey('oauth2', config.client_id);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Coverage Analyzer
|
|
3
|
-
*
|
|
4
|
-
* Analyzes coverage data to provide insights, trends, and recommendations.
|
|
5
|
-
*/
|
|
6
|
-
import type { FileCoverage, CoverageMetrics, CoverageResult, CoverageTrend, CoverageGap, CoverageComparison, CoverageThreshold, CoverageType, CoverageReport } from './types.js';
|
|
7
|
-
/**
|
|
8
|
-
* Historical coverage data point
|
|
9
|
-
*/
|
|
10
|
-
interface HistoricalCoverage {
|
|
11
|
-
runId: string;
|
|
12
|
-
timestamp: number;
|
|
13
|
-
metrics: CoverageMetrics;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Coverage Analyzer class
|
|
17
|
-
*/
|
|
18
|
-
export declare class CoverageAnalyzer {
|
|
19
|
-
private history;
|
|
20
|
-
/**
|
|
21
|
-
* Analyze coverage and generate insights
|
|
22
|
-
*/
|
|
23
|
-
analyze(result: CoverageResult, threshold?: CoverageThreshold): CoverageReport;
|
|
24
|
-
/**
|
|
25
|
-
* Check if coverage meets thresholds
|
|
26
|
-
*/
|
|
27
|
-
checkThresholds(metrics: CoverageMetrics, threshold?: CoverageThreshold): boolean;
|
|
28
|
-
/**
|
|
29
|
-
* Check if a single file meets thresholds
|
|
30
|
-
*/
|
|
31
|
-
checkFileThresholds(file: FileCoverage, threshold?: CoverageThreshold): boolean;
|
|
32
|
-
/**
|
|
33
|
-
* Find coverage gaps
|
|
34
|
-
*/
|
|
35
|
-
findGaps(files: Record<string, FileCoverage>, threshold?: CoverageThreshold): CoverageGap[];
|
|
36
|
-
/**
|
|
37
|
-
* Calculate priority for covering a file
|
|
38
|
-
*/
|
|
39
|
-
private calculatePriority;
|
|
40
|
-
/**
|
|
41
|
-
* Estimate effort to cover a file
|
|
42
|
-
*/
|
|
43
|
-
private estimateEffort;
|
|
44
|
-
/**
|
|
45
|
-
* Generate test suggestions for a file
|
|
46
|
-
*/
|
|
47
|
-
private generateSuggestions;
|
|
48
|
-
/**
|
|
49
|
-
* Group consecutive numbers into ranges
|
|
50
|
-
*/
|
|
51
|
-
private groupConsecutiveNumbers;
|
|
52
|
-
/**
|
|
53
|
-
* Get top and bottom files by coverage
|
|
54
|
-
*/
|
|
55
|
-
getTopFiles(files: Record<string, FileCoverage>, limit?: number): Array<{
|
|
56
|
-
path: string;
|
|
57
|
-
coverage: number;
|
|
58
|
-
type: 'best' | 'worst';
|
|
59
|
-
}>;
|
|
60
|
-
/**
|
|
61
|
-
* Compare two coverage results
|
|
62
|
-
*/
|
|
63
|
-
compare(baseResult: CoverageResult, compareResult: CoverageResult): CoverageComparison;
|
|
64
|
-
/**
|
|
65
|
-
* Add historical coverage data
|
|
66
|
-
*/
|
|
67
|
-
addHistory(key: string, data: HistoricalCoverage): void;
|
|
68
|
-
/**
|
|
69
|
-
* Get coverage trends
|
|
70
|
-
*/
|
|
71
|
-
getTrends(key: string, type?: CoverageType, limit?: number): CoverageTrend[];
|
|
72
|
-
/**
|
|
73
|
-
* Calculate trend direction
|
|
74
|
-
*/
|
|
75
|
-
getTrendDirection(trends: CoverageTrend[]): 'improving' | 'stable' | 'declining';
|
|
76
|
-
/**
|
|
77
|
-
* Predict future coverage based on trends
|
|
78
|
-
*/
|
|
79
|
-
predictCoverage(key: string, type: CoverageType | undefined, targetCoverage: number): {
|
|
80
|
-
predictedReach: number | null;
|
|
81
|
-
projectedCoverage: number;
|
|
82
|
-
confidence: 'high' | 'medium' | 'low';
|
|
83
|
-
};
|
|
84
|
-
/**
|
|
85
|
-
* Generate coverage summary text
|
|
86
|
-
*/
|
|
87
|
-
generateSummary(metrics: CoverageMetrics): string;
|
|
88
|
-
/**
|
|
89
|
-
* Format coverage percentage with color indicator
|
|
90
|
-
*/
|
|
91
|
-
formatCoverage(percentage: number, threshold?: number): string;
|
|
92
|
-
/**
|
|
93
|
-
* Clear history
|
|
94
|
-
*/
|
|
95
|
-
clearHistory(key?: string): void;
|
|
96
|
-
}
|
|
97
|
-
/**
|
|
98
|
-
* Create a coverage analyzer
|
|
99
|
-
*/
|
|
100
|
-
export declare function createCoverageAnalyzer(): CoverageAnalyzer;
|
|
101
|
-
export {};
|
|
@@ -1,415 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Coverage Analyzer
|
|
3
|
-
*
|
|
4
|
-
* Analyzes coverage data to provide insights, trends, and recommendations.
|
|
5
|
-
*/
|
|
6
|
-
/**
|
|
7
|
-
* Coverage Analyzer class
|
|
8
|
-
*/
|
|
9
|
-
export class CoverageAnalyzer {
|
|
10
|
-
history = new Map();
|
|
11
|
-
/**
|
|
12
|
-
* Analyze coverage and generate insights
|
|
13
|
-
*/
|
|
14
|
-
analyze(result, threshold) {
|
|
15
|
-
const thresholdsMet = this.checkThresholds(result.metrics, threshold);
|
|
16
|
-
const gaps = this.findGaps(result.files, threshold);
|
|
17
|
-
const topFiles = this.getTopFiles(result.files);
|
|
18
|
-
return {
|
|
19
|
-
runId: `run_${Date.now()}`,
|
|
20
|
-
timestamp: Date.now(),
|
|
21
|
-
metrics: result.metrics,
|
|
22
|
-
byGate: { [result.gate]: result.metrics },
|
|
23
|
-
topFiles,
|
|
24
|
-
gaps: gaps.slice(0, 10), // Top 10 gaps
|
|
25
|
-
thresholdsMet,
|
|
26
|
-
thresholdViolations: gaps.map(g => g.path)
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Check if coverage meets thresholds
|
|
31
|
-
*/
|
|
32
|
-
checkThresholds(metrics, threshold) {
|
|
33
|
-
if (!threshold) {
|
|
34
|
-
return true;
|
|
35
|
-
}
|
|
36
|
-
if (threshold.scope === 'per-file') {
|
|
37
|
-
// Per-file thresholds checked separately
|
|
38
|
-
return true;
|
|
39
|
-
}
|
|
40
|
-
if (threshold.line !== undefined && metrics.lineCoverage < threshold.line) {
|
|
41
|
-
return false;
|
|
42
|
-
}
|
|
43
|
-
if (threshold.branch !== undefined && metrics.branchCoverage < threshold.branch) {
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
if (threshold.function !== undefined && metrics.functionCoverage < threshold.function) {
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
49
|
-
if (threshold.statement !== undefined && metrics.statementCoverage < threshold.statement) {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
return true;
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Check if a single file meets thresholds
|
|
56
|
-
*/
|
|
57
|
-
checkFileThresholds(file, threshold) {
|
|
58
|
-
if (!threshold) {
|
|
59
|
-
return true;
|
|
60
|
-
}
|
|
61
|
-
if (threshold.line !== undefined && file.lineCoverage < threshold.line) {
|
|
62
|
-
return false;
|
|
63
|
-
}
|
|
64
|
-
if (threshold.branch !== undefined && file.branchCoverage < threshold.branch) {
|
|
65
|
-
return false;
|
|
66
|
-
}
|
|
67
|
-
if (threshold.function !== undefined && file.functionCoverage < threshold.function) {
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
if (threshold.statement !== undefined && file.statementCoverage < threshold.statement) {
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
return true;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Find coverage gaps
|
|
77
|
-
*/
|
|
78
|
-
findGaps(files, threshold) {
|
|
79
|
-
const gaps = [];
|
|
80
|
-
const targetLine = threshold?.line ?? 80;
|
|
81
|
-
const targetBranch = threshold?.branch ?? 70;
|
|
82
|
-
const targetFunction = threshold?.function ?? 75;
|
|
83
|
-
for (const [path, file] of Object.entries(files)) {
|
|
84
|
-
const minTarget = Math.min(targetLine, targetBranch, targetFunction);
|
|
85
|
-
const avgCoverage = (file.lineCoverage + file.branchCoverage + file.functionCoverage) / 3;
|
|
86
|
-
if (avgCoverage < minTarget) {
|
|
87
|
-
gaps.push({
|
|
88
|
-
path,
|
|
89
|
-
currentCoverage: avgCoverage,
|
|
90
|
-
targetCoverage: minTarget,
|
|
91
|
-
gap: minTarget - avgCoverage,
|
|
92
|
-
priority: this.calculatePriority(file, minTarget),
|
|
93
|
-
effort: this.estimateEffort(file),
|
|
94
|
-
uncoveredCount: file.uncoveredLines.length,
|
|
95
|
-
suggestions: this.generateSuggestions(file)
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
// Sort by gap size, then priority
|
|
100
|
-
gaps.sort((a, b) => {
|
|
101
|
-
if (a.priority !== b.priority) {
|
|
102
|
-
const priorityOrder = { high: 0, medium: 1, low: 2 };
|
|
103
|
-
return priorityOrder[a.priority] - priorityOrder[b.priority];
|
|
104
|
-
}
|
|
105
|
-
return b.gap - a.gap;
|
|
106
|
-
});
|
|
107
|
-
return gaps;
|
|
108
|
-
}
|
|
109
|
-
/**
|
|
110
|
-
* Calculate priority for covering a file
|
|
111
|
-
*/
|
|
112
|
-
calculatePriority(file, target) {
|
|
113
|
-
const gap = target - file.lineCoverage;
|
|
114
|
-
// High priority: large gap in important files
|
|
115
|
-
if (gap > 30) {
|
|
116
|
-
return 'high';
|
|
117
|
-
}
|
|
118
|
-
// Medium priority: moderate gap
|
|
119
|
-
if (gap > 10) {
|
|
120
|
-
return 'medium';
|
|
121
|
-
}
|
|
122
|
-
return 'low';
|
|
123
|
-
}
|
|
124
|
-
/**
|
|
125
|
-
* Estimate effort to cover a file
|
|
126
|
-
*/
|
|
127
|
-
estimateEffort(file) {
|
|
128
|
-
const complexity = file.totalBranches + file.totalFunctions;
|
|
129
|
-
const uncoveredRatio = file.uncoveredLines.length / Math.max(file.totalLines, 1);
|
|
130
|
-
if (complexity > 100 || uncoveredRatio > 0.5) {
|
|
131
|
-
return 'high';
|
|
132
|
-
}
|
|
133
|
-
if (complexity > 30 || uncoveredRatio > 0.2) {
|
|
134
|
-
return 'medium';
|
|
135
|
-
}
|
|
136
|
-
return 'low';
|
|
137
|
-
}
|
|
138
|
-
/**
|
|
139
|
-
* Generate test suggestions for a file
|
|
140
|
-
*/
|
|
141
|
-
generateSuggestions(file) {
|
|
142
|
-
const suggestions = [];
|
|
143
|
-
if (file.uncoveredLines.length > 0) {
|
|
144
|
-
const lineRanges = this.groupConsecutiveNumbers(file.uncoveredLines);
|
|
145
|
-
suggestions.push(`Add tests covering lines: ${lineRanges.slice(0, 3).join(', ')}`);
|
|
146
|
-
}
|
|
147
|
-
if (file.branchCoverage < file.lineCoverage) {
|
|
148
|
-
suggestions.push('Add tests for all branch conditions (true/false paths)');
|
|
149
|
-
}
|
|
150
|
-
if (file.functionCoverage < 100) {
|
|
151
|
-
suggestions.push('Add tests for uncovered functions');
|
|
152
|
-
}
|
|
153
|
-
if (file.totalFunctions === 0) {
|
|
154
|
-
suggestions.push('Consider splitting large functions into smaller, testable units');
|
|
155
|
-
}
|
|
156
|
-
return suggestions;
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Group consecutive numbers into ranges
|
|
160
|
-
*/
|
|
161
|
-
groupConsecutiveNumbers(numbers) {
|
|
162
|
-
if (numbers.length === 0)
|
|
163
|
-
return [];
|
|
164
|
-
const sorted = [...numbers].sort((a, b) => a - b);
|
|
165
|
-
const ranges = [];
|
|
166
|
-
let start = sorted[0];
|
|
167
|
-
let prev = sorted[0];
|
|
168
|
-
for (let i = 1; i < sorted.length; i++) {
|
|
169
|
-
if (sorted[i] === prev + 1) {
|
|
170
|
-
prev = sorted[i];
|
|
171
|
-
}
|
|
172
|
-
else {
|
|
173
|
-
ranges.push(start === prev ? `${start}` : `${start}-${prev}`);
|
|
174
|
-
start = sorted[i];
|
|
175
|
-
prev = sorted[i];
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
ranges.push(start === prev ? `${start}` : `${start}-${prev}`);
|
|
179
|
-
return ranges;
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Get top and bottom files by coverage
|
|
183
|
-
*/
|
|
184
|
-
getTopFiles(files, limit = 5) {
|
|
185
|
-
const fileArray = Object.entries(files).map(([path, file]) => ({
|
|
186
|
-
path,
|
|
187
|
-
coverage: file.lineCoverage,
|
|
188
|
-
type: 'best'
|
|
189
|
-
}));
|
|
190
|
-
// Sort by coverage
|
|
191
|
-
fileArray.sort((a, b) => b.coverage - a.coverage);
|
|
192
|
-
const result = [];
|
|
193
|
-
// Best files
|
|
194
|
-
for (let i = 0; i < Math.min(limit, fileArray.length); i++) {
|
|
195
|
-
result.push({ ...fileArray[i], type: 'best' });
|
|
196
|
-
}
|
|
197
|
-
// Worst files
|
|
198
|
-
for (let i = fileArray.length - 1; i >= Math.max(fileArray.length - limit, 0); i--) {
|
|
199
|
-
result.push({ path: fileArray[i].path, coverage: fileArray[i].coverage, type: 'worst' });
|
|
200
|
-
}
|
|
201
|
-
return result;
|
|
202
|
-
}
|
|
203
|
-
/**
|
|
204
|
-
* Compare two coverage results
|
|
205
|
-
*/
|
|
206
|
-
compare(baseResult, compareResult) {
|
|
207
|
-
const baseFiles = baseResult.files;
|
|
208
|
-
const compareFiles = compareResult.files;
|
|
209
|
-
const improved = [];
|
|
210
|
-
const regressed = [];
|
|
211
|
-
const newFiles = [];
|
|
212
|
-
const removedFiles = [];
|
|
213
|
-
// Check all files in base
|
|
214
|
-
for (const [path, baseFile] of Object.entries(baseFiles)) {
|
|
215
|
-
const compareFile = compareFiles[path];
|
|
216
|
-
if (!compareFile) {
|
|
217
|
-
removedFiles.push(path);
|
|
218
|
-
continue;
|
|
219
|
-
}
|
|
220
|
-
const delta = compareFile.lineCoverage - baseFile.lineCoverage;
|
|
221
|
-
if (delta > 0.5) {
|
|
222
|
-
improved.push({
|
|
223
|
-
path,
|
|
224
|
-
before: baseFile.lineCoverage,
|
|
225
|
-
after: compareFile.lineCoverage,
|
|
226
|
-
delta
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
else if (delta < -0.5) {
|
|
230
|
-
regressed.push({
|
|
231
|
-
path,
|
|
232
|
-
before: baseFile.lineCoverage,
|
|
233
|
-
after: compareFile.lineCoverage,
|
|
234
|
-
delta
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
// Find new files
|
|
239
|
-
for (const path of Object.keys(compareFiles)) {
|
|
240
|
-
if (!baseFiles[path]) {
|
|
241
|
-
newFiles.push(path);
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
// Calculate overall change
|
|
245
|
-
const overallChange = compareResult.metrics.lineCoverage - baseResult.metrics.lineCoverage;
|
|
246
|
-
return {
|
|
247
|
-
baseRunId: `base_${baseResult.timestamp}`,
|
|
248
|
-
compareRunId: `compare_${compareResult.timestamp}`,
|
|
249
|
-
improved,
|
|
250
|
-
regressed,
|
|
251
|
-
newFiles,
|
|
252
|
-
removedFiles,
|
|
253
|
-
overallChange
|
|
254
|
-
};
|
|
255
|
-
}
|
|
256
|
-
/**
|
|
257
|
-
* Add historical coverage data
|
|
258
|
-
*/
|
|
259
|
-
addHistory(key, data) {
|
|
260
|
-
if (!this.history.has(key)) {
|
|
261
|
-
this.history.set(key, []);
|
|
262
|
-
}
|
|
263
|
-
const history = this.history.get(key);
|
|
264
|
-
history.push(data);
|
|
265
|
-
// Keep only last 100 entries
|
|
266
|
-
if (history.length > 100) {
|
|
267
|
-
history.shift();
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Get coverage trends
|
|
272
|
-
*/
|
|
273
|
-
getTrends(key, type = 'line', limit = 30) {
|
|
274
|
-
const history = this.history.get(key) || [];
|
|
275
|
-
const sorted = history
|
|
276
|
-
.sort((a, b) => a.timestamp - b.timestamp)
|
|
277
|
-
.slice(-limit);
|
|
278
|
-
const trends = [];
|
|
279
|
-
let previousValue = 0;
|
|
280
|
-
for (const entry of sorted) {
|
|
281
|
-
let value;
|
|
282
|
-
switch (type) {
|
|
283
|
-
case 'line':
|
|
284
|
-
value = entry.metrics.lineCoverage;
|
|
285
|
-
break;
|
|
286
|
-
case 'branch':
|
|
287
|
-
value = entry.metrics.branchCoverage;
|
|
288
|
-
break;
|
|
289
|
-
case 'function':
|
|
290
|
-
value = entry.metrics.functionCoverage;
|
|
291
|
-
break;
|
|
292
|
-
case 'statement':
|
|
293
|
-
value = entry.metrics.statementCoverage;
|
|
294
|
-
break;
|
|
295
|
-
}
|
|
296
|
-
trends.push({
|
|
297
|
-
runId: entry.runId,
|
|
298
|
-
timestamp: entry.timestamp,
|
|
299
|
-
coverage: value,
|
|
300
|
-
type,
|
|
301
|
-
change: value - previousValue
|
|
302
|
-
});
|
|
303
|
-
previousValue = value;
|
|
304
|
-
}
|
|
305
|
-
return trends;
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* Calculate trend direction
|
|
309
|
-
*/
|
|
310
|
-
getTrendDirection(trends) {
|
|
311
|
-
if (trends.length < 3) {
|
|
312
|
-
return 'stable';
|
|
313
|
-
}
|
|
314
|
-
const recent = trends.slice(-5);
|
|
315
|
-
const avgChange = recent.reduce((sum, t) => sum + t.change, 0) / recent.length;
|
|
316
|
-
if (avgChange > 1)
|
|
317
|
-
return 'improving';
|
|
318
|
-
if (avgChange < -1)
|
|
319
|
-
return 'declining';
|
|
320
|
-
return 'stable';
|
|
321
|
-
}
|
|
322
|
-
/**
|
|
323
|
-
* Predict future coverage based on trends
|
|
324
|
-
*/
|
|
325
|
-
predictCoverage(key, type = 'line', targetCoverage) {
|
|
326
|
-
const trends = this.getTrends(key, type, 20);
|
|
327
|
-
if (trends.length < 5) {
|
|
328
|
-
return {
|
|
329
|
-
predictedReach: null,
|
|
330
|
-
projectedCoverage: trends[trends.length - 1]?.coverage || 0,
|
|
331
|
-
confidence: 'low'
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
|
-
// Simple linear regression
|
|
335
|
-
const n = trends.length;
|
|
336
|
-
let sumX = 0;
|
|
337
|
-
let sumY = 0;
|
|
338
|
-
let sumXY = 0;
|
|
339
|
-
let sumXX = 0;
|
|
340
|
-
for (let i = 0; i < n; i++) {
|
|
341
|
-
const x = i;
|
|
342
|
-
const y = trends[i].coverage;
|
|
343
|
-
sumX += x;
|
|
344
|
-
sumY += y;
|
|
345
|
-
sumXY += x * y;
|
|
346
|
-
sumXX += x * x;
|
|
347
|
-
}
|
|
348
|
-
const slope = (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX);
|
|
349
|
-
const intercept = (sumY - slope * sumX) / n;
|
|
350
|
-
const currentCoverage = trends[n - 1].coverage;
|
|
351
|
-
const avgCoverage = sumY / n;
|
|
352
|
-
const variance = trends.reduce((sum, t) => sum + Math.pow(t.coverage - avgCoverage, 2), 0) / n;
|
|
353
|
-
// Determine confidence based on variance
|
|
354
|
-
let confidence;
|
|
355
|
-
if (variance < 25)
|
|
356
|
-
confidence = 'high';
|
|
357
|
-
else if (variance < 100)
|
|
358
|
-
confidence = 'medium';
|
|
359
|
-
else
|
|
360
|
-
confidence = 'low';
|
|
361
|
-
// Project coverage for next run
|
|
362
|
-
const projectedCoverage = currentCoverage + slope;
|
|
363
|
-
// Predict when target will be reached
|
|
364
|
-
let predictedReach = null;
|
|
365
|
-
if (slope > 0.1) {
|
|
366
|
-
const runsNeeded = (targetCoverage - currentCoverage) / slope;
|
|
367
|
-
if (runsNeeded > 0 && runsNeeded < 100) {
|
|
368
|
-
predictedReach = Date.now() + runsNeeded * 24 * 60 * 60 * 1000; // Assume daily runs
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
return { predictedReach, projectedCoverage, confidence };
|
|
372
|
-
}
|
|
373
|
-
/**
|
|
374
|
-
* Generate coverage summary text
|
|
375
|
-
*/
|
|
376
|
-
generateSummary(metrics) {
|
|
377
|
-
const parts = [];
|
|
378
|
-
parts.push(`Line Coverage: ${metrics.lineCoverage.toFixed(1)}%`);
|
|
379
|
-
parts.push(`Branch Coverage: ${metrics.branchCoverage.toFixed(1)}%`);
|
|
380
|
-
parts.push(`Function Coverage: ${metrics.functionCoverage.toFixed(1)}%`);
|
|
381
|
-
if (metrics.totalFiles > 0) {
|
|
382
|
-
parts.push(`Files: ${metrics.filesWithCoverage}/${metrics.totalFiles}`);
|
|
383
|
-
}
|
|
384
|
-
return parts.join(' | ');
|
|
385
|
-
}
|
|
386
|
-
/**
|
|
387
|
-
* Format coverage percentage with color indicator
|
|
388
|
-
*/
|
|
389
|
-
formatCoverage(percentage, threshold = 80) {
|
|
390
|
-
if (percentage >= threshold) {
|
|
391
|
-
return `✓ ${percentage.toFixed(1)}%`;
|
|
392
|
-
}
|
|
393
|
-
else if (percentage >= threshold - 10) {
|
|
394
|
-
return `⚠ ${percentage.toFixed(1)}%`;
|
|
395
|
-
}
|
|
396
|
-
return `✗ ${percentage.toFixed(1)}%`;
|
|
397
|
-
}
|
|
398
|
-
/**
|
|
399
|
-
* Clear history
|
|
400
|
-
*/
|
|
401
|
-
clearHistory(key) {
|
|
402
|
-
if (key) {
|
|
403
|
-
this.history.delete(key);
|
|
404
|
-
}
|
|
405
|
-
else {
|
|
406
|
-
this.history.clear();
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
}
|
|
410
|
-
/**
|
|
411
|
-
* Create a coverage analyzer
|
|
412
|
-
*/
|
|
413
|
-
export function createCoverageAnalyzer() {
|
|
414
|
-
return new CoverageAnalyzer();
|
|
415
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Coverage Collector
|
|
3
|
-
*
|
|
4
|
-
* Collects coverage data from various test sources.
|
|
5
|
-
* Supports Jest, Vitest, Cypress, Playwright, and LCOV formats.
|
|
6
|
-
*/
|
|
7
|
-
import type { FileCoverage, CoverageMetrics, CoverageResult, CoverageConfig } from './types.js';
|
|
8
|
-
/**
|
|
9
|
-
* Coverage Collector class
|
|
10
|
-
*/
|
|
11
|
-
export declare class CoverageCollector {
|
|
12
|
-
private config;
|
|
13
|
-
constructor(config?: Partial<CoverageConfig>);
|
|
14
|
-
/**
|
|
15
|
-
* Collect coverage from a file path (auto-detect format)
|
|
16
|
-
*/
|
|
17
|
-
collectFromFile(filePath: string): Promise<CoverageResult | null>;
|
|
18
|
-
/**
|
|
19
|
-
* Collect coverage from LCOV format
|
|
20
|
-
*/
|
|
21
|
-
collectFromLcov(filePath: string): Promise<CoverageResult | null>;
|
|
22
|
-
/**
|
|
23
|
-
* Collect coverage from JSON format (Vitest/Istanbul)
|
|
24
|
-
*/
|
|
25
|
-
collectFromJson(filePath: string): Promise<CoverageResult | null>;
|
|
26
|
-
/**
|
|
27
|
-
* Collect coverage from Istanbul format
|
|
28
|
-
*/
|
|
29
|
-
collectFromIstanbul(filePath: string): Promise<CoverageResult | null>;
|
|
30
|
-
/**
|
|
31
|
-
* Parse LCOV format content
|
|
32
|
-
*/
|
|
33
|
-
private parseLcov;
|
|
34
|
-
/**
|
|
35
|
-
* Convert LCOV record to FileCoverage
|
|
36
|
-
*/
|
|
37
|
-
private convertLcovToFileCoverage;
|
|
38
|
-
/**
|
|
39
|
-
* Convert Vitest coverage data to FileCoverage
|
|
40
|
-
*/
|
|
41
|
-
private convertVitestToFileCoverage;
|
|
42
|
-
/**
|
|
43
|
-
* Convert Istanbul coverage data to FileCoverage
|
|
44
|
-
*/
|
|
45
|
-
private convertIstanbulToFileCoverage;
|
|
46
|
-
/**
|
|
47
|
-
* Calculate aggregate metrics from file coverage data
|
|
48
|
-
*/
|
|
49
|
-
calculateMetrics(files: Record<string, FileCoverage>): CoverageMetrics;
|
|
50
|
-
/**
|
|
51
|
-
* Detect coverage format from file path
|
|
52
|
-
*/
|
|
53
|
-
private detectFormat;
|
|
54
|
-
/**
|
|
55
|
-
* Filter files based on include/exclude patterns
|
|
56
|
-
*/
|
|
57
|
-
filterFiles(files: Record<string, FileCoverage>): Record<string, FileCoverage>;
|
|
58
|
-
/**
|
|
59
|
-
* Match path against glob pattern
|
|
60
|
-
*/
|
|
61
|
-
private matchPattern;
|
|
62
|
-
/**
|
|
63
|
-
* Merge multiple coverage results
|
|
64
|
-
*/
|
|
65
|
-
mergeCoverageResults(results: CoverageResult[]): CoverageResult;
|
|
66
|
-
/**
|
|
67
|
-
* Update configuration
|
|
68
|
-
*/
|
|
69
|
-
updateConfig(updates: Partial<CoverageConfig>): void;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Create a coverage collector with default config
|
|
73
|
-
*/
|
|
74
|
-
export declare function createCoverageCollector(config?: Partial<CoverageConfig>): CoverageCollector;
|