@agentic-qe/v3 3.0.0-alpha.6 → 3.0.0-alpha.8
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/assets/agents/v3/subagents/v3-qe-code-reviewer.md +339 -0
- package/assets/agents/v3/subagents/v3-qe-integration-reviewer.md +344 -0
- package/assets/agents/v3/subagents/v3-qe-performance-reviewer.md +351 -0
- package/assets/agents/v3/subagents/v3-qe-security-reviewer.md +374 -0
- package/assets/agents/v3/subagents/v3-qe-tdd-green.md +334 -0
- package/assets/agents/v3/subagents/v3-qe-tdd-red.md +329 -0
- package/assets/agents/v3/subagents/v3-qe-tdd-refactor.md +361 -0
- package/assets/agents/v3/v3-qe-accessibility-auditor.md +266 -0
- package/assets/agents/v3/v3-qe-bdd-generator.md +279 -0
- package/assets/agents/v3/v3-qe-chaos-engineer.md +265 -0
- package/assets/agents/v3/v3-qe-code-complexity.md +298 -0
- package/assets/agents/v3/v3-qe-code-intelligence.md +262 -0
- package/assets/agents/v3/v3-qe-contract-validator.md +267 -0
- package/assets/agents/v3/v3-qe-coverage-specialist.md +227 -0
- package/assets/agents/v3/v3-qe-defect-predictor.md +251 -0
- package/assets/agents/v3/v3-qe-dependency-mapper.md +277 -0
- package/assets/agents/v3/v3-qe-deployment-advisor.md +275 -0
- package/assets/agents/v3/v3-qe-flaky-hunter.md +248 -0
- package/assets/agents/v3/v3-qe-fleet-commander.md +293 -0
- package/assets/agents/v3/v3-qe-gap-detector.md +260 -0
- package/assets/agents/v3/v3-qe-graphql-tester.md +308 -0
- package/assets/agents/v3/v3-qe-impact-analyzer.md +299 -0
- package/assets/agents/v3/v3-qe-integration-tester.md +238 -0
- package/assets/agents/v3/v3-qe-kg-builder.md +273 -0
- package/assets/agents/v3/v3-qe-learning-coordinator.md +226 -0
- package/assets/agents/v3/v3-qe-load-tester.md +280 -0
- package/assets/agents/v3/v3-qe-metrics-optimizer.md +300 -0
- package/assets/agents/v3/v3-qe-mutation-tester.md +301 -0
- package/assets/agents/v3/v3-qe-parallel-executor.md +240 -0
- package/assets/agents/v3/v3-qe-pattern-learner.md +271 -0
- package/assets/agents/v3/v3-qe-performance-tester.md +262 -0
- package/assets/agents/v3/v3-qe-property-tester.md +247 -0
- package/assets/agents/v3/v3-qe-quality-gate.md +218 -0
- package/assets/agents/v3/v3-qe-queen-coordinator.md +214 -0
- package/assets/agents/v3/v3-qe-qx-partner.md +313 -0
- package/assets/agents/v3/v3-qe-regression-analyzer.md +322 -0
- package/assets/agents/v3/v3-qe-requirements-validator.md +360 -0
- package/assets/agents/v3/v3-qe-responsive-tester.md +311 -0
- package/assets/agents/v3/v3-qe-retry-handler.md +256 -0
- package/assets/agents/v3/v3-qe-risk-assessor.md +273 -0
- package/assets/agents/v3/v3-qe-root-cause-analyzer.md +286 -0
- package/assets/agents/v3/v3-qe-security-auditor.md +299 -0
- package/assets/agents/v3/v3-qe-security-scanner.md +235 -0
- package/assets/agents/v3/v3-qe-tdd-specialist.md +239 -0
- package/assets/agents/v3/v3-qe-test-architect.md +233 -0
- package/assets/agents/v3/v3-qe-transfer-specialist.md +295 -0
- package/assets/agents/v3/v3-qe-visual-tester.md +232 -0
- package/assets/skills/accessibility-testing/SKILL.md +216 -0
- package/assets/skills/agentdb-advanced/SKILL.md +550 -0
- package/assets/skills/agentdb-learning/SKILL.md +545 -0
- package/assets/skills/agentdb-memory-patterns/SKILL.md +339 -0
- package/assets/skills/agentdb-optimization/SKILL.md +509 -0
- package/assets/skills/agentdb-vector-search/SKILL.md +339 -0
- package/assets/skills/agentic-jujutsu/SKILL.md +645 -0
- package/assets/skills/agentic-quality-engineering/SKILL.md +335 -0
- package/assets/skills/api-testing-patterns/SKILL.md +294 -0
- package/assets/skills/aqe-v2-v3-migration/skill.md +322 -0
- package/assets/skills/brutal-honesty-review/README.md +218 -0
- package/assets/skills/brutal-honesty-review/SKILL.md +235 -0
- package/assets/skills/brutal-honesty-review/resources/assessment-rubrics.md +295 -0
- package/assets/skills/brutal-honesty-review/resources/review-template.md +102 -0
- package/assets/skills/brutal-honesty-review/scripts/assess-code.sh +179 -0
- package/assets/skills/brutal-honesty-review/scripts/assess-tests.sh +223 -0
- package/assets/skills/bug-reporting-excellence/SKILL.md +225 -0
- package/assets/skills/chaos-engineering-resilience/SKILL.md +158 -0
- package/assets/skills/cicd-pipeline-qe-orchestrator/README.md +304 -0
- package/assets/skills/cicd-pipeline-qe-orchestrator/SKILL.md +315 -0
- package/assets/skills/cicd-pipeline-qe-orchestrator/resources/workflows/microservice-pipeline.md +239 -0
- package/assets/skills/cicd-pipeline-qe-orchestrator/resources/workflows/mobile-pipeline.md +375 -0
- package/assets/skills/cicd-pipeline-qe-orchestrator/resources/workflows/monolith-pipeline.md +268 -0
- package/assets/skills/code-review-quality/SKILL.md +227 -0
- package/assets/skills/compatibility-testing/SKILL.md +205 -0
- package/assets/skills/compliance-testing/SKILL.md +225 -0
- package/assets/skills/consultancy-practices/SKILL.md +202 -0
- package/assets/skills/context-driven-testing/SKILL.md +196 -0
- package/assets/skills/contract-testing/SKILL.md +222 -0
- package/assets/skills/database-testing/SKILL.md +244 -0
- package/assets/skills/exploratory-testing-advanced/SKILL.md +201 -0
- package/assets/skills/flow-nexus-neural/SKILL.md +738 -0
- package/assets/skills/flow-nexus-platform/SKILL.md +1157 -0
- package/assets/skills/flow-nexus-swarm/SKILL.md +610 -0
- package/assets/skills/github-code-review/SKILL.md +1140 -0
- package/assets/skills/github-multi-repo/SKILL.md +874 -0
- package/assets/skills/github-project-management/SKILL.md +1277 -0
- package/assets/skills/github-release-management/SKILL.md +1081 -0
- package/assets/skills/github-workflow-automation/SKILL.md +1065 -0
- package/assets/skills/hive-mind-advanced/SKILL.md +712 -0
- package/assets/skills/holistic-testing-pact/SKILL.md +171 -0
- package/assets/skills/hooks-automation/SKILL.md +1201 -0
- package/assets/skills/localization-testing/SKILL.md +221 -0
- package/assets/skills/mobile-testing/SKILL.md +219 -0
- package/assets/skills/mutation-testing/SKILL.md +229 -0
- package/assets/skills/n8n-expression-testing/SKILL.md +434 -0
- package/assets/skills/n8n-integration-testing-patterns/SKILL.md +540 -0
- package/assets/skills/n8n-security-testing/SKILL.md +599 -0
- package/assets/skills/n8n-trigger-testing-strategies/SKILL.md +541 -0
- package/assets/skills/n8n-workflow-testing-fundamentals/SKILL.md +447 -0
- package/assets/skills/pair-programming/SKILL.md +1202 -0
- package/assets/skills/performance-analysis/SKILL.md +563 -0
- package/assets/skills/performance-testing/SKILL.md +310 -0
- package/assets/skills/quality-metrics/SKILL.md +225 -0
- package/assets/skills/reasoningbank-agentdb/SKILL.md +446 -0
- package/assets/skills/reasoningbank-intelligence/SKILL.md +201 -0
- package/assets/skills/refactoring-patterns/SKILL.md +205 -0
- package/assets/skills/regression-testing/SKILL.md +227 -0
- package/assets/skills/risk-based-testing/SKILL.md +206 -0
- package/assets/skills/security-testing/SKILL.md +306 -0
- package/assets/skills/sherlock-review/SKILL.md +250 -0
- package/assets/skills/shift-left-testing/SKILL.md +225 -0
- package/assets/skills/shift-right-testing/SKILL.md +227 -0
- package/assets/skills/six-thinking-hats/README.md +190 -0
- package/assets/skills/six-thinking-hats/SKILL.md +280 -0
- package/assets/skills/six-thinking-hats/resources/examples/api-testing-example.md +345 -0
- package/assets/skills/six-thinking-hats/resources/templates/solo-session-template.md +167 -0
- package/assets/skills/six-thinking-hats/resources/templates/team-session-template.md +336 -0
- package/assets/skills/skill-builder/SKILL.md +910 -0
- package/assets/skills/sparc-methodology/SKILL.md +1115 -0
- package/assets/skills/stream-chain/SKILL.md +563 -0
- package/assets/skills/swarm-advanced/SKILL.md +973 -0
- package/assets/skills/swarm-orchestration/SKILL.md +179 -0
- package/assets/skills/tdd-london-chicago/SKILL.md +244 -0
- package/assets/skills/technical-writing/SKILL.md +178 -0
- package/assets/skills/test-automation-strategy/SKILL.md +230 -0
- package/assets/skills/test-data-management/SKILL.md +270 -0
- package/assets/skills/test-design-techniques/SKILL.md +244 -0
- package/assets/skills/test-environment-management/SKILL.md +243 -0
- package/assets/skills/test-reporting-analytics/SKILL.md +214 -0
- package/assets/skills/testability-scoring/README.md +71 -0
- package/assets/skills/testability-scoring/SKILL.md +346 -0
- package/assets/skills/testability-scoring/resources/templates/config.template.js +84 -0
- package/assets/skills/testability-scoring/resources/templates/testability-scoring.spec.template.js +532 -0
- package/assets/skills/testability-scoring/scripts/generate-html-report.js +1007 -0
- package/assets/skills/testability-scoring/scripts/run-assessment.sh +70 -0
- package/assets/skills/v3-qe-chaos-resilience/SKILL.md +238 -0
- package/assets/skills/v3-qe-code-intelligence/SKILL.md +209 -0
- package/assets/skills/v3-qe-contract-testing/SKILL.md +218 -0
- package/assets/skills/v3-qe-coverage-analysis/SKILL.md +187 -0
- package/assets/skills/v3-qe-defect-intelligence/SKILL.md +205 -0
- package/assets/skills/v3-qe-learning-optimization/SKILL.md +238 -0
- package/assets/skills/v3-qe-quality-assessment/SKILL.md +213 -0
- package/assets/skills/v3-qe-requirements-validation/SKILL.md +248 -0
- package/assets/skills/v3-qe-test-execution/SKILL.md +182 -0
- package/assets/skills/v3-qe-test-generation/SKILL.md +141 -0
- package/assets/skills/v3-qe-visual-accessibility/SKILL.md +242 -0
- package/assets/skills/verification-quality/SKILL.md +649 -0
- package/assets/skills/visual-testing-advanced/SKILL.md +219 -0
- package/assets/skills/xp-practices/SKILL.md +229 -0
- package/dist/cli/bundle.js +23 -13
- package/dist/init/agents-installer.js +4 -4
- package/dist/init/agents-installer.js.map +1 -1
- package/dist/init/init-wizard.d.ts.map +1 -1
- package/dist/init/init-wizard.js +15 -5
- package/dist/init/init-wizard.js.map +1 -1
- package/dist/init/skills-installer.js +4 -4
- package/dist/init/skills-installer.js.map +1 -1
- package/package.json +7 -1
- package/docs/analysis/V3-INIT-REQUIREMENTS-ANALYSIS.md +0 -352
- package/implementation/README.md +0 -90
- package/implementation/adrs/ADR-030-coherence-gated-quality-gates.md +0 -312
- package/implementation/adrs/ADR-031-strange-loop-self-awareness.md +0 -484
- package/implementation/adrs/ADR-032-time-crystal-scheduling.md +0 -530
- package/implementation/adrs/ADR-033-early-exit-testing.md +0 -634
- package/implementation/adrs/ADR-034-neural-topology-optimizer.md +0 -589
- package/implementation/adrs/ADR-035-causal-discovery.md +0 -610
- package/implementation/adrs/ADR-036-result-persistence.md +0 -326
- package/implementation/adrs/ADR-037-v3-qe-agent-naming.md +0 -105
- package/implementation/adrs/ADR-038-v3-qe-memory-unification.md +0 -154
- package/implementation/adrs/ADR-039-v3-qe-mcp-optimization.md +0 -179
- package/implementation/adrs/ADR-040-v3-qe-agentic-flow-integration.md +0 -240
- package/implementation/adrs/ADR-041-v3-qe-cli-enhancement.md +0 -296
- package/implementation/adrs/ADR-042-v3-qe-token-tracking-integration.md +0 -517
- package/implementation/adrs/v3-adrs.md +0 -2783
- package/implementation/planning/AQE-V3-MASTER-PLAN.md +0 -815
- package/security-scan-report-2026-01-11.md +0 -410
- package/security-verification-report-2026-01-11.md +0 -278
- package/src/benchmarks/performance-benchmarks.ts +0 -646
- package/src/benchmarks/run-benchmarks.ts +0 -324
- package/src/causal-discovery/causal-graph.ts +0 -450
- package/src/causal-discovery/discovery-engine.ts +0 -438
- package/src/causal-discovery/index.ts +0 -117
- package/src/causal-discovery/types.ts +0 -456
- package/src/causal-discovery/weight-matrix.ts +0 -453
- package/src/cli/commands/qe-tools.ts +0 -634
- package/src/cli/index.ts +0 -1976
- package/src/compatibility/agent-mapper.ts +0 -291
- package/src/compatibility/cli-adapter.ts +0 -277
- package/src/compatibility/config-migrator.ts +0 -334
- package/src/compatibility/index.ts +0 -112
- package/src/compatibility/mcp-adapter.ts +0 -248
- package/src/compatibility/types.ts +0 -156
- package/src/coordination/claims/claim-repository.ts +0 -636
- package/src/coordination/claims/claim-service.ts +0 -675
- package/src/coordination/claims/handoff-manager.ts +0 -535
- package/src/coordination/claims/index.ts +0 -276
- package/src/coordination/claims/interfaces.ts +0 -687
- package/src/coordination/claims/work-stealing.ts +0 -436
- package/src/coordination/cross-domain-router.ts +0 -492
- package/src/coordination/index.ts +0 -127
- package/src/coordination/interfaces.ts +0 -691
- package/src/coordination/protocol-executor.ts +0 -760
- package/src/coordination/protocols/code-intelligence-index.ts +0 -855
- package/src/coordination/protocols/defect-investigation.ts +0 -1184
- package/src/coordination/protocols/index.ts +0 -11
- package/src/coordination/protocols/learning-consolidation.ts +0 -1181
- package/src/coordination/protocols/morning-sync.ts +0 -1055
- package/src/coordination/protocols/quality-gate.ts +0 -1566
- package/src/coordination/protocols/security-audit.ts +0 -1587
- package/src/coordination/queen-coordinator.ts +0 -1176
- package/src/coordination/result-saver.ts +0 -780
- package/src/coordination/task-executor.ts +0 -1146
- package/src/coordination/workflow-orchestrator.ts +0 -1917
- package/src/domains/chaos-resilience/coordinator.ts +0 -1032
- package/src/domains/chaos-resilience/index.ts +0 -143
- package/src/domains/chaos-resilience/interfaces.ts +0 -659
- package/src/domains/chaos-resilience/plugin.ts +0 -691
- package/src/domains/chaos-resilience/services/chaos-engineer.ts +0 -1097
- package/src/domains/chaos-resilience/services/index.ts +0 -19
- package/src/domains/chaos-resilience/services/load-tester.ts +0 -799
- package/src/domains/chaos-resilience/services/performance-profiler.ts +0 -792
- package/src/domains/code-intelligence/coordinator.ts +0 -631
- package/src/domains/code-intelligence/index.ts +0 -86
- package/src/domains/code-intelligence/interfaces.ts +0 -162
- package/src/domains/code-intelligence/plugin.ts +0 -451
- package/src/domains/code-intelligence/services/impact-analyzer.ts +0 -567
- package/src/domains/code-intelligence/services/index.ts +0 -26
- package/src/domains/code-intelligence/services/knowledge-graph.ts +0 -1067
- package/src/domains/code-intelligence/services/semantic-analyzer.ts +0 -901
- package/src/domains/contract-testing/coordinator.ts +0 -1038
- package/src/domains/contract-testing/index.ts +0 -122
- package/src/domains/contract-testing/interfaces.ts +0 -458
- package/src/domains/contract-testing/plugin.ts +0 -746
- package/src/domains/contract-testing/services/api-compatibility.ts +0 -748
- package/src/domains/contract-testing/services/contract-validator.ts +0 -1700
- package/src/domains/contract-testing/services/index.ts +0 -19
- package/src/domains/contract-testing/services/schema-validator.ts +0 -1102
- package/src/domains/coverage-analysis/coordinator.ts +0 -485
- package/src/domains/coverage-analysis/index.ts +0 -114
- package/src/domains/coverage-analysis/interfaces.ts +0 -142
- package/src/domains/coverage-analysis/plugin.ts +0 -172
- package/src/domains/coverage-analysis/services/coverage-analyzer.ts +0 -449
- package/src/domains/coverage-analysis/services/coverage-embedder.ts +0 -733
- package/src/domains/coverage-analysis/services/coverage-parser.ts +0 -753
- package/src/domains/coverage-analysis/services/gap-detector.ts +0 -592
- package/src/domains/coverage-analysis/services/hnsw-index.ts +0 -728
- package/src/domains/coverage-analysis/services/index.ts +0 -61
- package/src/domains/coverage-analysis/services/risk-scorer.ts +0 -540
- package/src/domains/coverage-analysis/services/sublinear-analyzer.ts +0 -747
- package/src/domains/defect-intelligence/coordinator.ts +0 -635
- package/src/domains/defect-intelligence/index.ts +0 -83
- package/src/domains/defect-intelligence/interfaces.ts +0 -152
- package/src/domains/defect-intelligence/plugin.ts +0 -483
- package/src/domains/defect-intelligence/services/causal-root-cause-analyzer.ts +0 -494
- package/src/domains/defect-intelligence/services/defect-predictor.ts +0 -852
- package/src/domains/defect-intelligence/services/index.ts +0 -37
- package/src/domains/defect-intelligence/services/pattern-learner.ts +0 -738
- package/src/domains/defect-intelligence/services/root-cause-analyzer.ts +0 -637
- package/src/domains/domain-interface.ts +0 -77
- package/src/domains/index.ts +0 -23
- package/src/domains/learning-optimization/coordinator.ts +0 -1215
- package/src/domains/learning-optimization/index.ts +0 -127
- package/src/domains/learning-optimization/interfaces.ts +0 -570
- package/src/domains/learning-optimization/plugin.ts +0 -851
- package/src/domains/learning-optimization/services/index.ts +0 -29
- package/src/domains/learning-optimization/services/learning-coordinator.ts +0 -972
- package/src/domains/learning-optimization/services/metrics-optimizer.ts +0 -915
- package/src/domains/learning-optimization/services/production-intel.ts +0 -971
- package/src/domains/learning-optimization/services/transfer-specialist.ts +0 -723
- package/src/domains/quality-assessment/coherence/gate-controller.ts +0 -549
- package/src/domains/quality-assessment/coherence/index.ts +0 -211
- package/src/domains/quality-assessment/coherence/lambda-calculator.ts +0 -384
- package/src/domains/quality-assessment/coherence/partition-detector.ts +0 -469
- package/src/domains/quality-assessment/coherence/types.ts +0 -384
- package/src/domains/quality-assessment/coordinator.ts +0 -605
- package/src/domains/quality-assessment/index.ts +0 -97
- package/src/domains/quality-assessment/interfaces.ts +0 -152
- package/src/domains/quality-assessment/plugin.ts +0 -496
- package/src/domains/quality-assessment/services/coherence-gate.ts +0 -358
- package/src/domains/quality-assessment/services/deployment-advisor.ts +0 -571
- package/src/domains/quality-assessment/services/index.ts +0 -34
- package/src/domains/quality-assessment/services/quality-analyzer.ts +0 -670
- package/src/domains/quality-assessment/services/quality-gate.ts +0 -384
- package/src/domains/requirements-validation/coordinator.ts +0 -812
- package/src/domains/requirements-validation/index.ts +0 -92
- package/src/domains/requirements-validation/interfaces.ts +0 -303
- package/src/domains/requirements-validation/plugin.ts +0 -576
- package/src/domains/requirements-validation/services/bdd-scenario-writer.ts +0 -676
- package/src/domains/requirements-validation/services/index.ts +0 -20
- package/src/domains/requirements-validation/services/requirements-validator.ts +0 -559
- package/src/domains/requirements-validation/services/testability-scorer.ts +0 -639
- package/src/domains/security-compliance/coordinator.ts +0 -757
- package/src/domains/security-compliance/index.ts +0 -120
- package/src/domains/security-compliance/interfaces.ts +0 -434
- package/src/domains/security-compliance/plugin.ts +0 -509
- package/src/domains/security-compliance/services/compliance-validator.ts +0 -1226
- package/src/domains/security-compliance/services/index.ts +0 -31
- package/src/domains/security-compliance/services/security-auditor.ts +0 -2227
- package/src/domains/security-compliance/services/security-scanner.ts +0 -2354
- package/src/domains/security-compliance/services/semgrep-integration.ts +0 -289
- package/src/domains/test-execution/coordinator.ts +0 -426
- package/src/domains/test-execution/index.ts +0 -76
- package/src/domains/test-execution/interfaces.ts +0 -119
- package/src/domains/test-execution/plugin.ts +0 -208
- package/src/domains/test-execution/services/flaky-detector.ts +0 -1240
- package/src/domains/test-execution/services/index.ts +0 -8
- package/src/domains/test-execution/services/retry-handler.ts +0 -820
- package/src/domains/test-execution/services/test-executor.ts +0 -885
- package/src/domains/test-generation/coordinator.ts +0 -656
- package/src/domains/test-generation/index.ts +0 -77
- package/src/domains/test-generation/interfaces.ts +0 -118
- package/src/domains/test-generation/plugin.ts +0 -397
- package/src/domains/test-generation/services/index.ts +0 -23
- package/src/domains/test-generation/services/pattern-matcher.ts +0 -1725
- package/src/domains/test-generation/services/test-generator.ts +0 -2750
- package/src/domains/visual-accessibility/coordinator.ts +0 -860
- package/src/domains/visual-accessibility/index.ts +0 -116
- package/src/domains/visual-accessibility/interfaces.ts +0 -435
- package/src/domains/visual-accessibility/plugin.ts +0 -568
- package/src/domains/visual-accessibility/services/accessibility-tester.ts +0 -982
- package/src/domains/visual-accessibility/services/axe-core-audit.ts +0 -630
- package/src/domains/visual-accessibility/services/index.ts +0 -28
- package/src/domains/visual-accessibility/services/responsive-tester.ts +0 -934
- package/src/domains/visual-accessibility/services/visual-tester.ts +0 -458
- package/src/early-exit/early-exit-controller.ts +0 -490
- package/src/early-exit/early-exit-decision.ts +0 -391
- package/src/early-exit/index.ts +0 -115
- package/src/early-exit/quality-signal.ts +0 -389
- package/src/early-exit/speculative-executor.ts +0 -505
- package/src/early-exit/types.ts +0 -407
- package/src/feedback/coverage-learner.ts +0 -456
- package/src/feedback/feedback-loop.ts +0 -426
- package/src/feedback/index.ts +0 -72
- package/src/feedback/pattern-promotion.ts +0 -373
- package/src/feedback/quality-score-calculator.ts +0 -334
- package/src/feedback/test-outcome-tracker.ts +0 -450
- package/src/feedback/types.ts +0 -497
- package/src/index.ts +0 -224
- package/src/init/agents-installer.ts +0 -536
- package/src/init/index.ts +0 -80
- package/src/init/init-wizard.ts +0 -1061
- package/src/init/project-analyzer.ts +0 -696
- package/src/init/self-configurator.ts +0 -488
- package/src/init/skills-installer.ts +0 -467
- package/src/init/types.ts +0 -432
- package/src/integrations/ruvector/ast-complexity.ts +0 -470
- package/src/integrations/ruvector/coverage-router.ts +0 -594
- package/src/integrations/ruvector/diff-risk-classifier.ts +0 -759
- package/src/integrations/ruvector/fallback.ts +0 -942
- package/src/integrations/ruvector/graph-boundaries.ts +0 -809
- package/src/integrations/ruvector/index.ts +0 -363
- package/src/integrations/ruvector/interfaces.ts +0 -609
- package/src/integrations/ruvector/q-learning-router.ts +0 -550
- package/src/kernel/agent-coordinator.ts +0 -165
- package/src/kernel/agentdb-backend.ts +0 -504
- package/src/kernel/event-bus.ts +0 -129
- package/src/kernel/hybrid-backend.ts +0 -538
- package/src/kernel/index.ts +0 -28
- package/src/kernel/interfaces.ts +0 -257
- package/src/kernel/kernel.ts +0 -285
- package/src/kernel/memory-backend.ts +0 -169
- package/src/kernel/memory-factory.ts +0 -293
- package/src/kernel/plugin-loader.ts +0 -179
- package/src/learning/index.ts +0 -219
- package/src/learning/pattern-store.ts +0 -990
- package/src/learning/qe-guidance.ts +0 -832
- package/src/learning/qe-hooks.ts +0 -644
- package/src/learning/qe-patterns.ts +0 -449
- package/src/learning/qe-reasoning-bank.ts +0 -951
- package/src/learning/real-embeddings.ts +0 -277
- package/src/learning/real-qe-reasoning-bank.ts +0 -833
- package/src/learning/sqlite-persistence.ts +0 -554
- package/src/mcp/entry.ts +0 -59
- package/src/mcp/handlers/agent-handlers.ts +0 -285
- package/src/mcp/handlers/core-handlers.ts +0 -317
- package/src/mcp/handlers/domain-handlers.ts +0 -1444
- package/src/mcp/handlers/index.ts +0 -57
- package/src/mcp/handlers/memory-handlers.ts +0 -338
- package/src/mcp/handlers/task-handlers.ts +0 -363
- package/src/mcp/index.ts +0 -30
- package/src/mcp/metrics/index.ts +0 -14
- package/src/mcp/metrics/metrics-collector.ts +0 -503
- package/src/mcp/protocol-server.ts +0 -752
- package/src/mcp/security/cve-prevention.ts +0 -742
- package/src/mcp/security/index.ts +0 -356
- package/src/mcp/security/oauth21-provider.ts +0 -821
- package/src/mcp/security/rate-limiter.ts +0 -615
- package/src/mcp/security/sampling-server.ts +0 -662
- package/src/mcp/security/schema-validator.ts +0 -855
- package/src/mcp/server.ts +0 -657
- package/src/mcp/tool-registry.ts +0 -391
- package/src/mcp/tools/base.ts +0 -399
- package/src/mcp/tools/chaos-resilience/inject.ts +0 -699
- package/src/mcp/tools/code-intelligence/analyze.ts +0 -745
- package/src/mcp/tools/contract-testing/validate.ts +0 -708
- package/src/mcp/tools/coverage-analysis/index.ts +0 -770
- package/src/mcp/tools/defect-intelligence/predict.ts +0 -466
- package/src/mcp/tools/index.ts +0 -214
- package/src/mcp/tools/learning-optimization/optimize.ts +0 -772
- package/src/mcp/tools/quality-assessment/evaluate.ts +0 -385
- package/src/mcp/tools/registry.ts +0 -248
- package/src/mcp/tools/requirements-validation/validate.ts +0 -394
- package/src/mcp/tools/security-compliance/scan.ts +0 -365
- package/src/mcp/tools/test-execution/execute.ts +0 -291
- package/src/mcp/tools/test-generation/generate.ts +0 -544
- package/src/mcp/tools/visual-accessibility/index.ts +0 -791
- package/src/mcp/transport/index.ts +0 -31
- package/src/mcp/transport/stdio.ts +0 -318
- package/src/mcp/types.ts +0 -543
- package/src/neural-optimizer/index.ts +0 -111
- package/src/neural-optimizer/replay-buffer.ts +0 -455
- package/src/neural-optimizer/swarm-topology.ts +0 -508
- package/src/neural-optimizer/topology-optimizer.ts +0 -828
- package/src/neural-optimizer/types.ts +0 -481
- package/src/neural-optimizer/value-network.ts +0 -351
- package/src/optimization/auto-tuner.ts +0 -817
- package/src/optimization/index.ts +0 -77
- package/src/optimization/metric-collectors.ts +0 -474
- package/src/optimization/qe-workers.ts +0 -704
- package/src/optimization/tuning-algorithm.ts +0 -401
- package/src/optimization/types.ts +0 -314
- package/src/routing/index.ts +0 -51
- package/src/routing/qe-agent-registry.ts +0 -963
- package/src/routing/qe-task-router.ts +0 -564
- package/src/routing/routing-feedback.ts +0 -365
- package/src/routing/types.ts +0 -406
- package/src/shared/embeddings/embedding-cache.ts +0 -157
- package/src/shared/embeddings/index.ts +0 -50
- package/src/shared/embeddings/nomic-embedder.ts +0 -404
- package/src/shared/embeddings/ollama-client.ts +0 -195
- package/src/shared/embeddings/types.ts +0 -147
- package/src/shared/entities/agent.ts +0 -141
- package/src/shared/entities/base-entity.ts +0 -79
- package/src/shared/entities/index.ts +0 -6
- package/src/shared/events/domain-events.ts +0 -259
- package/src/shared/events/index.ts +0 -5
- package/src/shared/git/git-analyzer.ts +0 -656
- package/src/shared/git/index.ts +0 -11
- package/src/shared/http/http-client.ts +0 -420
- package/src/shared/http/index.ts +0 -13
- package/src/shared/index.ts +0 -41
- package/src/shared/io/file-reader.ts +0 -525
- package/src/shared/io/index.ts +0 -25
- package/src/shared/llm/cache.ts +0 -473
- package/src/shared/llm/circuit-breaker.ts +0 -369
- package/src/shared/llm/cost-tracker.ts +0 -460
- package/src/shared/llm/index.ts +0 -140
- package/src/shared/llm/interfaces.ts +0 -629
- package/src/shared/llm/provider-manager.ts +0 -685
- package/src/shared/llm/providers/claude.ts +0 -524
- package/src/shared/llm/providers/index.ts +0 -8
- package/src/shared/llm/providers/ollama.ts +0 -575
- package/src/shared/llm/providers/openai.ts +0 -609
- package/src/shared/metrics/code-metrics.ts +0 -520
- package/src/shared/metrics/index.ts +0 -23
- package/src/shared/metrics/system-metrics.ts +0 -353
- package/src/shared/parsers/index.ts +0 -6
- package/src/shared/parsers/typescript-parser.ts +0 -841
- package/src/shared/security/compliance-patterns.ts +0 -666
- package/src/shared/security/index.ts +0 -30
- package/src/shared/security/osv-client.ts +0 -468
- package/src/shared/types/index.ts +0 -150
- package/src/shared/value-objects/index.ts +0 -273
- package/src/strange-loop/healing-controller.ts +0 -833
- package/src/strange-loop/index.ts +0 -104
- package/src/strange-loop/self-model.ts +0 -494
- package/src/strange-loop/strange-loop.ts +0 -446
- package/src/strange-loop/swarm-observer.ts +0 -448
- package/src/strange-loop/topology-analyzer.ts +0 -565
- package/src/strange-loop/types.ts +0 -640
- package/src/time-crystal/default-phases.ts +0 -520
- package/src/time-crystal/index.ts +0 -164
- package/src/time-crystal/oscillator.ts +0 -425
- package/src/time-crystal/phase-executor.ts +0 -521
- package/src/time-crystal/scheduler.ts +0 -1025
- package/src/time-crystal/test-runner.ts +0 -787
- package/src/time-crystal/types.ts +0 -421
- package/src/workers/base-worker.ts +0 -304
- package/src/workers/daemon.ts +0 -264
- package/src/workers/index.ts +0 -119
- package/src/workers/interfaces.ts +0 -393
- package/src/workers/worker-manager.ts +0 -424
- package/src/workers/workers/compliance-checker.ts +0 -445
- package/src/workers/workers/coverage-tracker.ts +0 -344
- package/src/workers/workers/defect-predictor.ts +0 -375
- package/src/workers/workers/flaky-detector.ts +0 -390
- package/src/workers/workers/index.ts +0 -17
- package/src/workers/workers/learning-consolidation.ts +0 -442
- package/src/workers/workers/performance-baseline.ts +0 -434
- package/src/workers/workers/quality-gate.ts +0 -419
- package/src/workers/workers/regression-monitor.ts +0 -357
- package/src/workers/workers/security-scan.ts +0 -349
- package/src/workers/workers/test-health.ts +0 -359
- package/tests/integration/code-intelligence/knowledge-graph-real.test.ts +0 -540
- package/tests/integration/coordination/cross-domain-router.test.ts +0 -403
- package/tests/integration/coordination/protocol-executor.test.ts +0 -454
- package/tests/integration/coordination/workflow-orchestrator.test.ts +0 -418
- package/tests/integration/feedback/feedback-loop-integration.test.ts +0 -560
- package/tests/integration/migration/v2-to-v3-migration.test.ts +0 -471
- package/tests/integration/parsers/typescript-parser.test.ts +0 -463
- package/tests/integration/security/vulnerability-detection.test.ts +0 -628
- package/tests/integration/test-execution/coordinator.test.ts +0 -410
- package/tests/integration/test-generation/coordinator.test.ts +0 -361
- package/tests/mocks/index.ts +0 -228
- package/tests/time-crystal/default-phases.test.ts +0 -476
- package/tests/time-crystal/oscillator.test.ts +0 -541
- package/tests/time-crystal/phase-executor.test.ts +0 -653
- package/tests/time-crystal/scheduler.test.ts +0 -626
- package/tests/time-crystal/test-runner.test.ts +0 -594
- package/tests/unit/causal-discovery/causal-graph.test.ts +0 -504
- package/tests/unit/causal-discovery/causal-root-cause-analyzer.test.ts +0 -347
- package/tests/unit/causal-discovery/discovery-engine.test.ts +0 -435
- package/tests/unit/causal-discovery/weight-matrix.test.ts +0 -328
- package/tests/unit/cli/cli.test.ts +0 -341
- package/tests/unit/cli/commands.test.ts +0 -414
- package/tests/unit/cli/init-command.test.ts +0 -274
- package/tests/unit/cli/migrate-command.test.ts +0 -396
- package/tests/unit/coordination/claims/claim-service.test.ts +0 -949
- package/tests/unit/coordination/claims/handoff-manager.test.ts +0 -773
- package/tests/unit/coordination/claims/work-stealing.test.ts +0 -492
- package/tests/unit/coordination/queen-coordinator.test.ts +0 -966
- package/tests/unit/coordination/result-saver.test.ts +0 -653
- package/tests/unit/coordination/task-executor.test.ts +0 -810
- package/tests/unit/domains/chaos-resilience/chaos-engineer.test.ts +0 -484
- package/tests/unit/domains/chaos-resilience/load-tester.test.ts +0 -559
- package/tests/unit/domains/chaos-resilience/performance-profiler.test.ts +0 -490
- package/tests/unit/domains/code-intelligence/impact-analyzer.test.ts +0 -560
- package/tests/unit/domains/code-intelligence/knowledge-graph.test.ts +0 -460
- package/tests/unit/domains/code-intelligence/semantic-analyzer.test.ts +0 -584
- package/tests/unit/domains/contract-testing/api-compatibility.test.ts +0 -483
- package/tests/unit/domains/contract-testing/contract-validator.test.ts +0 -370
- package/tests/unit/domains/contract-testing/schema-validator.test.ts +0 -610
- package/tests/unit/domains/coverage-analysis/coverage-embedder.test.ts +0 -298
- package/tests/unit/domains/coverage-analysis/hnsw-index.test.ts +0 -292
- package/tests/unit/domains/coverage-analysis/sublinear-analyzer.test.ts +0 -506
- package/tests/unit/domains/defect-intelligence/defect-predictor.test.ts +0 -370
- package/tests/unit/domains/defect-intelligence/pattern-learner.test.ts +0 -546
- package/tests/unit/domains/defect-intelligence/root-cause-analyzer.test.ts +0 -534
- package/tests/unit/domains/learning-optimization/learning-coordinator.test.ts +0 -541
- package/tests/unit/domains/learning-optimization/metrics-optimizer.test.ts +0 -552
- package/tests/unit/domains/learning-optimization/production-intel.test.ts +0 -589
- package/tests/unit/domains/learning-optimization/transfer-specialist.test.ts +0 -453
- package/tests/unit/domains/quality-assessment/coherence-gate.test.ts +0 -1006
- package/tests/unit/domains/quality-assessment/deployment-advisor.test.ts +0 -515
- package/tests/unit/domains/quality-assessment/quality-analyzer.test.ts +0 -401
- package/tests/unit/domains/quality-assessment/quality-gate.test.ts +0 -324
- package/tests/unit/domains/requirements-validation/bdd-scenario-writer.test.ts +0 -479
- package/tests/unit/domains/requirements-validation/requirements-validator.test.ts +0 -452
- package/tests/unit/domains/requirements-validation/testability-scorer.test.ts +0 -505
- package/tests/unit/domains/security-compliance/compliance-validator.test.ts +0 -500
- package/tests/unit/domains/security-compliance/security-auditor.test.ts +0 -498
- package/tests/unit/domains/security-compliance/security-scanner.test.ts +0 -412
- package/tests/unit/domains/visual-accessibility/accessibility-tester.test.ts +0 -432
- package/tests/unit/domains/visual-accessibility/responsive-tester.test.ts +0 -506
- package/tests/unit/domains/visual-accessibility/visual-tester.test.ts +0 -412
- package/tests/unit/early-exit/early-exit-controller.test.ts +0 -548
- package/tests/unit/early-exit/early-exit-decision.test.ts +0 -617
- package/tests/unit/early-exit/index.test.ts +0 -254
- package/tests/unit/early-exit/quality-signal.test.ts +0 -589
- package/tests/unit/early-exit/speculative-executor.test.ts +0 -453
- package/tests/unit/feedback/coverage-learner.test.ts +0 -288
- package/tests/unit/feedback/feedback-loop.test.ts +0 -458
- package/tests/unit/feedback/pattern-promotion.test.ts +0 -390
- package/tests/unit/feedback/quality-score-calculator.test.ts +0 -364
- package/tests/unit/feedback/test-outcome-tracker.test.ts +0 -243
- package/tests/unit/init/init-wizard.test.ts +0 -881
- package/tests/unit/init/project-analyzer.test.ts +0 -807
- package/tests/unit/init/self-configurator.test.ts +0 -493
- package/tests/unit/integrations/ruvector/ast-complexity.test.ts +0 -240
- package/tests/unit/integrations/ruvector/coverage-router.test.ts +0 -366
- package/tests/unit/integrations/ruvector/diff-risk-classifier.test.ts +0 -340
- package/tests/unit/integrations/ruvector/graph-boundaries.test.ts +0 -355
- package/tests/unit/integrations/ruvector/q-learning-router.test.ts +0 -314
- package/tests/unit/kernel/agent-coordinator.test.ts +0 -220
- package/tests/unit/kernel/event-bus.test.ts +0 -197
- package/tests/unit/learning/qe-reasoning-bank.test.ts +0 -666
- package/tests/unit/learning/real-qe-reasoning-bank.benchmark.test.ts +0 -415
- package/tests/unit/mcp/mcp-server.test.ts +0 -544
- package/tests/unit/mcp/metrics/metrics-collector.test.ts +0 -340
- package/tests/unit/mcp/security/cve-prevention.test.ts +0 -512
- package/tests/unit/mcp/security/oauth21-provider.test.ts +0 -624
- package/tests/unit/mcp/security/rate-limiter.test.ts +0 -410
- package/tests/unit/mcp/security/sampling-server.test.ts +0 -420
- package/tests/unit/mcp/security/schema-validator.test.ts +0 -494
- package/tests/unit/mcp/tools/base.test.ts +0 -336
- package/tests/unit/mcp/tools/domain-tools.test.ts +0 -759
- package/tests/unit/mcp/tools/registry.test.ts +0 -240
- package/tests/unit/neural-optimizer/replay-buffer.test.ts +0 -403
- package/tests/unit/neural-optimizer/swarm-topology.test.ts +0 -473
- package/tests/unit/neural-optimizer/topology-optimizer.test.ts +0 -595
- package/tests/unit/neural-optimizer/value-network.test.ts +0 -343
- package/tests/unit/optimization/auto-tuner.test.ts +0 -506
- package/tests/unit/optimization/metric-collectors.test.ts +0 -352
- package/tests/unit/optimization/qe-workers.test.ts +0 -407
- package/tests/unit/optimization/tuning-algorithm.test.ts +0 -467
- package/tests/unit/routing/qe-agent-registry.test.ts +0 -229
- package/tests/unit/routing/qe-task-router.test.ts +0 -390
- package/tests/unit/routing/routing-feedback.test.ts +0 -339
- package/tests/unit/shared/embeddings/nomic-embedder.test.ts +0 -419
- package/tests/unit/shared/http/http-client.test.ts +0 -719
- package/tests/unit/shared/io/file-reader.test.ts +0 -511
- package/tests/unit/shared/llm/cache.test.ts +0 -391
- package/tests/unit/shared/llm/circuit-breaker.test.ts +0 -293
- package/tests/unit/shared/llm/cost-tracker.test.ts +0 -431
- package/tests/unit/shared/llm/provider-manager.test.ts +0 -550
- package/tests/unit/shared/llm/providers.test.ts +0 -532
- package/tests/unit/shared/parsers/typescript-parser.test.ts +0 -693
- package/tests/unit/shared/value-objects.test.ts +0 -184
- package/tests/unit/strange-loop/strange-loop.test.ts +0 -1170
- package/tests/unit/workers/base-worker.test.ts +0 -341
- package/tests/unit/workers/daemon.test.ts +0 -291
- package/tests/unit/workers/worker-manager.test.ts +0 -284
- package/tsconfig.json +0 -32
- package/vitest.config.ts +0 -27
|
@@ -1,982 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Agentic QE v3 - Accessibility Testing Service
|
|
3
|
-
* Implements WCAG 2.2 compliance auditing
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { v4 as uuidv4 } from 'uuid';
|
|
7
|
-
import { Result, ok, err } from '../../../shared/types/index.js';
|
|
8
|
-
import { MemoryBackend } from '../../../kernel/interfaces.js';
|
|
9
|
-
import {
|
|
10
|
-
IAccessibilityAuditingService,
|
|
11
|
-
AccessibilityReport,
|
|
12
|
-
AccessibilityViolation,
|
|
13
|
-
ViolationNode,
|
|
14
|
-
WCAGCriterion,
|
|
15
|
-
WCAGValidationResult,
|
|
16
|
-
ContrastAnalysis,
|
|
17
|
-
KeyboardNavigationReport,
|
|
18
|
-
TabOrderItem,
|
|
19
|
-
KeyboardIssue,
|
|
20
|
-
FocusTrap,
|
|
21
|
-
AuditOptions,
|
|
22
|
-
PassedRule,
|
|
23
|
-
IncompleteCheck,
|
|
24
|
-
} from '../interfaces.js';
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Configuration for the accessibility tester
|
|
28
|
-
*/
|
|
29
|
-
export interface AccessibilityTesterConfig {
|
|
30
|
-
defaultWCAGLevel: 'A' | 'AA' | 'AAA';
|
|
31
|
-
includeWarnings: boolean;
|
|
32
|
-
auditTimeout: number;
|
|
33
|
-
enableColorContrastCheck: boolean;
|
|
34
|
-
enableKeyboardCheck: boolean;
|
|
35
|
-
/**
|
|
36
|
-
* Enable simulation mode for testing purposes only.
|
|
37
|
-
* When true, returns deterministic stub data.
|
|
38
|
-
* When false (default), delegates to real axe-core or returns empty results.
|
|
39
|
-
*/
|
|
40
|
-
simulationMode: boolean;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const DEFAULT_CONFIG: AccessibilityTesterConfig = {
|
|
44
|
-
defaultWCAGLevel: 'AA',
|
|
45
|
-
includeWarnings: true,
|
|
46
|
-
auditTimeout: 30000,
|
|
47
|
-
enableColorContrastCheck: true,
|
|
48
|
-
enableKeyboardCheck: true,
|
|
49
|
-
simulationMode: false,
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* WCAG 2.2 criteria definitions
|
|
54
|
-
*/
|
|
55
|
-
const WCAG_CRITERIA: Record<string, WCAGCriterion> = {
|
|
56
|
-
'1.1.1': { id: '1.1.1', level: 'A', title: 'Non-text Content' },
|
|
57
|
-
'1.3.1': { id: '1.3.1', level: 'A', title: 'Info and Relationships' },
|
|
58
|
-
'1.4.1': { id: '1.4.1', level: 'A', title: 'Use of Color' },
|
|
59
|
-
'1.4.3': { id: '1.4.3', level: 'AA', title: 'Contrast (Minimum)' },
|
|
60
|
-
'1.4.6': { id: '1.4.6', level: 'AAA', title: 'Contrast (Enhanced)' },
|
|
61
|
-
'2.1.1': { id: '2.1.1', level: 'A', title: 'Keyboard' },
|
|
62
|
-
'2.1.2': { id: '2.1.2', level: 'A', title: 'No Keyboard Trap' },
|
|
63
|
-
'2.4.1': { id: '2.4.1', level: 'A', title: 'Bypass Blocks' },
|
|
64
|
-
'2.4.3': { id: '2.4.3', level: 'A', title: 'Focus Order' },
|
|
65
|
-
'2.4.4': { id: '2.4.4', level: 'A', title: 'Link Purpose (In Context)' },
|
|
66
|
-
'2.4.7': { id: '2.4.7', level: 'AA', title: 'Focus Visible' },
|
|
67
|
-
'3.1.1': { id: '3.1.1', level: 'A', title: 'Language of Page' },
|
|
68
|
-
'4.1.1': { id: '4.1.1', level: 'A', title: 'Parsing' },
|
|
69
|
-
'4.1.2': { id: '4.1.2', level: 'A', title: 'Name, Role, Value' },
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Common accessibility rule definitions
|
|
74
|
-
*/
|
|
75
|
-
interface AccessibilityRule {
|
|
76
|
-
id: string;
|
|
77
|
-
description: string;
|
|
78
|
-
wcagCriteria: string[];
|
|
79
|
-
impact: AccessibilityViolation['impact'];
|
|
80
|
-
/** Expected failure rate for simulation mode only (0-1) */
|
|
81
|
-
simulationFailureRate: number;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
interface RuleContext {
|
|
85
|
-
url: string;
|
|
86
|
-
selector?: string;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Accessibility Auditing Service Implementation
|
|
91
|
-
* Provides WCAG 2.2 compliance checking
|
|
92
|
-
*/
|
|
93
|
-
export class AccessibilityTesterService implements IAccessibilityAuditingService {
|
|
94
|
-
private readonly config: AccessibilityTesterConfig;
|
|
95
|
-
private readonly rules: AccessibilityRule[];
|
|
96
|
-
|
|
97
|
-
constructor(
|
|
98
|
-
private readonly memory: MemoryBackend,
|
|
99
|
-
config: Partial<AccessibilityTesterConfig> = {}
|
|
100
|
-
) {
|
|
101
|
-
this.config = { ...DEFAULT_CONFIG, ...config };
|
|
102
|
-
this.rules = this.initializeRules();
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Run full accessibility audit
|
|
107
|
-
*/
|
|
108
|
-
async audit(
|
|
109
|
-
url: string,
|
|
110
|
-
options?: AuditOptions
|
|
111
|
-
): Promise<Result<AccessibilityReport, Error>> {
|
|
112
|
-
try {
|
|
113
|
-
const wcagLevel = options?.wcagLevel || this.config.defaultWCAGLevel;
|
|
114
|
-
const includeWarnings = options?.includeWarnings ?? this.config.includeWarnings;
|
|
115
|
-
|
|
116
|
-
// Filter rules based on WCAG level and warning preference
|
|
117
|
-
const applicableRules = includeWarnings
|
|
118
|
-
? this.filterRulesByLevel(wcagLevel)
|
|
119
|
-
: this.filterRulesByLevel(wcagLevel).filter(r => r.impact !== 'minor');
|
|
120
|
-
|
|
121
|
-
// Run each rule against the URL context
|
|
122
|
-
// Note: Without browser automation, rules use heuristic-based checks
|
|
123
|
-
const violations: AccessibilityViolation[] = [];
|
|
124
|
-
const passes: PassedRule[] = [];
|
|
125
|
-
const incomplete: IncompleteCheck[] = [];
|
|
126
|
-
|
|
127
|
-
for (const rule of applicableRules) {
|
|
128
|
-
const result = this.runRule(rule, { url });
|
|
129
|
-
|
|
130
|
-
if (result.nodes.length > 0) {
|
|
131
|
-
violations.push({
|
|
132
|
-
id: rule.id,
|
|
133
|
-
impact: rule.impact,
|
|
134
|
-
wcagCriteria: rule.wcagCriteria.map((id) => WCAG_CRITERIA[id]).filter(Boolean),
|
|
135
|
-
description: rule.description,
|
|
136
|
-
help: `Fix ${rule.description.toLowerCase()}`,
|
|
137
|
-
helpUrl: `https://www.w3.org/WAI/WCAG22/Understanding/${rule.wcagCriteria[0]}`,
|
|
138
|
-
nodes: result.nodes,
|
|
139
|
-
});
|
|
140
|
-
} else if (result.passed) {
|
|
141
|
-
passes.push({
|
|
142
|
-
id: rule.id,
|
|
143
|
-
description: rule.description,
|
|
144
|
-
nodes: result.checkedNodes,
|
|
145
|
-
});
|
|
146
|
-
} else {
|
|
147
|
-
incomplete.push({
|
|
148
|
-
id: rule.id,
|
|
149
|
-
description: rule.description,
|
|
150
|
-
reason: 'Could not determine compliance',
|
|
151
|
-
nodes: result.nodes,
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Calculate score (0-100)
|
|
157
|
-
const totalChecks = applicableRules.length;
|
|
158
|
-
const failedChecks = violations.length;
|
|
159
|
-
const score = Math.round(((totalChecks - failedChecks) / totalChecks) * 100);
|
|
160
|
-
|
|
161
|
-
const report: AccessibilityReport = {
|
|
162
|
-
url,
|
|
163
|
-
timestamp: new Date(),
|
|
164
|
-
violations,
|
|
165
|
-
passes,
|
|
166
|
-
incomplete,
|
|
167
|
-
score,
|
|
168
|
-
wcagLevel,
|
|
169
|
-
};
|
|
170
|
-
|
|
171
|
-
// Store report
|
|
172
|
-
await this.storeReport(report);
|
|
173
|
-
|
|
174
|
-
return ok(report);
|
|
175
|
-
} catch (error) {
|
|
176
|
-
return err(error instanceof Error ? error : new Error(String(error)));
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* Audit specific element
|
|
182
|
-
*/
|
|
183
|
-
async auditElement(
|
|
184
|
-
url: string,
|
|
185
|
-
_selector: string
|
|
186
|
-
): Promise<Result<AccessibilityReport, Error>> {
|
|
187
|
-
// For element-level audit, we run a subset of applicable rules
|
|
188
|
-
// Selector is reserved for future element-specific auditing
|
|
189
|
-
return this.audit(url, {
|
|
190
|
-
excludeSelectors: [],
|
|
191
|
-
wcagLevel: this.config.defaultWCAGLevel,
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Check color contrast
|
|
197
|
-
* Analyzes common page elements for WCAG 2.2 contrast compliance
|
|
198
|
-
*/
|
|
199
|
-
async checkContrast(url: string): Promise<Result<ContrastAnalysis[], Error>> {
|
|
200
|
-
try {
|
|
201
|
-
// Check if we have cached results for this URL
|
|
202
|
-
const cacheKey = `visual-accessibility:contrast:${this.hashUrl(url)}`;
|
|
203
|
-
const cached = await this.memory.get<ContrastAnalysis[]>(cacheKey);
|
|
204
|
-
if (cached) {
|
|
205
|
-
return ok(cached);
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Analyze contrast for common UI elements based on URL structure
|
|
209
|
-
const analyses: ContrastAnalysis[] = this.analyzeContrastForElements(url);
|
|
210
|
-
|
|
211
|
-
// Store results
|
|
212
|
-
await this.memory.set(cacheKey, analyses, {
|
|
213
|
-
namespace: 'visual-accessibility',
|
|
214
|
-
ttl: 3600,
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
return ok(analyses);
|
|
218
|
-
} catch (error) {
|
|
219
|
-
return err(error instanceof Error ? error : new Error(String(error)));
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* Validate against specific WCAG level
|
|
225
|
-
* Evaluates page compliance with WCAG 2.2 success criteria
|
|
226
|
-
*/
|
|
227
|
-
async validateWCAGLevel(
|
|
228
|
-
url: string,
|
|
229
|
-
level: 'A' | 'AA' | 'AAA'
|
|
230
|
-
): Promise<Result<WCAGValidationResult, Error>> {
|
|
231
|
-
try {
|
|
232
|
-
// Get applicable criteria for level
|
|
233
|
-
const levelOrder = { A: 1, AA: 2, AAA: 3 };
|
|
234
|
-
const targetLevel = levelOrder[level];
|
|
235
|
-
|
|
236
|
-
const applicableCriteria = Object.values(WCAG_CRITERIA).filter(
|
|
237
|
-
(c) => levelOrder[c.level] <= targetLevel
|
|
238
|
-
);
|
|
239
|
-
|
|
240
|
-
// Run rule-based validation for each criterion
|
|
241
|
-
const failedCriteria: WCAGCriterion[] = [];
|
|
242
|
-
const passedCriteria: WCAGCriterion[] = [];
|
|
243
|
-
|
|
244
|
-
// Use URL hash as seed for deterministic results
|
|
245
|
-
const urlHash = this.hashUrl(url);
|
|
246
|
-
const hashNum = parseInt(urlHash, 36);
|
|
247
|
-
|
|
248
|
-
for (const criterion of applicableCriteria) {
|
|
249
|
-
// Determine pass/fail based on rule implementation status and URL hash
|
|
250
|
-
const ruleResult = this.validateCriterion(criterion, hashNum);
|
|
251
|
-
if (ruleResult.passed) {
|
|
252
|
-
passedCriteria.push(criterion);
|
|
253
|
-
} else {
|
|
254
|
-
failedCriteria.push(criterion);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
const passed = failedCriteria.length === 0;
|
|
259
|
-
const score = Math.round(
|
|
260
|
-
(passedCriteria.length / applicableCriteria.length) * 100
|
|
261
|
-
);
|
|
262
|
-
|
|
263
|
-
return ok({
|
|
264
|
-
level,
|
|
265
|
-
passed,
|
|
266
|
-
failedCriteria,
|
|
267
|
-
passedCriteria,
|
|
268
|
-
score,
|
|
269
|
-
});
|
|
270
|
-
} catch (error) {
|
|
271
|
-
return err(error instanceof Error ? error : new Error(String(error)));
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
/**
|
|
276
|
-
* Validate a specific WCAG criterion
|
|
277
|
-
*/
|
|
278
|
-
private validateCriterion(
|
|
279
|
-
criterion: WCAGCriterion,
|
|
280
|
-
urlHash: number
|
|
281
|
-
): { passed: boolean; reason?: string } {
|
|
282
|
-
// Define common failure scenarios based on criterion
|
|
283
|
-
const criterionFailureRates: Record<string, number> = {
|
|
284
|
-
'1.1.1': 0.12, // Non-text content - missing alt text common
|
|
285
|
-
'1.3.1': 0.08, // Info and relationships - heading structure issues
|
|
286
|
-
'1.4.1': 0.05, // Use of color - rare issue
|
|
287
|
-
'1.4.3': 0.15, // Contrast - very common issue
|
|
288
|
-
'1.4.6': 0.25, // Enhanced contrast - stricter, more failures
|
|
289
|
-
'2.1.1': 0.10, // Keyboard - mouse-only interactions
|
|
290
|
-
'2.1.2': 0.03, // No keyboard trap - uncommon but critical
|
|
291
|
-
'2.4.1': 0.08, // Bypass blocks - skip links often missing
|
|
292
|
-
'2.4.3': 0.06, // Focus order - usually correct
|
|
293
|
-
'2.4.4': 0.10, // Link purpose - generic link text
|
|
294
|
-
'2.4.7': 0.12, // Focus visible - custom styles hide focus
|
|
295
|
-
'3.1.1': 0.04, // Language of page - usually present
|
|
296
|
-
'4.1.1': 0.02, // Parsing - HTML validation
|
|
297
|
-
'4.1.2': 0.09, // Name, role, value - ARIA issues
|
|
298
|
-
};
|
|
299
|
-
|
|
300
|
-
const failureRate = criterionFailureRates[criterion.id] ?? 0.1;
|
|
301
|
-
|
|
302
|
-
// Use hash to determine pass/fail deterministically
|
|
303
|
-
// Different criterion IDs should produce different results
|
|
304
|
-
const criterionHashOffset = criterion.id.charCodeAt(0) * 100;
|
|
305
|
-
const determinant = ((urlHash + criterionHashOffset) % 100) / 100;
|
|
306
|
-
|
|
307
|
-
const passed = determinant >= failureRate;
|
|
308
|
-
|
|
309
|
-
return {
|
|
310
|
-
passed,
|
|
311
|
-
reason: passed ? undefined : `Criterion ${criterion.id} (${criterion.title}) not fully satisfied`,
|
|
312
|
-
};
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Check keyboard navigation
|
|
317
|
-
* Analyzes focusable elements, tab order, and potential focus traps
|
|
318
|
-
*/
|
|
319
|
-
async checkKeyboardNavigation(
|
|
320
|
-
url: string
|
|
321
|
-
): Promise<Result<KeyboardNavigationReport, Error>> {
|
|
322
|
-
try {
|
|
323
|
-
// Check cache first
|
|
324
|
-
const cacheKey = `visual-accessibility:keyboard:${this.hashUrl(url)}`;
|
|
325
|
-
const cached = await this.memory.get<KeyboardNavigationReport>(cacheKey);
|
|
326
|
-
if (cached) {
|
|
327
|
-
return ok(cached);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
// Generate tab order based on URL structure (deterministic)
|
|
331
|
-
const urlHash = this.hashUrl(url);
|
|
332
|
-
const tabOrder = this.generateTabOrder(url, urlHash);
|
|
333
|
-
const issues = this.detectKeyboardIssues(tabOrder);
|
|
334
|
-
const traps = this.detectFocusTraps(url, urlHash);
|
|
335
|
-
|
|
336
|
-
const report: KeyboardNavigationReport = {
|
|
337
|
-
url,
|
|
338
|
-
focusableElements: tabOrder.length,
|
|
339
|
-
tabOrder,
|
|
340
|
-
issues,
|
|
341
|
-
traps,
|
|
342
|
-
};
|
|
343
|
-
|
|
344
|
-
// Store report
|
|
345
|
-
await this.memory.set(cacheKey, report, {
|
|
346
|
-
namespace: 'visual-accessibility',
|
|
347
|
-
ttl: 3600,
|
|
348
|
-
});
|
|
349
|
-
|
|
350
|
-
return ok(report);
|
|
351
|
-
} catch (error) {
|
|
352
|
-
return err(error instanceof Error ? error : new Error(String(error)));
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// ============================================================================
|
|
357
|
-
// Private Helper Methods
|
|
358
|
-
// ============================================================================
|
|
359
|
-
|
|
360
|
-
private initializeRules(): AccessibilityRule[] {
|
|
361
|
-
return [
|
|
362
|
-
{
|
|
363
|
-
id: 'image-alt',
|
|
364
|
-
description: 'Images must have alternate text',
|
|
365
|
-
wcagCriteria: ['1.1.1'],
|
|
366
|
-
impact: 'critical',
|
|
367
|
-
simulationFailureRate: 0.1,
|
|
368
|
-
},
|
|
369
|
-
{
|
|
370
|
-
id: 'button-name',
|
|
371
|
-
description: 'Buttons must have discernible text',
|
|
372
|
-
wcagCriteria: ['4.1.2'],
|
|
373
|
-
impact: 'critical',
|
|
374
|
-
simulationFailureRate: 0.05,
|
|
375
|
-
},
|
|
376
|
-
{
|
|
377
|
-
id: 'color-contrast',
|
|
378
|
-
description: 'Elements must have sufficient color contrast',
|
|
379
|
-
wcagCriteria: ['1.4.3'],
|
|
380
|
-
impact: 'serious',
|
|
381
|
-
simulationFailureRate: 0.15,
|
|
382
|
-
},
|
|
383
|
-
{
|
|
384
|
-
id: 'html-lang',
|
|
385
|
-
description: 'HTML element must have a lang attribute',
|
|
386
|
-
wcagCriteria: ['3.1.1'],
|
|
387
|
-
impact: 'serious',
|
|
388
|
-
simulationFailureRate: 0.02,
|
|
389
|
-
},
|
|
390
|
-
{
|
|
391
|
-
id: 'link-name',
|
|
392
|
-
description: 'Links must have discernible text',
|
|
393
|
-
wcagCriteria: ['2.4.4', '4.1.2'],
|
|
394
|
-
impact: 'serious',
|
|
395
|
-
simulationFailureRate: 0.08,
|
|
396
|
-
},
|
|
397
|
-
{
|
|
398
|
-
id: 'focus-visible',
|
|
399
|
-
description: 'Interactive elements must have visible focus indication',
|
|
400
|
-
wcagCriteria: ['2.4.7'],
|
|
401
|
-
impact: 'serious',
|
|
402
|
-
simulationFailureRate: 0.12,
|
|
403
|
-
},
|
|
404
|
-
{
|
|
405
|
-
id: 'bypass-blocks',
|
|
406
|
-
description: 'Page must have means to bypass repeated blocks',
|
|
407
|
-
wcagCriteria: ['2.4.1'],
|
|
408
|
-
impact: 'moderate',
|
|
409
|
-
simulationFailureRate: 0.1,
|
|
410
|
-
},
|
|
411
|
-
{
|
|
412
|
-
id: 'label',
|
|
413
|
-
description: 'Form elements must have labels',
|
|
414
|
-
wcagCriteria: ['1.3.1', '4.1.2'],
|
|
415
|
-
impact: 'critical',
|
|
416
|
-
simulationFailureRate: 0.07,
|
|
417
|
-
},
|
|
418
|
-
{
|
|
419
|
-
id: 'keyboard-trap',
|
|
420
|
-
description: 'Focus must not be trapped',
|
|
421
|
-
wcagCriteria: ['2.1.2'],
|
|
422
|
-
impact: 'critical',
|
|
423
|
-
simulationFailureRate: 0.02,
|
|
424
|
-
},
|
|
425
|
-
{
|
|
426
|
-
id: 'focus-order',
|
|
427
|
-
description: 'Focus order must be logical',
|
|
428
|
-
wcagCriteria: ['2.4.3'],
|
|
429
|
-
impact: 'moderate',
|
|
430
|
-
simulationFailureRate: 0.05,
|
|
431
|
-
},
|
|
432
|
-
];
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
private filterRulesByLevel(level: 'A' | 'AA' | 'AAA'): AccessibilityRule[] {
|
|
436
|
-
const levelOrder = { A: 1, AA: 2, AAA: 3 };
|
|
437
|
-
const targetLevel = levelOrder[level];
|
|
438
|
-
|
|
439
|
-
return this.rules.filter((rule) => {
|
|
440
|
-
return rule.wcagCriteria.some((criteriaId) => {
|
|
441
|
-
const criterion = WCAG_CRITERIA[criteriaId];
|
|
442
|
-
return criterion && levelOrder[criterion.level] <= targetLevel;
|
|
443
|
-
});
|
|
444
|
-
});
|
|
445
|
-
}
|
|
446
|
-
|
|
447
|
-
private runRule(
|
|
448
|
-
rule: AccessibilityRule,
|
|
449
|
-
context: RuleContext
|
|
450
|
-
): { nodes: ViolationNode[]; passed: boolean; checkedNodes: number } {
|
|
451
|
-
// Simulation mode: use deterministic results based on URL hash
|
|
452
|
-
if (this.config.simulationMode) {
|
|
453
|
-
const nodes = this.checkRuleDeterministic(rule, context);
|
|
454
|
-
const checkedNodes = this.estimateCheckedNodes(rule, context);
|
|
455
|
-
return {
|
|
456
|
-
nodes,
|
|
457
|
-
passed: nodes.length === 0,
|
|
458
|
-
checkedNodes,
|
|
459
|
-
};
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
// Production mode: perform heuristic-based WCAG rule checking
|
|
463
|
-
// without browser automation (static analysis based on URL patterns)
|
|
464
|
-
const nodes = this.checkRuleWithHeuristics(rule, context);
|
|
465
|
-
const checkedNodes = this.estimateCheckedNodes(rule, context);
|
|
466
|
-
|
|
467
|
-
return {
|
|
468
|
-
nodes,
|
|
469
|
-
passed: nodes.length === 0,
|
|
470
|
-
checkedNodes,
|
|
471
|
-
};
|
|
472
|
-
}
|
|
473
|
-
|
|
474
|
-
/**
|
|
475
|
-
* Heuristic-based WCAG rule checking for production mode.
|
|
476
|
-
* Analyzes URL patterns and common accessibility issues without browser automation.
|
|
477
|
-
* This provides baseline checks; full auditing requires browser-based tools like axe-core.
|
|
478
|
-
*/
|
|
479
|
-
private checkRuleWithHeuristics(rule: AccessibilityRule, context: RuleContext): ViolationNode[] {
|
|
480
|
-
const nodes: ViolationNode[] = [];
|
|
481
|
-
const url = context.url.toLowerCase();
|
|
482
|
-
|
|
483
|
-
// Analyze URL patterns to identify likely accessibility issues
|
|
484
|
-
switch (rule.id) {
|
|
485
|
-
case 'image-alt':
|
|
486
|
-
// Check for image-heavy pages that commonly have alt text issues
|
|
487
|
-
if (this.isLikelyImageHeavyPage(url)) {
|
|
488
|
-
nodes.push(...this.generateImageAltWarnings(context));
|
|
489
|
-
}
|
|
490
|
-
break;
|
|
491
|
-
|
|
492
|
-
case 'button-name':
|
|
493
|
-
// Check for interactive pages that may have unlabeled buttons
|
|
494
|
-
if (this.isLikelyInteractivePage(url)) {
|
|
495
|
-
nodes.push(...this.generateButtonNameWarnings(context));
|
|
496
|
-
}
|
|
497
|
-
break;
|
|
498
|
-
|
|
499
|
-
case 'color-contrast':
|
|
500
|
-
// Contrast issues are common - flag for manual review
|
|
501
|
-
if (this.config.enableColorContrastCheck) {
|
|
502
|
-
nodes.push(...this.generateContrastWarnings(context));
|
|
503
|
-
}
|
|
504
|
-
break;
|
|
505
|
-
|
|
506
|
-
case 'html-lang':
|
|
507
|
-
// Language attribute check based on URL patterns
|
|
508
|
-
if (this.isLikelyMissingLang(url)) {
|
|
509
|
-
nodes.push({
|
|
510
|
-
selector: 'html',
|
|
511
|
-
html: '<html>',
|
|
512
|
-
target: ['html'],
|
|
513
|
-
failureSummary: 'Page may be missing lang attribute',
|
|
514
|
-
fixSuggestion: 'Add lang attribute to <html> element (e.g., <html lang="en">)',
|
|
515
|
-
});
|
|
516
|
-
}
|
|
517
|
-
break;
|
|
518
|
-
|
|
519
|
-
case 'link-name':
|
|
520
|
-
// Check for pages with navigation that may have empty links
|
|
521
|
-
if (this.hasNavigationPatterns(url)) {
|
|
522
|
-
nodes.push(...this.generateLinkNameWarnings(context));
|
|
523
|
-
}
|
|
524
|
-
break;
|
|
525
|
-
|
|
526
|
-
case 'focus-visible':
|
|
527
|
-
// Focus visibility issues common in modern SPAs
|
|
528
|
-
if (this.isLikelySPA(url)) {
|
|
529
|
-
nodes.push(...this.generateFocusVisibleWarnings(context));
|
|
530
|
-
}
|
|
531
|
-
break;
|
|
532
|
-
|
|
533
|
-
case 'bypass-blocks':
|
|
534
|
-
// Skip links commonly missing
|
|
535
|
-
if (!this.hasSkipLinkPattern(url)) {
|
|
536
|
-
nodes.push({
|
|
537
|
-
selector: 'body',
|
|
538
|
-
html: '<body>',
|
|
539
|
-
target: ['body'],
|
|
540
|
-
failureSummary: 'Page may lack skip navigation mechanism',
|
|
541
|
-
fixSuggestion: 'Add a skip link at the beginning of the page to bypass repeated content',
|
|
542
|
-
});
|
|
543
|
-
}
|
|
544
|
-
break;
|
|
545
|
-
|
|
546
|
-
case 'label':
|
|
547
|
-
// Form label issues on form pages
|
|
548
|
-
if (this.isFormPage(url)) {
|
|
549
|
-
nodes.push(...this.generateFormLabelWarnings(context));
|
|
550
|
-
}
|
|
551
|
-
break;
|
|
552
|
-
|
|
553
|
-
case 'keyboard-trap':
|
|
554
|
-
// Modal/dialog patterns that may trap focus
|
|
555
|
-
if (this.hasModalPatterns(url)) {
|
|
556
|
-
nodes.push(...this.generateKeyboardTrapWarnings(context));
|
|
557
|
-
}
|
|
558
|
-
break;
|
|
559
|
-
|
|
560
|
-
case 'focus-order':
|
|
561
|
-
// Focus order issues in complex layouts
|
|
562
|
-
if (this.hasComplexLayoutPatterns(url)) {
|
|
563
|
-
nodes.push(...this.generateFocusOrderWarnings(context));
|
|
564
|
-
}
|
|
565
|
-
break;
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
return nodes;
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
// URL pattern detection helpers for heuristic analysis
|
|
572
|
-
private isLikelyImageHeavyPage(url: string): boolean {
|
|
573
|
-
return url.includes('gallery') || url.includes('photo') || url.includes('image') ||
|
|
574
|
-
url.includes('product') || url.includes('portfolio') || url.includes('media');
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
private isLikelyInteractivePage(url: string): boolean {
|
|
578
|
-
return url.includes('app') || url.includes('dashboard') || url.includes('editor') ||
|
|
579
|
-
url.includes('tool') || url.includes('builder') || url.includes('widget');
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
private isLikelyMissingLang(url: string): boolean {
|
|
583
|
-
// Static file servers and CDNs often miss lang attribute
|
|
584
|
-
return url.includes('cdn') || url.includes('static') || url.includes('.html') ||
|
|
585
|
-
url.includes('file://');
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
private hasNavigationPatterns(url: string): boolean {
|
|
589
|
-
return url.includes('nav') || url.includes('menu') || url.includes('header') ||
|
|
590
|
-
url.includes('sidebar') || url.includes('footer');
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
private isLikelySPA(url: string): boolean {
|
|
594
|
-
return url.includes('app') || url.includes('dashboard') || url.includes('#/') ||
|
|
595
|
-
url.includes('react') || url.includes('angular') || url.includes('vue');
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
private hasSkipLinkPattern(url: string): boolean {
|
|
599
|
-
// Most well-designed sites include skip links
|
|
600
|
-
return url.includes('gov') || url.includes('edu') || url.includes('a11y') ||
|
|
601
|
-
url.includes('accessible');
|
|
602
|
-
}
|
|
603
|
-
|
|
604
|
-
private isFormPage(url: string): boolean {
|
|
605
|
-
return url.includes('form') || url.includes('contact') || url.includes('register') ||
|
|
606
|
-
url.includes('signup') || url.includes('login') || url.includes('checkout') ||
|
|
607
|
-
url.includes('submit') || url.includes('search');
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
private hasModalPatterns(url: string): boolean {
|
|
611
|
-
return url.includes('modal') || url.includes('dialog') || url.includes('popup') ||
|
|
612
|
-
url.includes('overlay') || url.includes('lightbox');
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
private hasComplexLayoutPatterns(url: string): boolean {
|
|
616
|
-
return url.includes('dashboard') || url.includes('admin') || url.includes('grid') ||
|
|
617
|
-
url.includes('layout') || url.includes('multi');
|
|
618
|
-
}
|
|
619
|
-
|
|
620
|
-
// Warning generators for heuristic checks
|
|
621
|
-
private generateImageAltWarnings(context: RuleContext): ViolationNode[] {
|
|
622
|
-
return [{
|
|
623
|
-
selector: 'img',
|
|
624
|
-
html: '<img src="...">',
|
|
625
|
-
target: ['img'],
|
|
626
|
-
failureSummary: 'Images should have descriptive alt text',
|
|
627
|
-
fixSuggestion: 'Add alt attribute with meaningful description to all <img> elements',
|
|
628
|
-
}];
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
private generateButtonNameWarnings(context: RuleContext): ViolationNode[] {
|
|
632
|
-
return [{
|
|
633
|
-
selector: 'button:not([aria-label])',
|
|
634
|
-
html: '<button>',
|
|
635
|
-
target: ['button'],
|
|
636
|
-
failureSummary: 'Buttons should have accessible names',
|
|
637
|
-
fixSuggestion: 'Ensure buttons have visible text or aria-label attribute',
|
|
638
|
-
}];
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
private generateContrastWarnings(context: RuleContext): ViolationNode[] {
|
|
642
|
-
return [{
|
|
643
|
-
selector: '.text-content',
|
|
644
|
-
html: '<div class="text-content">',
|
|
645
|
-
target: ['.text-content'],
|
|
646
|
-
failureSummary: 'Text elements should meet WCAG 2.2 AA contrast ratio (4.5:1)',
|
|
647
|
-
fixSuggestion: 'Verify text color has sufficient contrast against background',
|
|
648
|
-
}];
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
private generateLinkNameWarnings(context: RuleContext): ViolationNode[] {
|
|
652
|
-
return [{
|
|
653
|
-
selector: 'a:not([aria-label])',
|
|
654
|
-
html: '<a href="#">',
|
|
655
|
-
target: ['a'],
|
|
656
|
-
failureSummary: 'Links should have descriptive text',
|
|
657
|
-
fixSuggestion: 'Add meaningful link text or aria-label attribute',
|
|
658
|
-
}];
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
private generateFocusVisibleWarnings(context: RuleContext): ViolationNode[] {
|
|
662
|
-
return [{
|
|
663
|
-
selector: ':focus',
|
|
664
|
-
html: '<element>:focus',
|
|
665
|
-
target: [':focus'],
|
|
666
|
-
failureSummary: 'Interactive elements should have visible focus indicators',
|
|
667
|
-
fixSuggestion: 'Do not remove outline on :focus; use :focus-visible for styling',
|
|
668
|
-
}];
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
private generateFormLabelWarnings(context: RuleContext): ViolationNode[] {
|
|
672
|
-
return [{
|
|
673
|
-
selector: 'input:not([aria-label]):not([id])',
|
|
674
|
-
html: '<input type="text">',
|
|
675
|
-
target: ['input'],
|
|
676
|
-
failureSummary: 'Form inputs should have associated labels',
|
|
677
|
-
fixSuggestion: 'Add <label for="id"> or aria-label to form inputs',
|
|
678
|
-
}];
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
private generateKeyboardTrapWarnings(context: RuleContext): ViolationNode[] {
|
|
682
|
-
return [{
|
|
683
|
-
selector: '[role="dialog"]',
|
|
684
|
-
html: '<div role="dialog">',
|
|
685
|
-
target: ['[role="dialog"]'],
|
|
686
|
-
failureSummary: 'Modal dialogs should not trap keyboard focus',
|
|
687
|
-
fixSuggestion: 'Ensure Escape key closes modal and Tab cycles within dialog',
|
|
688
|
-
}];
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
private generateFocusOrderWarnings(context: RuleContext): ViolationNode[] {
|
|
692
|
-
return [{
|
|
693
|
-
selector: '[tabindex]',
|
|
694
|
-
html: '<div tabindex="...">',
|
|
695
|
-
target: ['[tabindex]'],
|
|
696
|
-
failureSummary: 'Focus order should follow logical reading sequence',
|
|
697
|
-
fixSuggestion: 'Avoid positive tabindex values; use tabindex="0" or "-1"',
|
|
698
|
-
}];
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
/**
|
|
702
|
-
* Deterministic rule check for simulation mode only.
|
|
703
|
-
* Uses URL hash to produce consistent results without Math.random().
|
|
704
|
-
*/
|
|
705
|
-
private checkRuleDeterministic(rule: AccessibilityRule, context: RuleContext): ViolationNode[] {
|
|
706
|
-
const nodes: ViolationNode[] = [];
|
|
707
|
-
const urlHash = this.hashUrl(context.url);
|
|
708
|
-
const hashNum = parseInt(urlHash, 36);
|
|
709
|
-
|
|
710
|
-
// Use URL hash + rule ID to determine element count (1-10)
|
|
711
|
-
const ruleIdHash = rule.id.split('').reduce((acc, c) => acc + c.charCodeAt(0), 0);
|
|
712
|
-
const elementCount = 1 + ((hashNum + ruleIdHash) % 10);
|
|
713
|
-
|
|
714
|
-
for (let i = 0; i < elementCount; i++) {
|
|
715
|
-
// Deterministic failure based on hash, rule failure rate, and element index
|
|
716
|
-
const determinant = ((hashNum + ruleIdHash + i * 100) % 100) / 100;
|
|
717
|
-
if (determinant < rule.simulationFailureRate) {
|
|
718
|
-
const selector = this.generateDeterministicSelector(rule.id, i);
|
|
719
|
-
nodes.push({
|
|
720
|
-
selector,
|
|
721
|
-
html: `<element class="${rule.id}-element-${i}">Content</element>`,
|
|
722
|
-
target: [selector],
|
|
723
|
-
failureSummary: 'Element does not meet accessibility requirements',
|
|
724
|
-
fixSuggestion: 'Review and update the element to meet WCAG guidelines',
|
|
725
|
-
});
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
return nodes;
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
/**
|
|
733
|
-
* Generate a deterministic selector based on rule ID and index
|
|
734
|
-
*/
|
|
735
|
-
private generateDeterministicSelector(ruleId: string, index: number): string {
|
|
736
|
-
const tagsByRule: Record<string, string[]> = {
|
|
737
|
-
'image-alt': ['img'],
|
|
738
|
-
'button-name': ['button'],
|
|
739
|
-
'color-contrast': ['div', 'p', 'span'],
|
|
740
|
-
'html-lang': ['html'],
|
|
741
|
-
'link-name': ['a'],
|
|
742
|
-
'focus-visible': ['button', 'a', 'input'],
|
|
743
|
-
'bypass-blocks': ['main', 'nav'],
|
|
744
|
-
'label': ['input', 'select', 'textarea'],
|
|
745
|
-
'keyboard-trap': ['div', 'dialog'],
|
|
746
|
-
'focus-order': ['button', 'a', 'input'],
|
|
747
|
-
};
|
|
748
|
-
|
|
749
|
-
const tags = tagsByRule[ruleId] || ['div'];
|
|
750
|
-
const tag = tags[index % tags.length];
|
|
751
|
-
const classes = ['content', 'widget', 'component', 'item', 'element'];
|
|
752
|
-
const className = classes[index % classes.length];
|
|
753
|
-
|
|
754
|
-
return `${tag}.${className}`;
|
|
755
|
-
}
|
|
756
|
-
|
|
757
|
-
/**
|
|
758
|
-
* Estimate the number of elements checked based on rule category
|
|
759
|
-
*/
|
|
760
|
-
private estimateCheckedNodes(rule: AccessibilityRule, context: RuleContext): number {
|
|
761
|
-
// Base estimate on rule category - different rules check different element types
|
|
762
|
-
const ruleId = rule.id.toLowerCase();
|
|
763
|
-
|
|
764
|
-
// Image rules typically check fewer elements
|
|
765
|
-
if (ruleId.includes('image') || ruleId.includes('alt')) {
|
|
766
|
-
return 5 + (context.url.length % 10); // 5-14 elements
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
// Form rules check form elements
|
|
770
|
-
if (ruleId.includes('form') || ruleId.includes('label') || ruleId.includes('input')) {
|
|
771
|
-
return 8 + (context.url.length % 12); // 8-19 elements
|
|
772
|
-
}
|
|
773
|
-
|
|
774
|
-
// Link rules check all anchor elements
|
|
775
|
-
if (ruleId.includes('link') || ruleId.includes('anchor')) {
|
|
776
|
-
return 15 + (context.url.length % 20); // 15-34 elements
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
// Color/contrast rules check text elements
|
|
780
|
-
if (ruleId.includes('color') || ruleId.includes('contrast')) {
|
|
781
|
-
return 20 + (context.url.length % 15); // 20-34 elements
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
// Heading rules check heading hierarchy
|
|
785
|
-
if (ruleId.includes('heading') || ruleId.includes('h1') || ruleId.includes('h2')) {
|
|
786
|
-
return 6 + (context.url.length % 8); // 6-13 elements
|
|
787
|
-
}
|
|
788
|
-
|
|
789
|
-
// ARIA rules check interactive elements
|
|
790
|
-
if (ruleId.includes('aria') || ruleId.includes('role')) {
|
|
791
|
-
return 12 + (context.url.length % 18); // 12-29 elements
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
// Default: moderate number of elements
|
|
795
|
-
return 10 + (context.url.length % 10); // 10-19 elements
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
/**
|
|
800
|
-
* Analyze contrast for common UI elements
|
|
801
|
-
*/
|
|
802
|
-
private analyzeContrastForElements(url: string): ContrastAnalysis[] {
|
|
803
|
-
const elements = ['h1', 'p', 'a', 'button', '.card-text', '.nav-link'];
|
|
804
|
-
const analyses: ContrastAnalysis[] = [];
|
|
805
|
-
const urlHash = this.hashUrl(url);
|
|
806
|
-
const hashNum = parseInt(urlHash, 36);
|
|
807
|
-
|
|
808
|
-
for (let i = 0; i < elements.length; i++) {
|
|
809
|
-
const element = elements[i];
|
|
810
|
-
|
|
811
|
-
// Calculate contrast ratio deterministically based on URL and element
|
|
812
|
-
// Using common website patterns: most sites have decent contrast
|
|
813
|
-
const baseRatio = 4.5 + ((hashNum + i * 1000) % 100) / 10; // 4.5 to 14.5
|
|
814
|
-
const ratio = Math.round(baseRatio * 100) / 100;
|
|
815
|
-
|
|
816
|
-
// Large text (h1, button) requires 3:1, normal text requires 4.5:1
|
|
817
|
-
const isLargeText = element === 'h1' || element === 'button';
|
|
818
|
-
const requiredRatio = isLargeText ? 3 : 4.5;
|
|
819
|
-
const passes = ratio >= requiredRatio;
|
|
820
|
-
|
|
821
|
-
// Generate representative colors based on hash (hex format for test compatibility)
|
|
822
|
-
const fgValue = 20 + ((hashNum + i * 50) % 30); // 20-50 (dark, ~0x14-0x32)
|
|
823
|
-
const bgValue = 200 + ((hashNum + i * 30) % 55); // 200-255 (light)
|
|
824
|
-
|
|
825
|
-
const fgHex = fgValue.toString(16).padStart(2, '0');
|
|
826
|
-
const bgHex = bgValue.toString(16).padStart(2, '0');
|
|
827
|
-
|
|
828
|
-
analyses.push({
|
|
829
|
-
element,
|
|
830
|
-
foreground: `#${fgHex}${fgHex}${fgHex}`, // Grayscale hex
|
|
831
|
-
background: `#${bgHex}${bgHex}${bgHex}`, // Grayscale hex
|
|
832
|
-
ratio,
|
|
833
|
-
requiredRatio,
|
|
834
|
-
passes,
|
|
835
|
-
wcagLevel: 'AA',
|
|
836
|
-
});
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
return analyses;
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
/**
|
|
843
|
-
* Generate tab order based on URL structure
|
|
844
|
-
*/
|
|
845
|
-
private generateTabOrder(url: string, urlHash: string): TabOrderItem[] {
|
|
846
|
-
const items: TabOrderItem[] = [];
|
|
847
|
-
const hashNum = parseInt(urlHash, 36);
|
|
848
|
-
|
|
849
|
-
// Standard focusable elements in typical page structure
|
|
850
|
-
const elements: Array<{ selector: string; type: string }> = [
|
|
851
|
-
{ selector: '#skip-link', type: 'link' },
|
|
852
|
-
{ selector: 'header nav a.logo', type: 'link' },
|
|
853
|
-
{ selector: 'header nav a.menu-item', type: 'link' },
|
|
854
|
-
{ selector: '#search-input', type: 'input' },
|
|
855
|
-
{ selector: '#search-button', type: 'button' },
|
|
856
|
-
{ selector: 'main a', type: 'link' },
|
|
857
|
-
{ selector: 'main button', type: 'button' },
|
|
858
|
-
{ selector: 'form input', type: 'input' },
|
|
859
|
-
{ selector: 'form select', type: 'input' },
|
|
860
|
-
{ selector: 'form button[type="submit"]', type: 'button' },
|
|
861
|
-
{ selector: 'footer a', type: 'link' },
|
|
862
|
-
];
|
|
863
|
-
|
|
864
|
-
// Determine which elements have visible focus (deterministic based on URL)
|
|
865
|
-
elements.forEach((elem, index) => {
|
|
866
|
-
// Most elements should have visible focus, ~12% don't
|
|
867
|
-
const focusVisibleDeterminant = (hashNum + index * 17) % 100;
|
|
868
|
-
const hasVisibleFocus = focusVisibleDeterminant >= 12;
|
|
869
|
-
|
|
870
|
-
items.push({
|
|
871
|
-
index,
|
|
872
|
-
selector: elem.selector,
|
|
873
|
-
elementType: elem.type as 'link' | 'button' | 'input',
|
|
874
|
-
hasVisibleFocus,
|
|
875
|
-
});
|
|
876
|
-
});
|
|
877
|
-
|
|
878
|
-
return items;
|
|
879
|
-
}
|
|
880
|
-
|
|
881
|
-
private detectKeyboardIssues(tabOrder: TabOrderItem[]): KeyboardIssue[] {
|
|
882
|
-
const issues: KeyboardIssue[] = [];
|
|
883
|
-
|
|
884
|
-
// Check for missing focus indicators
|
|
885
|
-
for (const item of tabOrder) {
|
|
886
|
-
if (!item.hasVisibleFocus) {
|
|
887
|
-
issues.push({
|
|
888
|
-
type: 'no-focus-indicator',
|
|
889
|
-
selector: item.selector,
|
|
890
|
-
description: `Element ${item.selector} does not have a visible focus indicator`,
|
|
891
|
-
});
|
|
892
|
-
}
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
// Check for skip link
|
|
896
|
-
if (!tabOrder.some((item) => item.selector.includes('skip'))) {
|
|
897
|
-
issues.push({
|
|
898
|
-
type: 'skip-link-missing',
|
|
899
|
-
selector: 'body',
|
|
900
|
-
description: 'Page is missing a skip navigation link',
|
|
901
|
-
});
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
// Check for logical focus order issues
|
|
905
|
-
const hasLogicalOrder = tabOrder.every((item, index) => {
|
|
906
|
-
if (index === 0) return true;
|
|
907
|
-
// Check that navigation elements come before main content
|
|
908
|
-
const isNav = item.selector.includes('nav') || item.selector.includes('header');
|
|
909
|
-
const prevIsMain = tabOrder[index - 1].selector.includes('main');
|
|
910
|
-
return !(isNav && prevIsMain);
|
|
911
|
-
});
|
|
912
|
-
|
|
913
|
-
if (!hasLogicalOrder) {
|
|
914
|
-
issues.push({
|
|
915
|
-
type: 'incorrect-tab-order',
|
|
916
|
-
selector: 'body',
|
|
917
|
-
description: 'Focus order does not follow logical reading sequence',
|
|
918
|
-
});
|
|
919
|
-
}
|
|
920
|
-
|
|
921
|
-
return issues;
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
/**
|
|
925
|
-
* Detect focus traps based on URL patterns
|
|
926
|
-
*/
|
|
927
|
-
private detectFocusTraps(url: string, urlHash: string): FocusTrap[] {
|
|
928
|
-
const traps: FocusTrap[] = [];
|
|
929
|
-
const hashNum = parseInt(urlHash, 36);
|
|
930
|
-
|
|
931
|
-
// Check for common focus trap patterns based on URL
|
|
932
|
-
const hasModal = url.includes('modal') || url.includes('dialog') || url.includes('popup');
|
|
933
|
-
const hasForm = url.includes('form') || url.includes('checkout') || url.includes('register');
|
|
934
|
-
|
|
935
|
-
// 8% chance of focus trap issue for pages with modal-like patterns
|
|
936
|
-
if (hasModal && hashNum % 100 < 8) {
|
|
937
|
-
traps.push({
|
|
938
|
-
selector: '.modal, [role="dialog"]',
|
|
939
|
-
description: 'Modal dialog may trap focus without escape mechanism',
|
|
940
|
-
escapePath: 'Ensure Escape key closes modal and focus returns to trigger element',
|
|
941
|
-
});
|
|
942
|
-
}
|
|
943
|
-
|
|
944
|
-
// 5% chance of focus trap in complex forms
|
|
945
|
-
if (hasForm && hashNum % 100 < 5) {
|
|
946
|
-
traps.push({
|
|
947
|
-
selector: 'form .autocomplete, form .datepicker',
|
|
948
|
-
description: 'Form widget may trap keyboard focus',
|
|
949
|
-
escapePath: 'Add keyboard navigation (Tab/Escape) to exit widget',
|
|
950
|
-
});
|
|
951
|
-
}
|
|
952
|
-
|
|
953
|
-
return traps;
|
|
954
|
-
}
|
|
955
|
-
|
|
956
|
-
private async storeReport(report: AccessibilityReport): Promise<void> {
|
|
957
|
-
const reportId = uuidv4();
|
|
958
|
-
await this.memory.set(
|
|
959
|
-
`visual-accessibility:report:${reportId}`,
|
|
960
|
-
report,
|
|
961
|
-
{ namespace: 'visual-accessibility', persist: true }
|
|
962
|
-
);
|
|
963
|
-
|
|
964
|
-
// Also store as latest for URL
|
|
965
|
-
await this.memory.set(
|
|
966
|
-
`visual-accessibility:latest:${this.hashUrl(report.url)}`,
|
|
967
|
-
report,
|
|
968
|
-
{ namespace: 'visual-accessibility', persist: true }
|
|
969
|
-
);
|
|
970
|
-
}
|
|
971
|
-
|
|
972
|
-
private hashUrl(url: string): string {
|
|
973
|
-
let hash = 0;
|
|
974
|
-
for (let i = 0; i < url.length; i++) {
|
|
975
|
-
const char = url.charCodeAt(i);
|
|
976
|
-
hash = (hash << 5) - hash + char;
|
|
977
|
-
hash = hash & hash;
|
|
978
|
-
}
|
|
979
|
-
return Math.abs(hash).toString(36);
|
|
980
|
-
}
|
|
981
|
-
|
|
982
|
-
}
|