agentic-qe 3.3.2 → 3.3.4
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/.claude/agents/v3/README.md +100 -0
- package/.claude/agents/v3/qe-accessibility-auditor.md +112 -11
- package/.claude/agents/v3/qe-bdd-generator.md +40 -0
- package/.claude/agents/v3/qe-coverage-specialist.md +39 -0
- package/.claude/agents/v3/qe-defect-predictor.md +36 -0
- package/.claude/agents/v3/qe-gap-detector.md +39 -0
- package/.claude/agents/v3/qe-pattern-learner.md +31 -0
- package/.claude/agents/v3/qe-product-factors-assessor.md +34 -0
- package/.claude/agents/v3/qe-quality-criteria-recommender.md +32 -0
- package/.claude/agents/v3/qe-quality-gate.md +39 -0
- package/.claude/agents/v3/qe-requirements-validator.md +37 -0
- package/.claude/agents/v3/qe-risk-assessor.md +33 -0
- package/.claude/agents/v3/qe-tdd-specialist.md +33 -0
- package/.claude/agents/v3/qe-test-architect.md +36 -0
- package/.claude/helpers/statusline-v3.cjs +96 -27
- package/.claude/skills/README.md +30 -104
- package/.claude/skills/a11y-ally/SKILL.md +1658 -0
- package/.claude/skills/qcsd-ideation-swarm/SKILL.md +1750 -0
- package/.claude/skills/skills-manifest.json +78 -8
- package/README.md +24 -7
- package/package.json +1 -1
- package/scripts/demo-warmup.sh +45 -0
- package/scripts/fetch-content.js +460 -0
- package/scripts/sync-claude-flow.cjs +99 -0
- package/v3/CHANGELOG.md +188 -0
- package/v3/README.md +18 -9
- package/v3/assets/agents/v3/README.md +100 -0
- package/v3/assets/agents/v3/qe-accessibility-auditor.md +112 -11
- package/v3/assets/agents/v3/qe-bdd-generator.md +40 -0
- package/v3/assets/agents/v3/qe-coverage-specialist.md +39 -0
- package/v3/assets/agents/v3/qe-defect-predictor.md +36 -0
- package/v3/assets/agents/v3/qe-gap-detector.md +39 -0
- package/v3/assets/agents/v3/qe-pattern-learner.md +31 -0
- package/v3/assets/agents/v3/qe-product-factors-assessor.md +34 -0
- package/v3/assets/agents/v3/qe-quality-criteria-recommender.md +32 -0
- package/v3/assets/agents/v3/qe-quality-gate.md +39 -0
- package/v3/assets/agents/v3/qe-requirements-validator.md +37 -0
- package/v3/assets/agents/v3/qe-risk-assessor.md +33 -0
- package/v3/assets/agents/v3/qe-tdd-specialist.md +33 -0
- package/v3/assets/agents/v3/qe-test-architect.md +36 -0
- package/v3/assets/hooks/cross-phase-memory.yaml +253 -0
- package/v3/assets/skills/a11y-ally/SKILL.md +1658 -0
- package/v3/assets/skills/qcsd-ideation-swarm/SKILL.md +1750 -0
- package/v3/assets/skills/skills-manifest.json +753 -0
- package/v3/dist/adapters/claude-flow/model-router-bridge.d.ts.map +1 -1
- package/v3/dist/adapters/claude-flow/model-router-bridge.js +6 -4
- package/v3/dist/adapters/claude-flow/model-router-bridge.js.map +1 -1
- package/v3/dist/adapters/claude-flow/pretrain-bridge.d.ts.map +1 -1
- package/v3/dist/adapters/claude-flow/pretrain-bridge.js +13 -8
- package/v3/dist/adapters/claude-flow/pretrain-bridge.js.map +1 -1
- package/v3/dist/adapters/claude-flow/trajectory-bridge.d.ts.map +1 -1
- package/v3/dist/adapters/claude-flow/trajectory-bridge.js +9 -6
- package/v3/dist/adapters/claude-flow/trajectory-bridge.js.map +1 -1
- package/v3/dist/benchmarks/performance-benchmarks.d.ts.map +1 -1
- package/v3/dist/benchmarks/performance-benchmarks.js +5 -3
- package/v3/dist/benchmarks/performance-benchmarks.js.map +1 -1
- package/v3/dist/cli/bundle.js +47008 -36837
- package/v3/dist/cli/commands/hooks.d.ts.map +1 -1
- package/v3/dist/cli/commands/hooks.js +288 -0
- package/v3/dist/cli/commands/hooks.js.map +1 -1
- package/v3/dist/cli/commands/sync.d.ts.map +1 -1
- package/v3/dist/cli/commands/sync.js +0 -6
- package/v3/dist/cli/commands/sync.js.map +1 -1
- package/v3/dist/cli/handlers/init-handler.d.ts.map +1 -1
- package/v3/dist/cli/handlers/init-handler.js +11 -0
- package/v3/dist/cli/handlers/init-handler.js.map +1 -1
- package/v3/dist/cli/index.js +14 -2
- package/v3/dist/cli/index.js.map +1 -1
- package/v3/dist/cli/scheduler/persistent-scheduler.d.ts.map +1 -1
- package/v3/dist/cli/scheduler/persistent-scheduler.js +3 -2
- package/v3/dist/cli/scheduler/persistent-scheduler.js.map +1 -1
- package/v3/dist/cli/wizards/test-wizard.d.ts.map +1 -1
- package/v3/dist/cli/wizards/test-wizard.js +6 -4
- package/v3/dist/cli/wizards/test-wizard.js.map +1 -1
- package/v3/dist/coordination/consensus/domain-findings.d.ts +202 -0
- package/v3/dist/coordination/consensus/domain-findings.d.ts.map +1 -0
- package/v3/dist/coordination/consensus/domain-findings.js +66 -0
- package/v3/dist/coordination/consensus/domain-findings.js.map +1 -0
- package/v3/dist/coordination/consensus/index.d.ts +2 -0
- package/v3/dist/coordination/consensus/index.d.ts.map +1 -1
- package/v3/dist/coordination/consensus/index.js +4 -0
- package/v3/dist/coordination/consensus/index.js.map +1 -1
- package/v3/dist/coordination/consensus/providers/native-learning-provider.d.ts.map +1 -1
- package/v3/dist/coordination/consensus/providers/native-learning-provider.js +10 -8
- package/v3/dist/coordination/consensus/providers/native-learning-provider.js.map +1 -1
- package/v3/dist/coordination/consensus/providers/ollama-provider.d.ts.map +1 -1
- package/v3/dist/coordination/consensus/providers/ollama-provider.js +5 -4
- package/v3/dist/coordination/consensus/providers/ollama-provider.js.map +1 -1
- package/v3/dist/coordination/consensus/providers/openai-provider.d.ts.map +1 -1
- package/v3/dist/coordination/consensus/providers/openai-provider.js +5 -4
- package/v3/dist/coordination/consensus/providers/openai-provider.js.map +1 -1
- package/v3/dist/coordination/constants.d.ts +198 -0
- package/v3/dist/coordination/constants.d.ts.map +1 -0
- package/v3/dist/coordination/constants.js +210 -0
- package/v3/dist/coordination/constants.js.map +1 -0
- package/v3/dist/coordination/index.d.ts +1 -0
- package/v3/dist/coordination/index.d.ts.map +1 -1
- package/v3/dist/coordination/index.js +4 -0
- package/v3/dist/coordination/index.js.map +1 -1
- package/v3/dist/coordination/mincut/dream-integration.d.ts.map +1 -1
- package/v3/dist/coordination/mincut/dream-integration.js +5 -1
- package/v3/dist/coordination/mincut/dream-integration.js.map +1 -1
- package/v3/dist/coordination/mixins/consensus-enabled-domain.d.ts +225 -0
- package/v3/dist/coordination/mixins/consensus-enabled-domain.d.ts.map +1 -0
- package/v3/dist/coordination/mixins/consensus-enabled-domain.js +466 -0
- package/v3/dist/coordination/mixins/consensus-enabled-domain.js.map +1 -0
- package/v3/dist/coordination/mixins/index.d.ts +14 -0
- package/v3/dist/coordination/mixins/index.d.ts.map +1 -0
- package/v3/dist/coordination/mixins/index.js +28 -0
- package/v3/dist/coordination/mixins/index.js.map +1 -0
- package/v3/dist/coordination/mixins/mincut-aware-domain.d.ts +227 -0
- package/v3/dist/coordination/mixins/mincut-aware-domain.d.ts.map +1 -0
- package/v3/dist/coordination/mixins/mincut-aware-domain.js +368 -0
- package/v3/dist/coordination/mixins/mincut-aware-domain.js.map +1 -0
- package/v3/dist/coordination/queen-coordinator.d.ts +19 -1
- package/v3/dist/coordination/queen-coordinator.d.ts.map +1 -1
- package/v3/dist/coordination/queen-coordinator.js +87 -7
- package/v3/dist/coordination/queen-coordinator.js.map +1 -1
- package/v3/dist/coordination/task-executor.d.ts +21 -1
- package/v3/dist/coordination/task-executor.d.ts.map +1 -1
- package/v3/dist/coordination/task-executor.js +227 -11
- package/v3/dist/coordination/task-executor.js.map +1 -1
- package/v3/dist/coordination/workflow-orchestrator.d.ts.map +1 -1
- package/v3/dist/coordination/workflow-orchestrator.js +261 -0
- package/v3/dist/coordination/workflow-orchestrator.js.map +1 -1
- package/v3/dist/domains/chaos-resilience/coordinator.d.ts +92 -0
- package/v3/dist/domains/chaos-resilience/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/chaos-resilience/coordinator.js +241 -1
- package/v3/dist/domains/chaos-resilience/coordinator.js.map +1 -1
- package/v3/dist/domains/chaos-resilience/plugin.d.ts +14 -3
- package/v3/dist/domains/chaos-resilience/plugin.d.ts.map +1 -1
- package/v3/dist/domains/chaos-resilience/plugin.js +97 -1
- package/v3/dist/domains/chaos-resilience/plugin.js.map +1 -1
- package/v3/dist/domains/chaos-resilience/services/chaos-engineer.d.ts +29 -2
- package/v3/dist/domains/chaos-resilience/services/chaos-engineer.d.ts.map +1 -1
- package/v3/dist/domains/chaos-resilience/services/chaos-engineer.js +62 -3
- package/v3/dist/domains/chaos-resilience/services/chaos-engineer.js.map +1 -1
- package/v3/dist/domains/chaos-resilience/services/performance-profiler.d.ts.map +1 -1
- package/v3/dist/domains/chaos-resilience/services/performance-profiler.js +12 -8
- package/v3/dist/domains/chaos-resilience/services/performance-profiler.js.map +1 -1
- package/v3/dist/domains/code-intelligence/coordinator.d.ts +112 -0
- package/v3/dist/domains/code-intelligence/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/code-intelligence/coordinator.js +221 -0
- package/v3/dist/domains/code-intelligence/coordinator.js.map +1 -1
- package/v3/dist/domains/code-intelligence/plugin.d.ts +13 -3
- package/v3/dist/domains/code-intelligence/plugin.d.ts.map +1 -1
- package/v3/dist/domains/code-intelligence/plugin.js +85 -0
- package/v3/dist/domains/code-intelligence/plugin.js.map +1 -1
- package/v3/dist/domains/code-intelligence/services/knowledge-graph.d.ts +66 -2
- package/v3/dist/domains/code-intelligence/services/knowledge-graph.d.ts.map +1 -1
- package/v3/dist/domains/code-intelligence/services/knowledge-graph.js +253 -3
- package/v3/dist/domains/code-intelligence/services/knowledge-graph.js.map +1 -1
- package/v3/dist/domains/code-intelligence/services/product-factors-bridge.d.ts.map +1 -1
- package/v3/dist/domains/code-intelligence/services/product-factors-bridge.js +3 -2
- package/v3/dist/domains/code-intelligence/services/product-factors-bridge.js.map +1 -1
- package/v3/dist/domains/constants.d.ts +481 -0
- package/v3/dist/domains/constants.d.ts.map +1 -0
- package/v3/dist/domains/constants.js +503 -0
- package/v3/dist/domains/constants.js.map +1 -0
- package/v3/dist/domains/contract-testing/coordinator.d.ts +89 -1
- package/v3/dist/domains/contract-testing/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/contract-testing/coordinator.js +222 -1
- package/v3/dist/domains/contract-testing/coordinator.js.map +1 -1
- package/v3/dist/domains/contract-testing/interfaces.d.ts +29 -1
- package/v3/dist/domains/contract-testing/interfaces.d.ts.map +1 -1
- package/v3/dist/domains/contract-testing/plugin.d.ts +6 -1
- package/v3/dist/domains/contract-testing/plugin.d.ts.map +1 -1
- package/v3/dist/domains/contract-testing/plugin.js +81 -2
- package/v3/dist/domains/contract-testing/plugin.js.map +1 -1
- package/v3/dist/domains/contract-testing/services/contract-validator.d.ts +29 -2
- package/v3/dist/domains/contract-testing/services/contract-validator.d.ts.map +1 -1
- package/v3/dist/domains/contract-testing/services/contract-validator.js +62 -6
- package/v3/dist/domains/contract-testing/services/contract-validator.js.map +1 -1
- package/v3/dist/domains/coverage-analysis/coordinator.d.ts +95 -2
- package/v3/dist/domains/coverage-analysis/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/coverage-analysis/coordinator.js +274 -6
- package/v3/dist/domains/coverage-analysis/coordinator.js.map +1 -1
- package/v3/dist/domains/coverage-analysis/services/coverage-analyzer.d.ts +119 -3
- package/v3/dist/domains/coverage-analysis/services/coverage-analyzer.d.ts.map +1 -1
- package/v3/dist/domains/coverage-analysis/services/coverage-analyzer.js +267 -5
- package/v3/dist/domains/coverage-analysis/services/coverage-analyzer.js.map +1 -1
- package/v3/dist/domains/coverage-analysis/services/gap-detector.d.ts +111 -2
- package/v3/dist/domains/coverage-analysis/services/gap-detector.d.ts.map +1 -1
- package/v3/dist/domains/coverage-analysis/services/gap-detector.js +231 -3
- package/v3/dist/domains/coverage-analysis/services/gap-detector.js.map +1 -1
- package/v3/dist/domains/coverage-analysis/services/hnsw-index.d.ts.map +1 -1
- package/v3/dist/domains/coverage-analysis/services/hnsw-index.js +1 -0
- package/v3/dist/domains/coverage-analysis/services/hnsw-index.js.map +1 -1
- package/v3/dist/domains/defect-intelligence/coordinator.d.ts +80 -1
- package/v3/dist/domains/defect-intelligence/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/defect-intelligence/coordinator.js +262 -7
- package/v3/dist/domains/defect-intelligence/coordinator.js.map +1 -1
- package/v3/dist/domains/defect-intelligence/interfaces.d.ts +17 -0
- package/v3/dist/domains/defect-intelligence/interfaces.d.ts.map +1 -1
- package/v3/dist/domains/defect-intelligence/plugin.d.ts +6 -1
- package/v3/dist/domains/defect-intelligence/plugin.d.ts.map +1 -1
- package/v3/dist/domains/defect-intelligence/plugin.js +101 -0
- package/v3/dist/domains/defect-intelligence/plugin.js.map +1 -1
- package/v3/dist/domains/defect-intelligence/services/defect-predictor.d.ts +91 -2
- package/v3/dist/domains/defect-intelligence/services/defect-predictor.d.ts.map +1 -1
- package/v3/dist/domains/defect-intelligence/services/defect-predictor.js +277 -9
- package/v3/dist/domains/defect-intelligence/services/defect-predictor.js.map +1 -1
- package/v3/dist/domains/defect-intelligence/services/root-cause-analyzer.d.ts +79 -2
- package/v3/dist/domains/defect-intelligence/services/root-cause-analyzer.d.ts.map +1 -1
- package/v3/dist/domains/defect-intelligence/services/root-cause-analyzer.js +259 -3
- package/v3/dist/domains/defect-intelligence/services/root-cause-analyzer.js.map +1 -1
- package/v3/dist/domains/domain-interface.d.ts +155 -0
- package/v3/dist/domains/domain-interface.d.ts.map +1 -1
- package/v3/dist/domains/domain-interface.js +164 -9
- package/v3/dist/domains/domain-interface.js.map +1 -1
- package/v3/dist/domains/learning-optimization/coordinator.d.ts +88 -0
- package/v3/dist/domains/learning-optimization/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/learning-optimization/coordinator.js +227 -1
- package/v3/dist/domains/learning-optimization/coordinator.js.map +1 -1
- package/v3/dist/domains/learning-optimization/index.d.ts +1 -1
- package/v3/dist/domains/learning-optimization/index.d.ts.map +1 -1
- package/v3/dist/domains/learning-optimization/index.js.map +1 -1
- package/v3/dist/domains/learning-optimization/interfaces.d.ts +4 -0
- package/v3/dist/domains/learning-optimization/interfaces.d.ts.map +1 -1
- package/v3/dist/domains/learning-optimization/plugin.d.ts +2 -1
- package/v3/dist/domains/learning-optimization/plugin.d.ts.map +1 -1
- package/v3/dist/domains/learning-optimization/plugin.js +50 -1
- package/v3/dist/domains/learning-optimization/plugin.js.map +1 -1
- package/v3/dist/domains/learning-optimization/services/learning-coordinator.d.ts +54 -2
- package/v3/dist/domains/learning-optimization/services/learning-coordinator.d.ts.map +1 -1
- package/v3/dist/domains/learning-optimization/services/learning-coordinator.js +90 -3
- package/v3/dist/domains/learning-optimization/services/learning-coordinator.js.map +1 -1
- package/v3/dist/domains/quality-assessment/coordinator.d.ts +194 -1
- package/v3/dist/domains/quality-assessment/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/quality-assessment/coordinator.js +664 -6
- package/v3/dist/domains/quality-assessment/coordinator.js.map +1 -1
- package/v3/dist/domains/quality-assessment/interfaces.d.ts +22 -0
- package/v3/dist/domains/quality-assessment/interfaces.d.ts.map +1 -1
- package/v3/dist/domains/quality-assessment/services/deployment-advisor.d.ts +61 -2
- package/v3/dist/domains/quality-assessment/services/deployment-advisor.d.ts.map +1 -1
- package/v3/dist/domains/quality-assessment/services/deployment-advisor.js +213 -5
- package/v3/dist/domains/quality-assessment/services/deployment-advisor.js.map +1 -1
- package/v3/dist/domains/quality-assessment/services/quality-analyzer.d.ts +59 -4
- package/v3/dist/domains/quality-assessment/services/quality-analyzer.d.ts.map +1 -1
- package/v3/dist/domains/quality-assessment/services/quality-analyzer.js +195 -3
- package/v3/dist/domains/quality-assessment/services/quality-analyzer.js.map +1 -1
- package/v3/dist/domains/requirements-validation/coordinator.d.ts +78 -0
- package/v3/dist/domains/requirements-validation/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/requirements-validation/coordinator.js +189 -0
- package/v3/dist/domains/requirements-validation/coordinator.js.map +1 -1
- package/v3/dist/domains/requirements-validation/index.d.ts +1 -0
- package/v3/dist/domains/requirements-validation/index.d.ts.map +1 -1
- package/v3/dist/domains/requirements-validation/index.js +2 -0
- package/v3/dist/domains/requirements-validation/index.js.map +1 -1
- package/v3/dist/domains/requirements-validation/interfaces.d.ts +4 -0
- package/v3/dist/domains/requirements-validation/interfaces.d.ts.map +1 -1
- package/v3/dist/domains/requirements-validation/plugin.d.ts +13 -1
- package/v3/dist/domains/requirements-validation/plugin.d.ts.map +1 -1
- package/v3/dist/domains/requirements-validation/plugin.js +94 -0
- package/v3/dist/domains/requirements-validation/plugin.js.map +1 -1
- package/v3/dist/domains/requirements-validation/qcsd-ideation-plugin.d.ts +245 -0
- package/v3/dist/domains/requirements-validation/qcsd-ideation-plugin.d.ts.map +1 -0
- package/v3/dist/domains/requirements-validation/qcsd-ideation-plugin.js +1143 -0
- package/v3/dist/domains/requirements-validation/qcsd-ideation-plugin.js.map +1 -0
- package/v3/dist/domains/requirements-validation/services/product-factors-assessment/code-intelligence/codebase-analyzer.d.ts.map +1 -1
- package/v3/dist/domains/requirements-validation/services/product-factors-assessment/code-intelligence/codebase-analyzer.js +3 -2
- package/v3/dist/domains/requirements-validation/services/product-factors-assessment/code-intelligence/codebase-analyzer.js.map +1 -1
- package/v3/dist/domains/requirements-validation/services/requirements-validator.d.ts +106 -2
- package/v3/dist/domains/requirements-validation/services/requirements-validator.d.ts.map +1 -1
- package/v3/dist/domains/requirements-validation/services/requirements-validator.js +263 -3
- package/v3/dist/domains/requirements-validation/services/requirements-validator.js.map +1 -1
- package/v3/dist/domains/security-compliance/coordinator.d.ts +56 -1
- package/v3/dist/domains/security-compliance/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/security-compliance/coordinator.js +241 -17
- package/v3/dist/domains/security-compliance/coordinator.js.map +1 -1
- package/v3/dist/domains/security-compliance/interfaces.d.ts +2 -0
- package/v3/dist/domains/security-compliance/interfaces.d.ts.map +1 -1
- package/v3/dist/domains/security-compliance/plugin.d.ts +3 -2
- package/v3/dist/domains/security-compliance/plugin.d.ts.map +1 -1
- package/v3/dist/domains/security-compliance/plugin.js +64 -0
- package/v3/dist/domains/security-compliance/plugin.js.map +1 -1
- package/v3/dist/domains/security-compliance/services/scanners/dast-auth-testing.d.ts +25 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-auth-testing.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-auth-testing.js +160 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-auth-testing.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-helpers.d.ts +48 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-helpers.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-helpers.js +385 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-helpers.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-injection-testing.d.ts +20 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-injection-testing.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-injection-testing.js +99 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-injection-testing.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-scanner.d.ts +62 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-scanner.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-scanner.js +329 -0
- package/v3/dist/domains/security-compliance/services/scanners/dast-scanner.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/dependency-scanner.d.ts +46 -0
- package/v3/dist/domains/security-compliance/services/scanners/dependency-scanner.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/dependency-scanner.js +180 -0
- package/v3/dist/domains/security-compliance/services/scanners/dependency-scanner.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/index.d.ts +14 -0
- package/v3/dist/domains/security-compliance/services/scanners/index.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/index.js +16 -0
- package/v3/dist/domains/security-compliance/services/scanners/index.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/sast-scanner.d.ts +92 -0
- package/v3/dist/domains/security-compliance/services/scanners/sast-scanner.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/sast-scanner.js +440 -0
- package/v3/dist/domains/security-compliance/services/scanners/sast-scanner.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/scanner-orchestrator.d.ts +78 -0
- package/v3/dist/domains/security-compliance/services/scanners/scanner-orchestrator.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/scanner-orchestrator.js +179 -0
- package/v3/dist/domains/security-compliance/services/scanners/scanner-orchestrator.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/scanner-types.d.ts +91 -0
- package/v3/dist/domains/security-compliance/services/scanners/scanner-types.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/scanner-types.js +15 -0
- package/v3/dist/domains/security-compliance/services/scanners/scanner-types.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/security-patterns.d.ts +16 -0
- package/v3/dist/domains/security-compliance/services/scanners/security-patterns.d.ts.map +1 -0
- package/v3/dist/domains/security-compliance/services/scanners/security-patterns.js +507 -0
- package/v3/dist/domains/security-compliance/services/scanners/security-patterns.js.map +1 -0
- package/v3/dist/domains/security-compliance/services/security-auditor.d.ts.map +1 -1
- package/v3/dist/domains/security-compliance/services/security-auditor.js +2 -1
- package/v3/dist/domains/security-compliance/services/security-auditor.js.map +1 -1
- package/v3/dist/domains/security-compliance/services/security-scanner.d.ts +20 -182
- package/v3/dist/domains/security-compliance/services/security-scanner.d.ts.map +1 -1
- package/v3/dist/domains/security-compliance/services/security-scanner.js +37 -1909
- package/v3/dist/domains/security-compliance/services/security-scanner.js.map +1 -1
- package/v3/dist/domains/security-compliance/services/semgrep-integration.d.ts.map +1 -1
- package/v3/dist/domains/security-compliance/services/semgrep-integration.js +7 -6
- package/v3/dist/domains/security-compliance/services/semgrep-integration.js.map +1 -1
- package/v3/dist/domains/test-execution/coordinator.d.ts +89 -0
- package/v3/dist/domains/test-execution/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/test-execution/coordinator.js +259 -2
- package/v3/dist/domains/test-execution/coordinator.js.map +1 -1
- package/v3/dist/domains/test-execution/services/auth-state-manager.d.ts.map +1 -1
- package/v3/dist/domains/test-execution/services/auth-state-manager.js +6 -4
- package/v3/dist/domains/test-execution/services/auth-state-manager.js.map +1 -1
- package/v3/dist/domains/test-execution/services/e2e/assertion-handlers.d.ts +55 -0
- package/v3/dist/domains/test-execution/services/e2e/assertion-handlers.d.ts.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/assertion-handlers.js +407 -0
- package/v3/dist/domains/test-execution/services/e2e/assertion-handlers.js.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/browser-orchestrator.d.ts +122 -0
- package/v3/dist/domains/test-execution/services/e2e/browser-orchestrator.d.ts.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/browser-orchestrator.js +325 -0
- package/v3/dist/domains/test-execution/services/e2e/browser-orchestrator.js.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/e2e-coordinator.d.ts +97 -0
- package/v3/dist/domains/test-execution/services/e2e/e2e-coordinator.d.ts.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/e2e-coordinator.js +297 -0
- package/v3/dist/domains/test-execution/services/e2e/e2e-coordinator.js.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/index.d.ts +22 -0
- package/v3/dist/domains/test-execution/services/e2e/index.d.ts.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/index.js +52 -0
- package/v3/dist/domains/test-execution/services/e2e/index.js.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/result-collector.d.ts +51 -0
- package/v3/dist/domains/test-execution/services/e2e/result-collector.d.ts.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/result-collector.js +133 -0
- package/v3/dist/domains/test-execution/services/e2e/result-collector.js.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/step-executors.d.ts +48 -0
- package/v3/dist/domains/test-execution/services/e2e/step-executors.d.ts.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/step-executors.js +422 -0
- package/v3/dist/domains/test-execution/services/e2e/step-executors.js.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/step-retry-handler.d.ts +49 -0
- package/v3/dist/domains/test-execution/services/e2e/step-retry-handler.d.ts.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/step-retry-handler.js +146 -0
- package/v3/dist/domains/test-execution/services/e2e/step-retry-handler.js.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/types.d.ts +138 -0
- package/v3/dist/domains/test-execution/services/e2e/types.d.ts.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/types.js +65 -0
- package/v3/dist/domains/test-execution/services/e2e/types.js.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/wait-condition-handler.d.ts +33 -0
- package/v3/dist/domains/test-execution/services/e2e/wait-condition-handler.d.ts.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e/wait-condition-handler.js +114 -0
- package/v3/dist/domains/test-execution/services/e2e/wait-condition-handler.js.map +1 -0
- package/v3/dist/domains/test-execution/services/e2e-runner.d.ts +18 -392
- package/v3/dist/domains/test-execution/services/e2e-runner.d.ts.map +1 -1
- package/v3/dist/domains/test-execution/services/e2e-runner.js +25 -1757
- package/v3/dist/domains/test-execution/services/e2e-runner.js.map +1 -1
- package/v3/dist/domains/test-execution/services/flaky-detector.d.ts.map +1 -1
- package/v3/dist/domains/test-execution/services/flaky-detector.js +12 -9
- package/v3/dist/domains/test-execution/services/flaky-detector.js.map +1 -1
- package/v3/dist/domains/test-execution/services/retry-handler.d.ts.map +1 -1
- package/v3/dist/domains/test-execution/services/retry-handler.js +7 -5
- package/v3/dist/domains/test-execution/services/retry-handler.js.map +1 -1
- package/v3/dist/domains/test-execution/services/test-executor.d.ts +30 -2
- package/v3/dist/domains/test-execution/services/test-executor.d.ts.map +1 -1
- package/v3/dist/domains/test-execution/services/test-executor.js +67 -5
- package/v3/dist/domains/test-execution/services/test-executor.js.map +1 -1
- package/v3/dist/domains/test-generation/coordinator.d.ts +97 -0
- package/v3/dist/domains/test-generation/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/test-generation/coordinator.js +237 -0
- package/v3/dist/domains/test-generation/coordinator.js.map +1 -1
- package/v3/dist/domains/test-generation/interfaces.d.ts +2 -0
- package/v3/dist/domains/test-generation/interfaces.d.ts.map +1 -1
- package/v3/dist/domains/test-generation/services/test-generator.d.ts +32 -0
- package/v3/dist/domains/test-generation/services/test-generator.d.ts.map +1 -1
- package/v3/dist/domains/test-generation/services/test-generator.js +158 -3
- package/v3/dist/domains/test-generation/services/test-generator.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/coordinator.d.ts +147 -0
- package/v3/dist/domains/visual-accessibility/coordinator.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/coordinator.js +382 -2
- package/v3/dist/domains/visual-accessibility/coordinator.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/plugin.d.ts +2 -1
- package/v3/dist/domains/visual-accessibility/plugin.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/plugin.js +66 -3
- package/v3/dist/domains/visual-accessibility/plugin.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/accessibility-tester.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/accessibility-tester.js +3 -2
- package/v3/dist/domains/visual-accessibility/services/accessibility-tester.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/browser-security-scanner.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/browser-security-scanner.js +22 -12
- package/v3/dist/domains/visual-accessibility/services/browser-security-scanner.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/viewport-capture.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/viewport-capture.js +3 -2
- package/v3/dist/domains/visual-accessibility/services/viewport-capture.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/visual-regression.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/visual-regression.js +3 -2
- package/v3/dist/domains/visual-accessibility/services/visual-regression.js.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/visual-tester.d.ts +47 -2
- package/v3/dist/domains/visual-accessibility/services/visual-tester.d.ts.map +1 -1
- package/v3/dist/domains/visual-accessibility/services/visual-tester.js +87 -3
- package/v3/dist/domains/visual-accessibility/services/visual-tester.js.map +1 -1
- package/v3/dist/hooks/cross-phase-hooks.d.ts +42 -0
- package/v3/dist/hooks/cross-phase-hooks.d.ts.map +1 -0
- package/v3/dist/hooks/cross-phase-hooks.js +338 -0
- package/v3/dist/hooks/cross-phase-hooks.js.map +1 -0
- package/v3/dist/hooks/index.d.ts +9 -0
- package/v3/dist/hooks/index.d.ts.map +1 -0
- package/v3/dist/hooks/index.js +9 -0
- package/v3/dist/hooks/index.js.map +1 -0
- package/v3/dist/init/agents-installer.d.ts.map +1 -1
- package/v3/dist/init/agents-installer.js +6 -4
- package/v3/dist/init/agents-installer.js.map +1 -1
- package/v3/dist/init/enhancements/claude-flow-adapter.d.ts.map +1 -1
- package/v3/dist/init/enhancements/claude-flow-adapter.js +15 -9
- package/v3/dist/init/enhancements/claude-flow-adapter.js.map +1 -1
- package/v3/dist/init/enhancements/detector.js +6 -4
- package/v3/dist/init/enhancements/detector.js.map +1 -1
- package/v3/dist/init/init-wizard.d.ts +5 -0
- package/v3/dist/init/init-wizard.d.ts.map +1 -1
- package/v3/dist/init/init-wizard.js +74 -11
- package/v3/dist/init/init-wizard.js.map +1 -1
- package/v3/dist/init/migration/data-migrator.d.ts.map +1 -1
- package/v3/dist/init/migration/data-migrator.js +6 -4
- package/v3/dist/init/migration/data-migrator.js.map +1 -1
- package/v3/dist/init/phases/02-analysis.js +2 -2
- package/v3/dist/init/phases/02-analysis.js.map +1 -1
- package/v3/dist/init/phases/04-database.d.ts.map +1 -1
- package/v3/dist/init/phases/04-database.js +0 -1
- package/v3/dist/init/phases/04-database.js.map +1 -1
- package/v3/dist/init/phases/11-claude-md.d.ts.map +1 -1
- package/v3/dist/init/phases/11-claude-md.js +25 -0
- package/v3/dist/init/phases/11-claude-md.js.map +1 -1
- package/v3/dist/init/phases/12-verification.d.ts.map +1 -1
- package/v3/dist/init/phases/12-verification.js +2 -1
- package/v3/dist/init/phases/12-verification.js.map +1 -1
- package/v3/dist/init/project-analyzer.d.ts.map +1 -1
- package/v3/dist/init/project-analyzer.js +12 -8
- package/v3/dist/init/project-analyzer.js.map +1 -1
- package/v3/dist/init/skills-installer.d.ts.map +1 -1
- package/v3/dist/init/skills-installer.js +6 -4
- package/v3/dist/init/skills-installer.js.map +1 -1
- package/v3/dist/init/token-bootstrap.d.ts.map +1 -1
- package/v3/dist/init/token-bootstrap.js +2 -1
- package/v3/dist/init/token-bootstrap.js.map +1 -1
- package/v3/dist/integrations/agent-booster-wasm/index.d.ts.map +1 -1
- package/v3/dist/integrations/agent-booster-wasm/index.js +8 -4
- package/v3/dist/integrations/agent-booster-wasm/index.js.map +1 -1
- package/v3/dist/integrations/agentic-flow/model-router/signal-collector.d.ts.map +1 -1
- package/v3/dist/integrations/agentic-flow/model-router/signal-collector.js +3 -2
- package/v3/dist/integrations/agentic-flow/model-router/signal-collector.js.map +1 -1
- package/v3/dist/integrations/agentic-flow/reasoning-bank/experience-replay.d.ts.map +1 -1
- package/v3/dist/integrations/agentic-flow/reasoning-bank/experience-replay.js.map +1 -1
- package/v3/dist/integrations/agentic-flow/reasoning-bank/trajectory-tracker.d.ts.map +1 -1
- package/v3/dist/integrations/agentic-flow/reasoning-bank/trajectory-tracker.js.map +1 -1
- package/v3/dist/integrations/browser/agent-browser/client.d.ts.map +1 -1
- package/v3/dist/integrations/browser/agent-browser/client.js +9 -6
- package/v3/dist/integrations/browser/agent-browser/client.js.map +1 -1
- package/v3/dist/integrations/browser/agent-browser/command-executor.d.ts.map +1 -1
- package/v3/dist/integrations/browser/agent-browser/command-executor.js +3 -2
- package/v3/dist/integrations/browser/agent-browser/command-executor.js.map +1 -1
- package/v3/dist/integrations/browser/index.d.ts +1 -0
- package/v3/dist/integrations/browser/index.d.ts.map +1 -1
- package/v3/dist/integrations/browser/index.js +6 -0
- package/v3/dist/integrations/browser/index.js.map +1 -1
- package/v3/dist/integrations/browser/web-content-fetcher.d.ts +154 -0
- package/v3/dist/integrations/browser/web-content-fetcher.d.ts.map +1 -0
- package/v3/dist/integrations/browser/web-content-fetcher.js +529 -0
- package/v3/dist/integrations/browser/web-content-fetcher.js.map +1 -0
- package/v3/dist/integrations/coherence/threshold-tuner.d.ts.map +1 -1
- package/v3/dist/integrations/coherence/threshold-tuner.js +3 -2
- package/v3/dist/integrations/coherence/threshold-tuner.js.map +1 -1
- package/v3/dist/integrations/coherence/wasm-loader.d.ts.map +1 -1
- package/v3/dist/integrations/coherence/wasm-loader.js +3 -2
- package/v3/dist/integrations/coherence/wasm-loader.js.map +1 -1
- package/v3/dist/integrations/n8n/agent-factory.d.ts.map +1 -1
- package/v3/dist/integrations/n8n/agent-factory.js +6 -4
- package/v3/dist/integrations/n8n/agent-factory.js.map +1 -1
- package/v3/dist/integrations/rl-suite/persistence/q-value-store.d.ts.map +1 -1
- package/v3/dist/integrations/rl-suite/persistence/q-value-store.js.map +1 -1
- package/v3/dist/integrations/ruvector/sona-persistence.d.ts.map +1 -1
- package/v3/dist/integrations/ruvector/sona-persistence.js +6 -4
- package/v3/dist/integrations/ruvector/sona-persistence.js.map +1 -1
- package/v3/dist/integrations/vibium/client.d.ts.map +1 -1
- package/v3/dist/integrations/vibium/client.js +3 -2
- package/v3/dist/integrations/vibium/client.js.map +1 -1
- package/v3/dist/kernel/agent-coordinator.d.ts +1 -1
- package/v3/dist/kernel/agent-coordinator.d.ts.map +1 -1
- package/v3/dist/kernel/agent-coordinator.js +4 -4
- package/v3/dist/kernel/agent-coordinator.js.map +1 -1
- package/v3/dist/kernel/constants.d.ts +155 -0
- package/v3/dist/kernel/constants.d.ts.map +1 -0
- package/v3/dist/kernel/constants.js +169 -0
- package/v3/dist/kernel/constants.js.map +1 -0
- package/v3/dist/kernel/event-bus.d.ts +8 -0
- package/v3/dist/kernel/event-bus.d.ts.map +1 -1
- package/v3/dist/kernel/event-bus.js +79 -17
- package/v3/dist/kernel/event-bus.js.map +1 -1
- package/v3/dist/kernel/hybrid-backend.d.ts.map +1 -1
- package/v3/dist/kernel/hybrid-backend.js +4 -3
- package/v3/dist/kernel/hybrid-backend.js.map +1 -1
- package/v3/dist/kernel/kernel.d.ts.map +1 -1
- package/v3/dist/kernel/kernel.js +3 -2
- package/v3/dist/kernel/kernel.js.map +1 -1
- package/v3/dist/kernel/memory-backend.d.ts.map +1 -1
- package/v3/dist/kernel/memory-backend.js +4 -3
- package/v3/dist/kernel/memory-backend.js.map +1 -1
- package/v3/dist/kernel/unified-memory.d.ts.map +1 -1
- package/v3/dist/kernel/unified-memory.js +14 -11
- package/v3/dist/kernel/unified-memory.js.map +1 -1
- package/v3/dist/kernel/unified-persistence.js +3 -2
- package/v3/dist/kernel/unified-persistence.js.map +1 -1
- package/v3/dist/learning/aqe-learning-engine.d.ts.map +1 -1
- package/v3/dist/learning/aqe-learning-engine.js +12 -8
- package/v3/dist/learning/aqe-learning-engine.js.map +1 -1
- package/v3/dist/learning/dream/index.d.ts +1 -1
- package/v3/dist/learning/dream/index.d.ts.map +1 -1
- package/v3/dist/learning/dream/index.js +3 -1
- package/v3/dist/learning/dream/index.js.map +1 -1
- package/v3/dist/learning/dream/spreading-activation.d.ts +41 -0
- package/v3/dist/learning/dream/spreading-activation.d.ts.map +1 -1
- package/v3/dist/learning/dream/spreading-activation.js +79 -0
- package/v3/dist/learning/dream/spreading-activation.js.map +1 -1
- package/v3/dist/learning/experience-capture-middleware.d.ts +119 -0
- package/v3/dist/learning/experience-capture-middleware.d.ts.map +1 -0
- package/v3/dist/learning/experience-capture-middleware.js +416 -0
- package/v3/dist/learning/experience-capture-middleware.js.map +1 -0
- package/v3/dist/learning/pattern-store.d.ts.map +1 -1
- package/v3/dist/learning/pattern-store.js +16 -6
- package/v3/dist/learning/pattern-store.js.map +1 -1
- package/v3/dist/learning/real-embeddings.d.ts.map +1 -1
- package/v3/dist/learning/real-embeddings.js +7 -1
- package/v3/dist/learning/real-embeddings.js.map +1 -1
- package/v3/dist/learning/sqlite-persistence.d.ts +1 -1
- package/v3/dist/learning/sqlite-persistence.d.ts.map +1 -1
- package/v3/dist/learning/sqlite-persistence.js.map +1 -1
- package/v3/dist/logging/console-logger.d.ts +96 -0
- package/v3/dist/logging/console-logger.d.ts.map +1 -0
- package/v3/dist/logging/console-logger.js +247 -0
- package/v3/dist/logging/console-logger.js.map +1 -0
- package/v3/dist/logging/index.d.ts +42 -0
- package/v3/dist/logging/index.d.ts.map +1 -0
- package/v3/dist/logging/index.js +39 -0
- package/v3/dist/logging/index.js.map +1 -0
- package/v3/dist/logging/logger-factory.d.ts +145 -0
- package/v3/dist/logging/logger-factory.d.ts.map +1 -0
- package/v3/dist/logging/logger-factory.js +218 -0
- package/v3/dist/logging/logger-factory.js.map +1 -0
- package/v3/dist/logging/logger.d.ts +89 -0
- package/v3/dist/logging/logger.d.ts.map +1 -0
- package/v3/dist/logging/logger.js +74 -0
- package/v3/dist/logging/logger.js.map +1 -0
- package/v3/dist/mcp/bundle.js +63771 -53632
- package/v3/dist/mcp/handlers/agent-handlers.js +2 -2
- package/v3/dist/mcp/handlers/agent-handlers.js.map +1 -1
- package/v3/dist/mcp/handlers/core-handlers.d.ts +2 -0
- package/v3/dist/mcp/handlers/core-handlers.d.ts.map +1 -1
- package/v3/dist/mcp/handlers/core-handlers.js +33 -0
- package/v3/dist/mcp/handlers/core-handlers.js.map +1 -1
- package/v3/dist/mcp/handlers/cross-phase-handlers.d.ts +110 -0
- package/v3/dist/mcp/handlers/cross-phase-handlers.d.ts.map +1 -0
- package/v3/dist/mcp/handlers/cross-phase-handlers.js +216 -0
- package/v3/dist/mcp/handlers/cross-phase-handlers.js.map +1 -0
- package/v3/dist/mcp/handlers/domain-handler-configs.d.ts +151 -0
- package/v3/dist/mcp/handlers/domain-handler-configs.d.ts.map +1 -0
- package/v3/dist/mcp/handlers/domain-handler-configs.js +486 -0
- package/v3/dist/mcp/handlers/domain-handler-configs.js.map +1 -0
- package/v3/dist/mcp/handlers/domain-handlers.d.ts +174 -121
- package/v3/dist/mcp/handlers/domain-handlers.d.ts.map +1 -1
- package/v3/dist/mcp/handlers/domain-handlers.js +178 -1049
- package/v3/dist/mcp/handlers/domain-handlers.js.map +1 -1
- package/v3/dist/mcp/handlers/handler-factory.d.ts +182 -0
- package/v3/dist/mcp/handlers/handler-factory.d.ts.map +1 -0
- package/v3/dist/mcp/handlers/handler-factory.js +327 -0
- package/v3/dist/mcp/handlers/handler-factory.js.map +1 -0
- package/v3/dist/mcp/handlers/index.d.ts +2 -1
- package/v3/dist/mcp/handlers/index.d.ts.map +1 -1
- package/v3/dist/mcp/handlers/index.js +4 -2
- package/v3/dist/mcp/handlers/index.js.map +1 -1
- package/v3/dist/mcp/handlers/task-handlers.d.ts +1 -0
- package/v3/dist/mcp/handlers/task-handlers.d.ts.map +1 -1
- package/v3/dist/mcp/handlers/task-handlers.js +91 -7
- package/v3/dist/mcp/handlers/task-handlers.js.map +1 -1
- package/v3/dist/mcp/handlers/wrapped-domain-handlers.d.ts +30 -0
- package/v3/dist/mcp/handlers/wrapped-domain-handlers.d.ts.map +1 -0
- package/v3/dist/mcp/handlers/wrapped-domain-handlers.js +75 -0
- package/v3/dist/mcp/handlers/wrapped-domain-handlers.js.map +1 -0
- package/v3/dist/mcp/server.d.ts.map +1 -1
- package/v3/dist/mcp/server.js +107 -1
- package/v3/dist/mcp/server.js.map +1 -1
- package/v3/dist/mcp/tools/chaos-resilience/inject.js +1 -1
- package/v3/dist/mcp/tools/chaos-resilience/inject.js.map +1 -1
- package/v3/dist/mcp/tools/contract-testing/validate.js +1 -1
- package/v3/dist/mcp/tools/contract-testing/validate.js.map +1 -1
- package/v3/dist/mcp/tools/learning-optimization/optimize.js +1 -1
- package/v3/dist/mcp/tools/learning-optimization/optimize.js.map +1 -1
- package/v3/dist/mcp/tools/visual-accessibility/index.js +2 -2
- package/v3/dist/mcp/tools/visual-accessibility/index.js.map +1 -1
- package/v3/dist/mcp/types.d.ts +5 -3
- package/v3/dist/mcp/types.d.ts.map +1 -1
- package/v3/dist/memory/cross-phase-memory.d.ts +55 -0
- package/v3/dist/memory/cross-phase-memory.d.ts.map +1 -0
- package/v3/dist/memory/cross-phase-memory.js +265 -0
- package/v3/dist/memory/cross-phase-memory.js.map +1 -0
- package/v3/dist/memory/index.d.ts +9 -0
- package/v3/dist/memory/index.d.ts.map +1 -0
- package/v3/dist/memory/index.js +9 -0
- package/v3/dist/memory/index.js.map +1 -0
- package/v3/dist/routing/qe-agent-registry.d.ts +1 -1
- package/v3/dist/routing/qe-agent-registry.d.ts.map +1 -1
- package/v3/dist/routing/qe-agent-registry.js +20 -1
- package/v3/dist/routing/qe-agent-registry.js.map +1 -1
- package/v3/dist/shared/io/file-reader.d.ts.map +1 -1
- package/v3/dist/shared/io/file-reader.js +3 -2
- package/v3/dist/shared/io/file-reader.js.map +1 -1
- package/v3/dist/shared/utils/binary-insert.d.ts +85 -0
- package/v3/dist/shared/utils/binary-insert.d.ts.map +1 -0
- package/v3/dist/shared/utils/binary-insert.js +122 -0
- package/v3/dist/shared/utils/binary-insert.js.map +1 -0
- package/v3/dist/shared/utils/index.d.ts +1 -0
- package/v3/dist/shared/utils/index.d.ts.map +1 -1
- package/v3/dist/shared/utils/index.js +1 -0
- package/v3/dist/shared/utils/index.js.map +1 -1
- package/v3/dist/strange-loop/belief-reconciler.d.ts.map +1 -1
- package/v3/dist/strange-loop/belief-reconciler.js +3 -2
- package/v3/dist/strange-loop/belief-reconciler.js.map +1 -1
- package/v3/dist/sync/claude-flow-bridge.d.ts +63 -0
- package/v3/dist/sync/claude-flow-bridge.d.ts.map +1 -0
- package/v3/dist/sync/claude-flow-bridge.js +322 -0
- package/v3/dist/sync/claude-flow-bridge.js.map +1 -0
- package/v3/dist/sync/cloud/postgres-writer.d.ts.map +1 -1
- package/v3/dist/sync/cloud/postgres-writer.js +0 -1
- package/v3/dist/sync/cloud/postgres-writer.js.map +1 -1
- package/v3/dist/sync/readers/sqlite-reader.d.ts.map +1 -1
- package/v3/dist/sync/readers/sqlite-reader.js +3 -2
- package/v3/dist/sync/readers/sqlite-reader.js.map +1 -1
- package/v3/dist/test-scheduling/flaky-tracking/flaky-tracker.d.ts.map +1 -1
- package/v3/dist/test-scheduling/flaky-tracking/flaky-tracker.js +3 -2
- package/v3/dist/test-scheduling/flaky-tracking/flaky-tracker.js.map +1 -1
- package/v3/dist/test-scheduling/git-aware/test-selector.d.ts.map +1 -1
- package/v3/dist/test-scheduling/git-aware/test-selector.js +3 -2
- package/v3/dist/test-scheduling/git-aware/test-selector.js.map +1 -1
- package/v3/dist/types/cross-phase-signals.d.ts +119 -0
- package/v3/dist/types/cross-phase-signals.d.ts.map +1 -0
- package/v3/dist/types/cross-phase-signals.js +33 -0
- package/v3/dist/types/cross-phase-signals.js.map +1 -0
- package/v3/dist/types/index.d.ts +9 -0
- package/v3/dist/types/index.d.ts.map +1 -0
- package/v3/dist/types/index.js +9 -0
- package/v3/dist/types/index.js.map +1 -0
- package/v3/dist/workers/worker-manager.d.ts.map +1 -1
- package/v3/dist/workers/worker-manager.js +3 -2
- package/v3/dist/workers/worker-manager.js.map +1 -1
- package/v3/dist/workflows/browser/workflow-loader.d.ts +3 -3
- package/v3/dist/workflows/browser/workflow-loader.d.ts.map +1 -1
- package/v3/dist/workflows/browser/workflow-loader.js.map +1 -1
- package/v3/package.json +4 -1
|
@@ -1,1769 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Agentic QE v3 - E2E Test Runner Service
|
|
2
|
+
* Agentic QE v3 - E2E Test Runner Service (Facade)
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* Provides step-by-step execution with retry logic, timeout handling,
|
|
7
|
-
* and comprehensive result aggregation.
|
|
4
|
+
* This file is a backward-compatible facade that re-exports from the
|
|
5
|
+
* modular E2E runner components located in ./e2e/
|
|
8
6
|
*
|
|
9
|
-
*
|
|
10
|
-
* -
|
|
11
|
-
* -
|
|
12
|
-
* -
|
|
7
|
+
* The E2E runner has been split into modular components:
|
|
8
|
+
* - e2e/types.ts: Configuration, interfaces, errors (~170 LOC)
|
|
9
|
+
* - e2e/browser-orchestrator.ts: Browser client management (~330 LOC)
|
|
10
|
+
* - e2e/step-executors.ts: Individual step execution (~850 LOC)
|
|
11
|
+
* - e2e/step-retry-handler.ts: Retry logic and timeout handling (~160 LOC)
|
|
12
|
+
* - e2e/result-collector.ts: Result aggregation (~150 LOC)
|
|
13
|
+
* - e2e/e2e-coordinator.ts: Main service orchestration (~340 LOC)
|
|
13
14
|
*
|
|
14
|
-
*
|
|
15
|
-
* - Snapshot-based element refs (@e1, @e2) for reliable element selection
|
|
16
|
-
* - Session management for state persistence
|
|
17
|
-
* - Network interception and API mocking
|
|
18
|
-
* - Device emulation for responsive testing
|
|
15
|
+
* All original public exports are preserved for backward compatibility.
|
|
19
16
|
*
|
|
20
17
|
* @module test-execution/services/e2e-runner
|
|
21
18
|
*/
|
|
22
|
-
import { safeEvaluateBoolean } from '../../../shared/utils/safe-expression-evaluator.js';
|
|
23
|
-
// Import unified browser client types
|
|
24
|
-
import { getBrowserClientForUseCase, } from '../../../integrations/browser';
|
|
25
|
-
import { isNavigateStep, isClickStep, isTypeStep, isWaitStep, isAssertStep, isScreenshotStep, isA11yCheckStep, } from '../types';
|
|
26
|
-
/**
|
|
27
|
-
* Default E2E runner configuration
|
|
28
|
-
*/
|
|
29
|
-
export const DEFAULT_E2E_RUNNER_CONFIG = {
|
|
30
|
-
defaultStepTimeout: 30000,
|
|
31
|
-
defaultRetries: 2,
|
|
32
|
-
retryDelay: 1000,
|
|
33
|
-
screenshotOnFailure: true,
|
|
34
|
-
stopOnFirstFailure: false,
|
|
35
|
-
pollingInterval: 100,
|
|
36
|
-
maxParallelWorkers: 4,
|
|
37
|
-
verbose: false,
|
|
38
|
-
preferAgentBrowser: true,
|
|
39
|
-
browserClientType: 'auto',
|
|
40
|
-
};
|
|
41
|
-
// ============================================================================
|
|
42
|
-
// E2E Runner Errors
|
|
43
|
-
// ============================================================================
|
|
44
|
-
/**
|
|
45
|
-
* E2E Runner error class
|
|
46
|
-
*/
|
|
47
|
-
export class E2ERunnerError extends Error {
|
|
48
|
-
code;
|
|
49
|
-
stepId;
|
|
50
|
-
cause;
|
|
51
|
-
constructor(message, code, stepId, cause) {
|
|
52
|
-
super(message);
|
|
53
|
-
this.code = code;
|
|
54
|
-
this.stepId = stepId;
|
|
55
|
-
this.cause = cause;
|
|
56
|
-
this.name = 'E2ERunnerError';
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Step timeout error
|
|
61
|
-
*/
|
|
62
|
-
export class StepTimeoutError extends E2ERunnerError {
|
|
63
|
-
constructor(stepId, timeout, cause) {
|
|
64
|
-
super(`Step "${stepId}" timed out after ${timeout}ms`, 'STEP_TIMEOUT', stepId, cause);
|
|
65
|
-
this.name = 'StepTimeoutError';
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Assertion failure error
|
|
70
|
-
*/
|
|
71
|
-
export class AssertionError extends E2ERunnerError {
|
|
72
|
-
expected;
|
|
73
|
-
actual;
|
|
74
|
-
constructor(message, stepId, expected, actual, cause) {
|
|
75
|
-
super(message, 'ASSERTION_FAILED', stepId, cause);
|
|
76
|
-
this.expected = expected;
|
|
77
|
-
this.actual = actual;
|
|
78
|
-
this.name = 'AssertionError';
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
19
|
// ============================================================================
|
|
82
|
-
//
|
|
20
|
+
// Re-export all public API from modular components
|
|
83
21
|
// ============================================================================
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
return 'tool' in client && client.tool === 'agent-browser';
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Type guard to check if client is a Vibium client (legacy)
|
|
92
|
-
*/
|
|
93
|
-
function isVibiumClient(client) {
|
|
94
|
-
return !('tool' in client) || !client.tool;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Convert a step selector to an ElementTarget for the unified browser interface
|
|
98
|
-
* Supports CSS selectors, XPath, text content, and agent-browser refs
|
|
99
|
-
*
|
|
100
|
-
* @param selector - The selector string from the step
|
|
101
|
-
* @returns ElementTarget for use with IBrowserClient
|
|
102
|
-
*/
|
|
103
|
-
function toElementTarget(selector) {
|
|
104
|
-
// Agent-browser snapshot refs (@e1, @e2, e1, e2)
|
|
105
|
-
if (/^@?e\d+$/.test(selector)) {
|
|
106
|
-
const value = selector.startsWith('@') ? selector : `@${selector}`;
|
|
107
|
-
return { type: 'ref', value };
|
|
108
|
-
}
|
|
109
|
-
// XPath selectors
|
|
110
|
-
if (selector.startsWith('//') || selector.startsWith('xpath=')) {
|
|
111
|
-
const value = selector.replace(/^xpath=/, '');
|
|
112
|
-
return { type: 'xpath', value };
|
|
113
|
-
}
|
|
114
|
-
// Text content matching
|
|
115
|
-
if (selector.startsWith('text=')) {
|
|
116
|
-
const value = selector.replace(/^text=/, '');
|
|
117
|
-
return { type: 'text', value };
|
|
118
|
-
}
|
|
119
|
-
// Default to CSS selector
|
|
120
|
-
return { type: 'css', value: selector };
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Convert BrowserScreenshotResult to Vibium ScreenshotResult format
|
|
124
|
-
* This is needed for backward compatibility
|
|
125
|
-
*/
|
|
126
|
-
function toVibiumScreenshotResult(result) {
|
|
127
|
-
return {
|
|
128
|
-
base64: result.base64,
|
|
129
|
-
path: result.path,
|
|
130
|
-
format: result.format,
|
|
131
|
-
dimensions: result.dimensions,
|
|
132
|
-
sizeBytes: result.base64 ? Math.ceil(result.base64.length * 0.75) : 0, // Estimate size from base64
|
|
133
|
-
capturedAt: new Date(),
|
|
134
|
-
};
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Convert axe-core results to Vibium AccessibilityResult format
|
|
138
|
-
*/
|
|
139
|
-
function toVibiumAccessibilityResult(axeResults) {
|
|
140
|
-
// Count violations by severity
|
|
141
|
-
const violationsBySeverity = {
|
|
142
|
-
critical: 0,
|
|
143
|
-
high: 0,
|
|
144
|
-
medium: 0,
|
|
145
|
-
low: 0,
|
|
146
|
-
info: 0,
|
|
147
|
-
};
|
|
148
|
-
const violations = axeResults.violations.map((v) => {
|
|
149
|
-
const impact = v.impact;
|
|
150
|
-
if (impact in violationsBySeverity) {
|
|
151
|
-
violationsBySeverity[impact]++;
|
|
152
|
-
}
|
|
153
|
-
return {
|
|
154
|
-
id: v.id,
|
|
155
|
-
impact: v.impact,
|
|
156
|
-
description: v.description,
|
|
157
|
-
nodes: v.nodes.length,
|
|
158
|
-
};
|
|
159
|
-
});
|
|
160
|
-
return {
|
|
161
|
-
passes: violations.length === 0,
|
|
162
|
-
violations: violations,
|
|
163
|
-
violationsBySeverity,
|
|
164
|
-
passedRules: axeResults.passes.map((p) => p.id),
|
|
165
|
-
incompleteRules: axeResults.incomplete.map((i) => i.id),
|
|
166
|
-
checkedAt: new Date(),
|
|
167
|
-
};
|
|
168
|
-
}
|
|
22
|
+
// Types and Configuration
|
|
23
|
+
export { DEFAULT_E2E_RUNNER_CONFIG, E2ERunnerError, StepTimeoutError, AssertionError, } from './e2e/types';
|
|
24
|
+
// Main Service and Factory Functions
|
|
25
|
+
export { E2ETestRunnerService, createE2ETestRunnerService, createE2ETestRunnerServiceWithBrowserClient, createAutoE2ETestRunnerService, } from './e2e/e2e-coordinator';
|
|
169
26
|
// ============================================================================
|
|
170
|
-
//
|
|
27
|
+
// Additional exports for advanced usage (internal modules)
|
|
171
28
|
// ============================================================================
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
* Agent-browser provides enhanced E2E testing capabilities:
|
|
181
|
-
* - Snapshot-based element refs (@e1, @e2) for reliable element selection
|
|
182
|
-
* - Session management for state persistence
|
|
183
|
-
* - Network interception and API mocking
|
|
184
|
-
* - Device emulation for responsive testing
|
|
185
|
-
*/
|
|
186
|
-
export class E2ETestRunnerService {
|
|
187
|
-
client;
|
|
188
|
-
config;
|
|
189
|
-
unifiedClient;
|
|
190
|
-
useAgentBrowser;
|
|
191
|
-
/**
|
|
192
|
-
* Create E2E Test Runner Service
|
|
193
|
-
*
|
|
194
|
-
* @param client - Browser automation client (VibiumClient or IBrowserClient)
|
|
195
|
-
* @param config - Runner configuration
|
|
196
|
-
*
|
|
197
|
-
* @example
|
|
198
|
-
* ```typescript
|
|
199
|
-
* // Using VibiumClient (legacy)
|
|
200
|
-
* const vibiumClient = await createVibiumClient({ enabled: true });
|
|
201
|
-
* const runner = new E2ETestRunnerService(vibiumClient);
|
|
202
|
-
*
|
|
203
|
-
* // Using agent-browser (recommended for E2E)
|
|
204
|
-
* const agentClient = await createAgentBrowserClient();
|
|
205
|
-
* const runner = new E2ETestRunnerService(agentClient, {
|
|
206
|
-
* preferAgentBrowser: true
|
|
207
|
-
* });
|
|
208
|
-
*
|
|
209
|
-
* // Using auto-selection
|
|
210
|
-
* const runner = createE2ETestRunnerServiceWithBrowserClient(undefined, {
|
|
211
|
-
* browserClientType: 'auto'
|
|
212
|
-
* });
|
|
213
|
-
* ```
|
|
214
|
-
*/
|
|
215
|
-
constructor(client, config = {}) {
|
|
216
|
-
this.client = client;
|
|
217
|
-
this.config = { ...DEFAULT_E2E_RUNNER_CONFIG, ...config };
|
|
218
|
-
// Use provided browser client from config if available
|
|
219
|
-
this.unifiedClient = config.browserClient ?? client;
|
|
220
|
-
// Determine if we're using agent-browser
|
|
221
|
-
this.useAgentBrowser = isAgentBrowserClient(this.unifiedClient);
|
|
222
|
-
this.log(`E2E Runner initialized with ${this.useAgentBrowser ? 'agent-browser' : 'vibium'} client`);
|
|
223
|
-
}
|
|
224
|
-
// ==========================================================================
|
|
225
|
-
// Public Methods
|
|
226
|
-
// ==========================================================================
|
|
227
|
-
/**
|
|
228
|
-
* Execute a single E2E test case
|
|
229
|
-
*/
|
|
230
|
-
async runTestCase(testCase) {
|
|
231
|
-
const startedAt = new Date();
|
|
232
|
-
const stepResults = [];
|
|
233
|
-
const screenshots = [];
|
|
234
|
-
const accessibilityResults = [];
|
|
235
|
-
// Check if test should be skipped
|
|
236
|
-
if (testCase.skip) {
|
|
237
|
-
return this.createSkippedResult(testCase, startedAt);
|
|
238
|
-
}
|
|
239
|
-
// Validate required environment variables
|
|
240
|
-
if (testCase.requiredEnvVars?.length) {
|
|
241
|
-
const missingVars = testCase.requiredEnvVars.filter((v) => !process.env[v]);
|
|
242
|
-
if (missingVars.length > 0) {
|
|
243
|
-
return this.createErrorResult(testCase, startedAt, `Missing required environment variables: ${missingVars.join(', ')}`);
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
try {
|
|
247
|
-
// Launch browser based on client type
|
|
248
|
-
const launchError = await this.ensureBrowserLaunched(testCase);
|
|
249
|
-
if (launchError) {
|
|
250
|
-
return this.createErrorResult(testCase, startedAt, launchError);
|
|
251
|
-
}
|
|
252
|
-
// Create execution context
|
|
253
|
-
const context = {
|
|
254
|
-
testCase,
|
|
255
|
-
baseUrl: testCase.baseUrl,
|
|
256
|
-
variables: testCase.testData ?? {},
|
|
257
|
-
previousResults: stepResults,
|
|
258
|
-
useAgentBrowser: this.useAgentBrowser,
|
|
259
|
-
};
|
|
260
|
-
// Get initial snapshot for agent-browser
|
|
261
|
-
if (this.useAgentBrowser) {
|
|
262
|
-
context.currentSnapshot = await this.refreshSnapshot();
|
|
263
|
-
}
|
|
264
|
-
// Execute beforeAll hooks
|
|
265
|
-
if (testCase.hooks?.beforeAll) {
|
|
266
|
-
const hookResults = await this.executeHooks(testCase.hooks.beforeAll, context, 'beforeAll');
|
|
267
|
-
stepResults.push(...hookResults);
|
|
268
|
-
if (this.hasFailure(hookResults) && this.config.stopOnFirstFailure) {
|
|
269
|
-
return this.createResult(testCase, startedAt, stepResults, screenshots, accessibilityResults);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
// Execute test steps
|
|
273
|
-
for (const step of testCase.steps) {
|
|
274
|
-
// Execute beforeEach hooks
|
|
275
|
-
if (testCase.hooks?.beforeEach) {
|
|
276
|
-
const hookResults = await this.executeHooks(testCase.hooks.beforeEach, context, 'beforeEach');
|
|
277
|
-
stepResults.push(...hookResults);
|
|
278
|
-
}
|
|
279
|
-
// Handle delay before step
|
|
280
|
-
if (step.delayBefore && step.delayBefore > 0) {
|
|
281
|
-
await this.delay(step.delayBefore);
|
|
282
|
-
}
|
|
283
|
-
// Execute the step with retry logic
|
|
284
|
-
const stepResult = await this.executeStepWithRetry(step, context);
|
|
285
|
-
stepResults.push(stepResult);
|
|
286
|
-
// Collect screenshots and accessibility results
|
|
287
|
-
if (stepResult.screenshot) {
|
|
288
|
-
screenshots.push(stepResult.screenshot);
|
|
289
|
-
}
|
|
290
|
-
if (stepResult.accessibilityResult) {
|
|
291
|
-
accessibilityResults.push(stepResult.accessibilityResult);
|
|
292
|
-
}
|
|
293
|
-
// Handle delay after step
|
|
294
|
-
if (step.delayAfter && step.delayAfter > 0) {
|
|
295
|
-
await this.delay(step.delayAfter);
|
|
296
|
-
}
|
|
297
|
-
// Execute afterEach hooks
|
|
298
|
-
if (testCase.hooks?.afterEach) {
|
|
299
|
-
const hookResults = await this.executeHooks(testCase.hooks.afterEach, context, 'afterEach');
|
|
300
|
-
stepResults.push(...hookResults);
|
|
301
|
-
}
|
|
302
|
-
// Check for step failure
|
|
303
|
-
if (!stepResult.success) {
|
|
304
|
-
// Execute onFailure hooks
|
|
305
|
-
if (testCase.hooks?.onFailure) {
|
|
306
|
-
const hookResults = await this.executeHooks(testCase.hooks.onFailure, context, 'onFailure');
|
|
307
|
-
stepResults.push(...hookResults);
|
|
308
|
-
}
|
|
309
|
-
// Capture failure screenshot if enabled
|
|
310
|
-
if (this.config.screenshotOnFailure && !stepResult.screenshot) {
|
|
311
|
-
const failureScreenshot = await this.captureFailureScreenshot(step.id);
|
|
312
|
-
if (failureScreenshot) {
|
|
313
|
-
stepResult.error = {
|
|
314
|
-
...stepResult.error,
|
|
315
|
-
failureScreenshot,
|
|
316
|
-
};
|
|
317
|
-
screenshots.push(failureScreenshot);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
// Stop on first failure if configured and step is required
|
|
321
|
-
if (this.config.stopOnFirstFailure && step.required && !step.continueOnFailure) {
|
|
322
|
-
break;
|
|
323
|
-
}
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
// Execute afterAll hooks
|
|
327
|
-
if (testCase.hooks?.afterAll) {
|
|
328
|
-
const hookResults = await this.executeHooks(testCase.hooks.afterAll, context, 'afterAll');
|
|
329
|
-
stepResults.push(...hookResults);
|
|
330
|
-
}
|
|
331
|
-
return this.createResult(testCase, startedAt, stepResults, screenshots, accessibilityResults);
|
|
332
|
-
}
|
|
333
|
-
catch (error) {
|
|
334
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
335
|
-
return this.createErrorResult(testCase, startedAt, errorMessage, stepResults);
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
/**
|
|
339
|
-
* Execute an E2E test suite
|
|
340
|
-
*/
|
|
341
|
-
async runTestSuite(suite, strategy = suite.parallel ? 'parallel' : 'sequential') {
|
|
342
|
-
const startedAt = new Date();
|
|
343
|
-
const testResults = [];
|
|
344
|
-
// Filter test cases (handle 'only' flag)
|
|
345
|
-
const onlyTests = suite.testCases.filter((tc) => tc.only);
|
|
346
|
-
const testsToRun = onlyTests.length > 0 ? onlyTests : suite.testCases;
|
|
347
|
-
if (strategy === 'parallel') {
|
|
348
|
-
// Execute tests in parallel with limited concurrency
|
|
349
|
-
const results = await this.executeInParallel(testsToRun, suite.maxWorkers);
|
|
350
|
-
testResults.push(...results);
|
|
351
|
-
}
|
|
352
|
-
else {
|
|
353
|
-
// Execute tests sequentially
|
|
354
|
-
for (const testCase of testsToRun) {
|
|
355
|
-
const result = await this.runTestCase(testCase);
|
|
356
|
-
testResults.push(result);
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
const completedAt = new Date();
|
|
360
|
-
const summary = this.calculateSummary(testResults);
|
|
361
|
-
return {
|
|
362
|
-
suiteId: suite.id,
|
|
363
|
-
suiteName: suite.name,
|
|
364
|
-
success: summary.failed === 0,
|
|
365
|
-
testResults,
|
|
366
|
-
summary: {
|
|
367
|
-
...summary,
|
|
368
|
-
totalDurationMs: completedAt.getTime() - startedAt.getTime(),
|
|
369
|
-
},
|
|
370
|
-
startedAt,
|
|
371
|
-
completedAt,
|
|
372
|
-
};
|
|
373
|
-
}
|
|
374
|
-
// ==========================================================================
|
|
375
|
-
// Browser Launch Helper
|
|
376
|
-
// ==========================================================================
|
|
377
|
-
/**
|
|
378
|
-
* Ensure browser is launched for the test case
|
|
379
|
-
* Handles both agent-browser and Vibium clients
|
|
380
|
-
*/
|
|
381
|
-
async ensureBrowserLaunched(testCase) {
|
|
382
|
-
try {
|
|
383
|
-
if (this.useAgentBrowser && isAgentBrowserClient(this.unifiedClient)) {
|
|
384
|
-
// Agent-browser launch - use client's configured session name
|
|
385
|
-
// Don't force a new session name to avoid conflicts
|
|
386
|
-
const launchResult = await this.unifiedClient.launch({
|
|
387
|
-
headless: true,
|
|
388
|
-
viewport: testCase.viewport,
|
|
389
|
-
// Use client's default session name, not test-specific
|
|
390
|
-
});
|
|
391
|
-
if (!launchResult.success) {
|
|
392
|
-
return `Failed to launch browser: ${launchResult.error.message}`;
|
|
393
|
-
}
|
|
394
|
-
return null;
|
|
395
|
-
}
|
|
396
|
-
else if (isVibiumClient(this.client)) {
|
|
397
|
-
// Legacy Vibium launch
|
|
398
|
-
const session = await this.client.getSession();
|
|
399
|
-
if (!session) {
|
|
400
|
-
const launchResult = await this.client.launch({
|
|
401
|
-
headless: true,
|
|
402
|
-
viewport: testCase.viewport,
|
|
403
|
-
...this.getBrowserContextOptions(testCase),
|
|
404
|
-
});
|
|
405
|
-
if (!launchResult.success) {
|
|
406
|
-
return `Failed to launch browser: ${launchResult.error.message}`;
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
return null;
|
|
410
|
-
}
|
|
411
|
-
else {
|
|
412
|
-
// Generic IBrowserClient launch
|
|
413
|
-
const launchResult = await this.unifiedClient.launch({
|
|
414
|
-
headless: true,
|
|
415
|
-
viewport: testCase.viewport,
|
|
416
|
-
});
|
|
417
|
-
if (!launchResult.success) {
|
|
418
|
-
return `Failed to launch browser: ${launchResult.error.message}`;
|
|
419
|
-
}
|
|
420
|
-
return null;
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
catch (error) {
|
|
424
|
-
return error instanceof Error ? error.message : String(error);
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
/**
|
|
428
|
-
* Refresh the page snapshot (agent-browser only)
|
|
429
|
-
*/
|
|
430
|
-
async refreshSnapshot() {
|
|
431
|
-
if (!this.useAgentBrowser || !isAgentBrowserClient(this.unifiedClient)) {
|
|
432
|
-
return undefined;
|
|
433
|
-
}
|
|
434
|
-
try {
|
|
435
|
-
const snapshotResult = await this.unifiedClient.getSnapshot({ interactive: true });
|
|
436
|
-
if (snapshotResult.success) {
|
|
437
|
-
return snapshotResult.value;
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
catch {
|
|
441
|
-
this.log('Failed to refresh snapshot');
|
|
442
|
-
}
|
|
443
|
-
return undefined;
|
|
444
|
-
}
|
|
445
|
-
// ==========================================================================
|
|
446
|
-
// Step Executors
|
|
447
|
-
// ==========================================================================
|
|
448
|
-
/**
|
|
449
|
-
* Execute a navigate step
|
|
450
|
-
* Supports both agent-browser and Vibium clients
|
|
451
|
-
*/
|
|
452
|
-
async executeNavigateStep(step, client, context) {
|
|
453
|
-
const url = this.resolveUrl(step.target, context.baseUrl);
|
|
454
|
-
// Use unified browser client if available
|
|
455
|
-
if (!isVibiumClient(client)) {
|
|
456
|
-
const browserClient = client;
|
|
457
|
-
const result = await browserClient.navigate(url);
|
|
458
|
-
if (!result.success) {
|
|
459
|
-
throw result.error;
|
|
460
|
-
}
|
|
461
|
-
// Refresh snapshot after navigation for agent-browser
|
|
462
|
-
if (context.useAgentBrowser) {
|
|
463
|
-
context.currentSnapshot = await this.refreshSnapshot();
|
|
464
|
-
}
|
|
465
|
-
return {
|
|
466
|
-
data: {
|
|
467
|
-
url: result.value.url,
|
|
468
|
-
title: result.value.title,
|
|
469
|
-
},
|
|
470
|
-
};
|
|
471
|
-
}
|
|
472
|
-
// Legacy Vibium path
|
|
473
|
-
const vibiumClient = client;
|
|
474
|
-
const result = await vibiumClient.navigate({
|
|
475
|
-
url,
|
|
476
|
-
waitUntil: step.options?.waitUntil ?? 'load',
|
|
477
|
-
timeout: step.timeout ?? this.config.defaultStepTimeout,
|
|
478
|
-
});
|
|
479
|
-
if (!result.success) {
|
|
480
|
-
throw result.error;
|
|
481
|
-
}
|
|
482
|
-
return {
|
|
483
|
-
data: {
|
|
484
|
-
url: result.value.url,
|
|
485
|
-
title: result.value.title,
|
|
486
|
-
},
|
|
487
|
-
};
|
|
488
|
-
}
|
|
489
|
-
/**
|
|
490
|
-
* Execute a click step
|
|
491
|
-
* Supports both agent-browser and Vibium clients
|
|
492
|
-
*/
|
|
493
|
-
async executeClickStep(step, client, context) {
|
|
494
|
-
// Use unified browser client if available
|
|
495
|
-
if (!isVibiumClient(client)) {
|
|
496
|
-
const browserClient = client;
|
|
497
|
-
const target = toElementTarget(step.target);
|
|
498
|
-
// Wait for element if using agent-browser
|
|
499
|
-
if (context.useAgentBrowser && isAgentBrowserClient(browserClient)) {
|
|
500
|
-
const waitResult = await browserClient.waitForElement(target, step.timeout);
|
|
501
|
-
if (!waitResult.success) {
|
|
502
|
-
throw waitResult.error;
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
const result = await browserClient.click(target);
|
|
506
|
-
if (!result.success) {
|
|
507
|
-
throw result.error;
|
|
508
|
-
}
|
|
509
|
-
// Refresh snapshot after click for agent-browser
|
|
510
|
-
if (context.useAgentBrowser) {
|
|
511
|
-
context.currentSnapshot = await this.refreshSnapshot();
|
|
512
|
-
}
|
|
513
|
-
// Wait for navigation if requested
|
|
514
|
-
if (step.options?.waitForNavigation && isAgentBrowserClient(browserClient)) {
|
|
515
|
-
await browserClient.waitForNetworkIdle(step.timeout);
|
|
516
|
-
}
|
|
517
|
-
return {
|
|
518
|
-
data: {},
|
|
519
|
-
};
|
|
520
|
-
}
|
|
521
|
-
// Legacy Vibium path
|
|
522
|
-
const vibiumClient = client;
|
|
523
|
-
// Scroll into view if requested
|
|
524
|
-
if (step.options?.scrollIntoView) {
|
|
525
|
-
await this.scrollIntoView(vibiumClient, step.target);
|
|
526
|
-
}
|
|
527
|
-
// Hover first if requested
|
|
528
|
-
if (step.options?.hoverFirst) {
|
|
529
|
-
const findResult = await vibiumClient.findElement({ selector: step.target });
|
|
530
|
-
if (!findResult.success) {
|
|
531
|
-
throw findResult.error;
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
const result = await vibiumClient.click({
|
|
535
|
-
selector: step.target,
|
|
536
|
-
button: step.options?.button,
|
|
537
|
-
clickCount: step.options?.clickCount,
|
|
538
|
-
delay: step.options?.delay,
|
|
539
|
-
position: step.options?.position,
|
|
540
|
-
modifiers: step.options?.modifiers,
|
|
541
|
-
force: step.options?.force,
|
|
542
|
-
timeout: step.timeout ?? this.config.defaultStepTimeout,
|
|
543
|
-
});
|
|
544
|
-
if (!result.success) {
|
|
545
|
-
throw result.error;
|
|
546
|
-
}
|
|
547
|
-
// Wait for navigation if requested
|
|
548
|
-
if (step.options?.waitForNavigation) {
|
|
549
|
-
await this.delay(500);
|
|
550
|
-
const pageInfo = await vibiumClient.getPageInfo();
|
|
551
|
-
if (pageInfo.success) {
|
|
552
|
-
return {
|
|
553
|
-
data: {
|
|
554
|
-
url: pageInfo.value.url,
|
|
555
|
-
},
|
|
556
|
-
};
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
return {
|
|
560
|
-
data: {
|
|
561
|
-
elementText: result.value.element?.textContent,
|
|
562
|
-
},
|
|
563
|
-
};
|
|
564
|
-
}
|
|
565
|
-
/**
|
|
566
|
-
* Execute a type step
|
|
567
|
-
* Supports both agent-browser and Vibium clients
|
|
568
|
-
*/
|
|
569
|
-
async executeTypeStep(step, client, context) {
|
|
570
|
-
// Use unified browser client if available
|
|
571
|
-
if (!isVibiumClient(client)) {
|
|
572
|
-
const browserClient = client;
|
|
573
|
-
const target = toElementTarget(step.target);
|
|
574
|
-
// Wait for element if using agent-browser
|
|
575
|
-
if (context.useAgentBrowser && isAgentBrowserClient(browserClient)) {
|
|
576
|
-
const waitResult = await browserClient.waitForElement(target, step.timeout);
|
|
577
|
-
if (!waitResult.success) {
|
|
578
|
-
throw waitResult.error;
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
const result = await browserClient.fill(target, step.value);
|
|
582
|
-
if (!result.success) {
|
|
583
|
-
throw result.error;
|
|
584
|
-
}
|
|
585
|
-
// Refresh snapshot after fill for agent-browser
|
|
586
|
-
if (context.useAgentBrowser) {
|
|
587
|
-
context.currentSnapshot = await this.refreshSnapshot();
|
|
588
|
-
}
|
|
589
|
-
return {
|
|
590
|
-
data: {
|
|
591
|
-
elementText: step.options?.sensitive ? '[MASKED]' : step.value,
|
|
592
|
-
},
|
|
593
|
-
};
|
|
594
|
-
}
|
|
595
|
-
// Legacy Vibium path
|
|
596
|
-
const vibiumClient = client;
|
|
597
|
-
const result = await vibiumClient.type({
|
|
598
|
-
selector: step.target,
|
|
599
|
-
text: step.value,
|
|
600
|
-
delay: step.options?.delay,
|
|
601
|
-
clear: step.options?.clear,
|
|
602
|
-
pressEnter: step.options?.pressEnter,
|
|
603
|
-
timeout: step.timeout ?? this.config.defaultStepTimeout,
|
|
604
|
-
});
|
|
605
|
-
if (!result.success) {
|
|
606
|
-
throw result.error;
|
|
607
|
-
}
|
|
608
|
-
return {
|
|
609
|
-
data: {
|
|
610
|
-
elementText: step.options?.sensitive ? '[MASKED]' : step.value,
|
|
611
|
-
},
|
|
612
|
-
};
|
|
613
|
-
}
|
|
614
|
-
/**
|
|
615
|
-
* Execute a wait step
|
|
616
|
-
* Supports both agent-browser and Vibium clients
|
|
617
|
-
*/
|
|
618
|
-
async executeWaitStep(step, client, context) {
|
|
619
|
-
const timeout = step.timeout ?? this.config.defaultStepTimeout;
|
|
620
|
-
const pollingInterval = step.options.pollingInterval ?? this.config.pollingInterval;
|
|
621
|
-
// Use agent-browser's native wait methods when available
|
|
622
|
-
if (!isVibiumClient(client) && isAgentBrowserClient(client)) {
|
|
623
|
-
const browserClient = client;
|
|
624
|
-
let waitResult;
|
|
625
|
-
switch (step.options.condition) {
|
|
626
|
-
case 'element-visible':
|
|
627
|
-
case 'element-hidden':
|
|
628
|
-
if (step.target) {
|
|
629
|
-
waitResult = await browserClient.waitForElement(toElementTarget(step.target), timeout);
|
|
630
|
-
}
|
|
631
|
-
break;
|
|
632
|
-
case 'element-text':
|
|
633
|
-
if (step.options.expectedText) {
|
|
634
|
-
waitResult = await browserClient.waitForText(step.options.expectedText, timeout);
|
|
635
|
-
}
|
|
636
|
-
break;
|
|
637
|
-
case 'url-match':
|
|
638
|
-
if (step.options.urlPattern) {
|
|
639
|
-
const pattern = typeof step.options.urlPattern === 'string'
|
|
640
|
-
? step.options.urlPattern
|
|
641
|
-
: step.options.urlPattern.source;
|
|
642
|
-
waitResult = await browserClient.waitForUrl(pattern, timeout);
|
|
643
|
-
}
|
|
644
|
-
break;
|
|
645
|
-
case 'network-idle':
|
|
646
|
-
case 'page-loaded':
|
|
647
|
-
case 'dom-loaded':
|
|
648
|
-
waitResult = await browserClient.waitForNetworkIdle(timeout);
|
|
649
|
-
break;
|
|
650
|
-
default:
|
|
651
|
-
// Fall back to polling for unsupported conditions
|
|
652
|
-
break;
|
|
653
|
-
}
|
|
654
|
-
if (waitResult && !waitResult.success) {
|
|
655
|
-
throw waitResult.error;
|
|
656
|
-
}
|
|
657
|
-
// Refresh snapshot after wait
|
|
658
|
-
context.currentSnapshot = await this.refreshSnapshot();
|
|
659
|
-
return { data: {} };
|
|
660
|
-
}
|
|
661
|
-
// Legacy Vibium path with polling
|
|
662
|
-
// Only use with VibiumClient
|
|
663
|
-
if (!isVibiumClient(client)) {
|
|
664
|
-
// For non-Vibium clients that aren't agent-browser, just wait for timeout
|
|
665
|
-
await this.delay(pollingInterval);
|
|
666
|
-
return { data: {} };
|
|
667
|
-
}
|
|
668
|
-
const waitData = await this.waitForCondition(step.options.condition, client, step, timeout, pollingInterval);
|
|
669
|
-
return {
|
|
670
|
-
data: waitData,
|
|
671
|
-
};
|
|
672
|
-
}
|
|
673
|
-
/**
|
|
674
|
-
* Execute an assert step
|
|
675
|
-
* Supports both agent-browser and Vibium clients
|
|
676
|
-
*/
|
|
677
|
-
async executeAssertStep(step, client, context) {
|
|
678
|
-
// Use unified browser client for assertions when available
|
|
679
|
-
if (!isVibiumClient(client)) {
|
|
680
|
-
const browserClient = client;
|
|
681
|
-
const assertResult = await this.performUnifiedAssertion(step.options.assertion, browserClient, step, context);
|
|
682
|
-
return {
|
|
683
|
-
data: {
|
|
684
|
-
actualValue: assertResult.actual,
|
|
685
|
-
expectedValue: assertResult.expected,
|
|
686
|
-
},
|
|
687
|
-
};
|
|
688
|
-
}
|
|
689
|
-
// Legacy Vibium path
|
|
690
|
-
const vibiumClient = client;
|
|
691
|
-
const assertResult = await this.performAssertion(step.options.assertion, vibiumClient, step);
|
|
692
|
-
return {
|
|
693
|
-
data: {
|
|
694
|
-
actualValue: assertResult.actual,
|
|
695
|
-
expectedValue: assertResult.expected,
|
|
696
|
-
},
|
|
697
|
-
};
|
|
698
|
-
}
|
|
699
|
-
/**
|
|
700
|
-
* Execute a screenshot step
|
|
701
|
-
* Supports both agent-browser and Vibium clients
|
|
702
|
-
*/
|
|
703
|
-
async executeScreenshotStep(step, client, _context) {
|
|
704
|
-
// Use unified browser client if available
|
|
705
|
-
if (!isVibiumClient(client)) {
|
|
706
|
-
const browserClient = client;
|
|
707
|
-
const result = await browserClient.screenshot({
|
|
708
|
-
path: step.target,
|
|
709
|
-
fullPage: step.options?.fullPage,
|
|
710
|
-
});
|
|
711
|
-
if (!result.success) {
|
|
712
|
-
throw result.error;
|
|
713
|
-
}
|
|
714
|
-
// Convert to ScreenshotResult format for consistency
|
|
715
|
-
const screenshotResult = toVibiumScreenshotResult(result.value);
|
|
716
|
-
return {
|
|
717
|
-
screenshot: screenshotResult,
|
|
718
|
-
data: {
|
|
719
|
-
url: result.value.path,
|
|
720
|
-
},
|
|
721
|
-
};
|
|
722
|
-
}
|
|
723
|
-
// Legacy Vibium path
|
|
724
|
-
const vibiumClient = client;
|
|
725
|
-
const result = await vibiumClient.screenshot({
|
|
726
|
-
selector: step.target,
|
|
727
|
-
fullPage: step.options?.fullPage,
|
|
728
|
-
format: step.options?.format,
|
|
729
|
-
quality: step.options?.quality,
|
|
730
|
-
omitBackground: step.options?.omitBackground,
|
|
731
|
-
});
|
|
732
|
-
if (!result.success) {
|
|
733
|
-
throw result.error;
|
|
734
|
-
}
|
|
735
|
-
return {
|
|
736
|
-
screenshot: result.value,
|
|
737
|
-
data: {
|
|
738
|
-
url: result.value.path,
|
|
739
|
-
},
|
|
740
|
-
};
|
|
741
|
-
}
|
|
742
|
-
/**
|
|
743
|
-
* Execute an accessibility check step
|
|
744
|
-
* Supports both agent-browser and Vibium clients
|
|
745
|
-
*/
|
|
746
|
-
async executeA11yCheckStep(step, client, _context) {
|
|
747
|
-
// Use unified browser client with evaluate for axe-core
|
|
748
|
-
if (!isVibiumClient(client)) {
|
|
749
|
-
const browserClient = client;
|
|
750
|
-
// Inject and run axe-core via evaluate
|
|
751
|
-
const axeScript = `
|
|
752
|
-
(async () => {
|
|
753
|
-
if (!window.axe) {
|
|
754
|
-
const script = document.createElement('script');
|
|
755
|
-
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/axe-core/4.7.2/axe.min.js';
|
|
756
|
-
document.head.appendChild(script);
|
|
757
|
-
await new Promise(resolve => script.onload = resolve);
|
|
758
|
-
}
|
|
759
|
-
const results = await axe.run(${step.target ? `'${step.target}'` : 'document'}, {
|
|
760
|
-
runOnly: ${JSON.stringify(step.options?.tags ?? ['wcag2a', 'wcag2aa'])},
|
|
761
|
-
});
|
|
762
|
-
return JSON.stringify(results);
|
|
763
|
-
})()
|
|
764
|
-
`;
|
|
765
|
-
const evalResult = await browserClient.evaluate(axeScript);
|
|
766
|
-
if (!evalResult.success) {
|
|
767
|
-
throw evalResult.error;
|
|
768
|
-
}
|
|
769
|
-
const axeResults = JSON.parse(evalResult.value);
|
|
770
|
-
const a11yResult = toVibiumAccessibilityResult(axeResults);
|
|
771
|
-
// Check severity thresholds
|
|
772
|
-
if (step.options?.failOnSeverity) {
|
|
773
|
-
const severityOrder = {
|
|
774
|
-
critical: 0, high: 1, medium: 2, low: 3, info: 4,
|
|
775
|
-
};
|
|
776
|
-
const threshold = severityOrder[step.options.failOnSeverity];
|
|
777
|
-
const violationsOverThreshold = axeResults.violations.filter((v) => severityOrder[v.impact] <= threshold);
|
|
778
|
-
if (violationsOverThreshold.length > 0) {
|
|
779
|
-
throw new AssertionError(`Accessibility violations found: ${violationsOverThreshold.length} at or above ${step.options.failOnSeverity}`, step.id, 0, violationsOverThreshold.length);
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
return { accessibilityResult: a11yResult };
|
|
783
|
-
}
|
|
784
|
-
// Legacy Vibium path
|
|
785
|
-
const vibiumClient = client;
|
|
786
|
-
const result = await vibiumClient.checkAccessibility({
|
|
787
|
-
selector: step.target,
|
|
788
|
-
wcagLevel: step.options?.wcagLevel ?? 'AA',
|
|
789
|
-
rules: step.options?.rules
|
|
790
|
-
? {
|
|
791
|
-
include: step.options.tags,
|
|
792
|
-
exclude: step.options.context?.exclude,
|
|
793
|
-
}
|
|
794
|
-
: undefined,
|
|
795
|
-
});
|
|
796
|
-
if (!result.success) {
|
|
797
|
-
throw result.error;
|
|
798
|
-
}
|
|
799
|
-
const a11yResult = result.value;
|
|
800
|
-
// Check if violations exceed threshold
|
|
801
|
-
if (step.options?.failOnSeverity) {
|
|
802
|
-
const severityOrder = {
|
|
803
|
-
critical: 0,
|
|
804
|
-
high: 1,
|
|
805
|
-
medium: 2,
|
|
806
|
-
low: 3,
|
|
807
|
-
info: 4,
|
|
808
|
-
};
|
|
809
|
-
const threshold = severityOrder[step.options.failOnSeverity];
|
|
810
|
-
const violations = a11yResult.violations.filter((v) => severityOrder[v.impact] <= threshold);
|
|
811
|
-
if (violations.length > 0) {
|
|
812
|
-
throw new AssertionError(`Accessibility violations found: ${violations.length} violations at or above ${step.options.failOnSeverity} severity`, step.id, 0, violations.length);
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
// Check max violations threshold
|
|
816
|
-
if (step.options?.maxViolations !== undefined &&
|
|
817
|
-
a11yResult.violations.length > step.options.maxViolations) {
|
|
818
|
-
throw new AssertionError(`Too many accessibility violations: ${a11yResult.violations.length} (max: ${step.options.maxViolations})`, step.id, step.options.maxViolations, a11yResult.violations.length);
|
|
819
|
-
}
|
|
820
|
-
return {
|
|
821
|
-
accessibilityResult: a11yResult,
|
|
822
|
-
};
|
|
823
|
-
}
|
|
824
|
-
// ==========================================================================
|
|
825
|
-
// Wait Condition Handlers
|
|
826
|
-
// ==========================================================================
|
|
827
|
-
/**
|
|
828
|
-
* Wait for a condition to be met
|
|
829
|
-
*/
|
|
830
|
-
async waitForCondition(condition, client, step, timeout, pollingInterval) {
|
|
831
|
-
const startTime = Date.now();
|
|
832
|
-
while (Date.now() - startTime < timeout) {
|
|
833
|
-
let conditionMet = false;
|
|
834
|
-
let data = {};
|
|
835
|
-
try {
|
|
836
|
-
switch (condition) {
|
|
837
|
-
case 'element-visible':
|
|
838
|
-
conditionMet = await this.checkElementVisible(client, step.target);
|
|
839
|
-
break;
|
|
840
|
-
case 'element-hidden':
|
|
841
|
-
conditionMet = !(await this.checkElementVisible(client, step.target));
|
|
842
|
-
break;
|
|
843
|
-
case 'element-enabled':
|
|
844
|
-
conditionMet = await this.checkElementEnabled(client, step.target);
|
|
845
|
-
break;
|
|
846
|
-
case 'element-disabled':
|
|
847
|
-
conditionMet = !(await this.checkElementEnabled(client, step.target));
|
|
848
|
-
break;
|
|
849
|
-
case 'element-text': {
|
|
850
|
-
const textResult = await this.checkElementText(client, step.target, step.options.expectedText, step.options.textMatchMode ?? 'contains');
|
|
851
|
-
conditionMet = textResult.matches;
|
|
852
|
-
data.elementText = textResult.actualText;
|
|
853
|
-
break;
|
|
854
|
-
}
|
|
855
|
-
case 'element-attribute': {
|
|
856
|
-
const attrResult = await this.checkElementAttribute(client, step.target, step.options.attributeName, step.options.attributeValue);
|
|
857
|
-
conditionMet = attrResult.matches;
|
|
858
|
-
data.attributeValue = attrResult.actualValue;
|
|
859
|
-
break;
|
|
860
|
-
}
|
|
861
|
-
case 'url-match': {
|
|
862
|
-
const pageInfo = await client.getPageInfo();
|
|
863
|
-
if (pageInfo.success) {
|
|
864
|
-
const pattern = step.options.urlPattern;
|
|
865
|
-
conditionMet =
|
|
866
|
-
typeof pattern === 'string'
|
|
867
|
-
? pageInfo.value.url.includes(pattern)
|
|
868
|
-
: new RegExp(pattern).test(pageInfo.value.url);
|
|
869
|
-
data.url = pageInfo.value.url;
|
|
870
|
-
}
|
|
871
|
-
break;
|
|
872
|
-
}
|
|
873
|
-
case 'network-idle':
|
|
874
|
-
case 'dom-loaded':
|
|
875
|
-
case 'page-loaded': {
|
|
876
|
-
const pageInfo = await client.getPageInfo();
|
|
877
|
-
if (pageInfo.success) {
|
|
878
|
-
const loadStateMap = {
|
|
879
|
-
'network-idle': ['networkidle'],
|
|
880
|
-
'dom-loaded': ['domcontentloaded', 'networkidle', 'loaded'],
|
|
881
|
-
'page-loaded': ['loaded', 'networkidle'],
|
|
882
|
-
};
|
|
883
|
-
conditionMet = loadStateMap[condition].includes(pageInfo.value.loadState);
|
|
884
|
-
}
|
|
885
|
-
break;
|
|
886
|
-
}
|
|
887
|
-
case 'custom':
|
|
888
|
-
// Custom conditions require external evaluation - always pass for now
|
|
889
|
-
conditionMet = true;
|
|
890
|
-
break;
|
|
891
|
-
}
|
|
892
|
-
// Handle negation
|
|
893
|
-
if (step.options.negate) {
|
|
894
|
-
conditionMet = !conditionMet;
|
|
895
|
-
}
|
|
896
|
-
if (conditionMet) {
|
|
897
|
-
return data;
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
catch {
|
|
901
|
-
// Condition check failed, continue polling
|
|
902
|
-
}
|
|
903
|
-
await this.delay(pollingInterval);
|
|
904
|
-
}
|
|
905
|
-
throw new StepTimeoutError(step.id, timeout, new Error(`Wait condition "${condition}" not met`));
|
|
906
|
-
}
|
|
907
|
-
// ==========================================================================
|
|
908
|
-
// Assertion Handlers
|
|
909
|
-
// ==========================================================================
|
|
910
|
-
/**
|
|
911
|
-
* Perform an assertion using the unified browser client (IBrowserClient)
|
|
912
|
-
* Supports agent-browser and generic browser clients
|
|
913
|
-
*/
|
|
914
|
-
async performUnifiedAssertion(assertion, client, step, _context) {
|
|
915
|
-
let actual;
|
|
916
|
-
const expected = step.options.expected ?? step.value;
|
|
917
|
-
switch (assertion) {
|
|
918
|
-
case 'element-exists':
|
|
919
|
-
case 'element-visible':
|
|
920
|
-
case 'visible': { // 'visible' is short form alias
|
|
921
|
-
if (step.target) {
|
|
922
|
-
const result = await client.isVisible(toElementTarget(step.target));
|
|
923
|
-
actual = result.success ? result.value : false;
|
|
924
|
-
}
|
|
925
|
-
else {
|
|
926
|
-
actual = false;
|
|
927
|
-
}
|
|
928
|
-
this.assertCondition(actual === true, step, true, actual);
|
|
929
|
-
break;
|
|
930
|
-
}
|
|
931
|
-
case 'element-not-exists':
|
|
932
|
-
case 'element-hidden':
|
|
933
|
-
case 'hidden': { // 'hidden' is short form alias
|
|
934
|
-
if (step.target) {
|
|
935
|
-
const result = await client.isVisible(toElementTarget(step.target));
|
|
936
|
-
actual = result.success ? !result.value : true;
|
|
937
|
-
}
|
|
938
|
-
else {
|
|
939
|
-
actual = true;
|
|
940
|
-
}
|
|
941
|
-
this.assertCondition(actual === true, step, true, actual);
|
|
942
|
-
break;
|
|
943
|
-
}
|
|
944
|
-
case 'element-text':
|
|
945
|
-
case 'text': { // 'text' is short form alias
|
|
946
|
-
if (step.target) {
|
|
947
|
-
const result = await client.getText(toElementTarget(step.target));
|
|
948
|
-
if (!result.success) {
|
|
949
|
-
throw result.error;
|
|
950
|
-
}
|
|
951
|
-
actual = result.value;
|
|
952
|
-
this.assertTextMatch(actual, expected, step.options.operator, step);
|
|
953
|
-
}
|
|
954
|
-
break;
|
|
955
|
-
}
|
|
956
|
-
case 'url-equals':
|
|
957
|
-
case 'url-contains':
|
|
958
|
-
case 'url-matches': {
|
|
959
|
-
// Get current URL via evaluate
|
|
960
|
-
const urlResult = await client.evaluate('window.location.href');
|
|
961
|
-
if (!urlResult.success) {
|
|
962
|
-
throw urlResult.error;
|
|
963
|
-
}
|
|
964
|
-
actual = urlResult.value;
|
|
965
|
-
if (assertion === 'url-equals') {
|
|
966
|
-
this.assertCondition(actual === expected, step, expected, actual);
|
|
967
|
-
}
|
|
968
|
-
else if (assertion === 'url-contains') {
|
|
969
|
-
this.assertCondition(actual.includes(expected), step, expected, actual);
|
|
970
|
-
}
|
|
971
|
-
else {
|
|
972
|
-
const regex = new RegExp(expected);
|
|
973
|
-
this.assertCondition(regex.test(actual), step, expected, actual);
|
|
974
|
-
}
|
|
975
|
-
break;
|
|
976
|
-
}
|
|
977
|
-
case 'title-equals':
|
|
978
|
-
case 'title-contains': {
|
|
979
|
-
const titleResult = await client.evaluate('document.title');
|
|
980
|
-
if (!titleResult.success) {
|
|
981
|
-
throw titleResult.error;
|
|
982
|
-
}
|
|
983
|
-
actual = titleResult.value;
|
|
984
|
-
if (assertion === 'title-equals') {
|
|
985
|
-
this.assertCondition(actual === expected, step, expected, actual);
|
|
986
|
-
}
|
|
987
|
-
else {
|
|
988
|
-
this.assertCondition(actual.includes(expected), step, expected, actual);
|
|
989
|
-
}
|
|
990
|
-
break;
|
|
991
|
-
}
|
|
992
|
-
case 'page-has-text': {
|
|
993
|
-
// Search for text on page
|
|
994
|
-
const textResult = await client.evaluate(`document.body.innerText.includes('${expected}')`);
|
|
995
|
-
actual = textResult.success ? textResult.value : false;
|
|
996
|
-
this.assertCondition(actual === true, step, true, actual);
|
|
997
|
-
break;
|
|
998
|
-
}
|
|
999
|
-
case 'element-attribute': {
|
|
1000
|
-
if (step.target && step.options.attributeName) {
|
|
1001
|
-
const attrResult = await client.evaluate(`document.querySelector('${step.target}')?.getAttribute('${step.options.attributeName}')`);
|
|
1002
|
-
if (attrResult.success) {
|
|
1003
|
-
actual = attrResult.value;
|
|
1004
|
-
this.assertCondition(actual === expected, step, expected, actual);
|
|
1005
|
-
}
|
|
1006
|
-
else {
|
|
1007
|
-
throw attrResult.error;
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
break;
|
|
1011
|
-
}
|
|
1012
|
-
case 'element-value': {
|
|
1013
|
-
if (step.target) {
|
|
1014
|
-
const valueResult = await client.evaluate(`document.querySelector('${step.target}')?.value`);
|
|
1015
|
-
if (valueResult.success) {
|
|
1016
|
-
actual = valueResult.value;
|
|
1017
|
-
this.assertCondition(actual === expected, step, expected, actual);
|
|
1018
|
-
}
|
|
1019
|
-
else {
|
|
1020
|
-
throw valueResult.error;
|
|
1021
|
-
}
|
|
1022
|
-
}
|
|
1023
|
-
break;
|
|
1024
|
-
}
|
|
1025
|
-
case 'element-count': {
|
|
1026
|
-
if (step.target) {
|
|
1027
|
-
const countResult = await client.evaluate(`document.querySelectorAll('${step.target}').length`);
|
|
1028
|
-
if (countResult.success) {
|
|
1029
|
-
actual = countResult.value;
|
|
1030
|
-
const expectedCount = step.options.count ?? expected;
|
|
1031
|
-
this.assertNumericCondition(actual, expectedCount, step.options.operator ?? 'eq', step);
|
|
1032
|
-
}
|
|
1033
|
-
else {
|
|
1034
|
-
throw countResult.error;
|
|
1035
|
-
}
|
|
1036
|
-
}
|
|
1037
|
-
break;
|
|
1038
|
-
}
|
|
1039
|
-
case 'element-class': {
|
|
1040
|
-
if (step.target && step.options.className) {
|
|
1041
|
-
const classResult = await client.evaluate(`document.querySelector('${step.target}')?.classList.contains('${step.options.className}')`);
|
|
1042
|
-
actual = classResult.success ? classResult.value : false;
|
|
1043
|
-
this.assertCondition(actual === true, step, true, actual);
|
|
1044
|
-
}
|
|
1045
|
-
break;
|
|
1046
|
-
}
|
|
1047
|
-
case 'element-enabled':
|
|
1048
|
-
case 'element-disabled': {
|
|
1049
|
-
if (step.target) {
|
|
1050
|
-
const enabledResult = await client.evaluate(`!document.querySelector('${step.target}')?.disabled`);
|
|
1051
|
-
actual = enabledResult.success ? enabledResult.value : false;
|
|
1052
|
-
if (assertion === 'element-disabled') {
|
|
1053
|
-
actual = !actual;
|
|
1054
|
-
}
|
|
1055
|
-
this.assertCondition(actual === true, step, true, actual);
|
|
1056
|
-
}
|
|
1057
|
-
break;
|
|
1058
|
-
}
|
|
1059
|
-
case 'console-no-errors':
|
|
1060
|
-
// This would require console log monitoring - mark as passed for now
|
|
1061
|
-
actual = true;
|
|
1062
|
-
break;
|
|
1063
|
-
case 'custom':
|
|
1064
|
-
// Custom assertions require external evaluation - always pass for now
|
|
1065
|
-
actual = true;
|
|
1066
|
-
break;
|
|
1067
|
-
default:
|
|
1068
|
-
throw new E2ERunnerError(`Unsupported assertion type: ${assertion}`, 'UNSUPPORTED_ASSERTION', step.id);
|
|
1069
|
-
}
|
|
1070
|
-
return { actual, expected };
|
|
1071
|
-
}
|
|
1072
|
-
/**
|
|
1073
|
-
* Perform an assertion (Legacy Vibium path)
|
|
1074
|
-
*/
|
|
1075
|
-
async performAssertion(assertion, client, step) {
|
|
1076
|
-
let actual;
|
|
1077
|
-
const expected = step.options.expected ?? step.value;
|
|
1078
|
-
switch (assertion) {
|
|
1079
|
-
case 'element-exists': {
|
|
1080
|
-
const result = await client.findElement({ selector: step.target });
|
|
1081
|
-
actual = result.success;
|
|
1082
|
-
this.assertCondition(actual === true, step, expected, actual);
|
|
1083
|
-
break;
|
|
1084
|
-
}
|
|
1085
|
-
case 'element-not-exists': {
|
|
1086
|
-
const result = await client.findElement({ selector: step.target });
|
|
1087
|
-
actual = !result.success;
|
|
1088
|
-
this.assertCondition(actual === true, step, true, actual);
|
|
1089
|
-
break;
|
|
1090
|
-
}
|
|
1091
|
-
case 'element-visible': {
|
|
1092
|
-
actual = await this.checkElementVisible(client, step.target);
|
|
1093
|
-
this.assertCondition(actual === true, step, true, actual);
|
|
1094
|
-
break;
|
|
1095
|
-
}
|
|
1096
|
-
case 'element-hidden': {
|
|
1097
|
-
actual = !(await this.checkElementVisible(client, step.target));
|
|
1098
|
-
this.assertCondition(actual === true, step, true, actual);
|
|
1099
|
-
break;
|
|
1100
|
-
}
|
|
1101
|
-
case 'element-enabled': {
|
|
1102
|
-
actual = await this.checkElementEnabled(client, step.target);
|
|
1103
|
-
this.assertCondition(actual === true, step, true, actual);
|
|
1104
|
-
break;
|
|
1105
|
-
}
|
|
1106
|
-
case 'element-disabled': {
|
|
1107
|
-
actual = !(await this.checkElementEnabled(client, step.target));
|
|
1108
|
-
this.assertCondition(actual === true, step, true, actual);
|
|
1109
|
-
break;
|
|
1110
|
-
}
|
|
1111
|
-
case 'element-text': {
|
|
1112
|
-
const textResult = await client.getText(step.target);
|
|
1113
|
-
if (!textResult.success) {
|
|
1114
|
-
throw textResult.error;
|
|
1115
|
-
}
|
|
1116
|
-
actual = textResult.value;
|
|
1117
|
-
this.assertTextMatch(actual, expected, step.options.operator, step);
|
|
1118
|
-
break;
|
|
1119
|
-
}
|
|
1120
|
-
case 'element-attribute': {
|
|
1121
|
-
const attrResult = await client.getAttribute(step.target, step.options.attributeName);
|
|
1122
|
-
if (!attrResult.success) {
|
|
1123
|
-
throw attrResult.error;
|
|
1124
|
-
}
|
|
1125
|
-
actual = attrResult.value;
|
|
1126
|
-
this.assertCondition(actual === expected, step, expected, actual);
|
|
1127
|
-
break;
|
|
1128
|
-
}
|
|
1129
|
-
case 'element-value': {
|
|
1130
|
-
const attrResult = await client.getAttribute(step.target, 'value');
|
|
1131
|
-
if (!attrResult.success) {
|
|
1132
|
-
throw attrResult.error;
|
|
1133
|
-
}
|
|
1134
|
-
actual = attrResult.value;
|
|
1135
|
-
this.assertCondition(actual === expected, step, expected, actual);
|
|
1136
|
-
break;
|
|
1137
|
-
}
|
|
1138
|
-
case 'element-count': {
|
|
1139
|
-
const elementsResult = await client.findElements({ selector: step.target });
|
|
1140
|
-
if (!elementsResult.success) {
|
|
1141
|
-
throw elementsResult.error;
|
|
1142
|
-
}
|
|
1143
|
-
actual = elementsResult.value.length;
|
|
1144
|
-
const expectedCount = step.options.count ?? expected;
|
|
1145
|
-
this.assertNumericCondition(actual, expectedCount, step.options.operator ?? 'eq', step);
|
|
1146
|
-
break;
|
|
1147
|
-
}
|
|
1148
|
-
case 'element-class': {
|
|
1149
|
-
const classResult = await client.getAttribute(step.target, 'class');
|
|
1150
|
-
if (!classResult.success) {
|
|
1151
|
-
throw classResult.error;
|
|
1152
|
-
}
|
|
1153
|
-
const classes = (classResult.value || '').split(/\s+/);
|
|
1154
|
-
actual = classes.includes(step.options.className);
|
|
1155
|
-
this.assertCondition(actual === true, step, true, actual);
|
|
1156
|
-
break;
|
|
1157
|
-
}
|
|
1158
|
-
case 'url-equals':
|
|
1159
|
-
case 'url-contains':
|
|
1160
|
-
case 'url-matches': {
|
|
1161
|
-
const pageInfo = await client.getPageInfo();
|
|
1162
|
-
if (!pageInfo.success) {
|
|
1163
|
-
throw pageInfo.error;
|
|
1164
|
-
}
|
|
1165
|
-
actual = pageInfo.value.url;
|
|
1166
|
-
if (assertion === 'url-equals') {
|
|
1167
|
-
this.assertCondition(actual === expected, step, expected, actual);
|
|
1168
|
-
}
|
|
1169
|
-
else if (assertion === 'url-contains') {
|
|
1170
|
-
this.assertCondition(actual.includes(expected), step, expected, actual);
|
|
1171
|
-
}
|
|
1172
|
-
else {
|
|
1173
|
-
const regex = new RegExp(expected);
|
|
1174
|
-
this.assertCondition(regex.test(actual), step, expected, actual);
|
|
1175
|
-
}
|
|
1176
|
-
break;
|
|
1177
|
-
}
|
|
1178
|
-
case 'title-equals':
|
|
1179
|
-
case 'title-contains': {
|
|
1180
|
-
const pageInfo = await client.getPageInfo();
|
|
1181
|
-
if (!pageInfo.success) {
|
|
1182
|
-
throw pageInfo.error;
|
|
1183
|
-
}
|
|
1184
|
-
actual = pageInfo.value.title;
|
|
1185
|
-
if (assertion === 'title-equals') {
|
|
1186
|
-
this.assertCondition(actual === expected, step, expected, actual);
|
|
1187
|
-
}
|
|
1188
|
-
else {
|
|
1189
|
-
this.assertCondition(actual.includes(expected), step, expected, actual);
|
|
1190
|
-
}
|
|
1191
|
-
break;
|
|
1192
|
-
}
|
|
1193
|
-
case 'page-has-text': {
|
|
1194
|
-
// This would require getting page text content
|
|
1195
|
-
// For now, we'll check if text exists using findElements
|
|
1196
|
-
const selector = `//*[contains(text(),'${expected}')]`;
|
|
1197
|
-
const result = await client.findElements({ selector, selectorType: 'xpath' });
|
|
1198
|
-
actual = result.success && result.value.length > 0;
|
|
1199
|
-
this.assertCondition(actual === true, step, true, actual);
|
|
1200
|
-
break;
|
|
1201
|
-
}
|
|
1202
|
-
case 'console-no-errors':
|
|
1203
|
-
// This would require console log monitoring - mark as passed for now
|
|
1204
|
-
actual = true;
|
|
1205
|
-
break;
|
|
1206
|
-
case 'custom':
|
|
1207
|
-
// Custom assertions require external evaluation - always pass for now
|
|
1208
|
-
actual = true;
|
|
1209
|
-
break;
|
|
1210
|
-
default:
|
|
1211
|
-
throw new E2ERunnerError(`Unsupported assertion type: ${assertion}`, 'UNSUPPORTED_ASSERTION', step.id);
|
|
1212
|
-
}
|
|
1213
|
-
return { actual, expected };
|
|
1214
|
-
}
|
|
1215
|
-
// ==========================================================================
|
|
1216
|
-
// Helper Methods
|
|
1217
|
-
// ==========================================================================
|
|
1218
|
-
/**
|
|
1219
|
-
* Execute a step with retry logic
|
|
1220
|
-
*/
|
|
1221
|
-
async executeStepWithRetry(step, context) {
|
|
1222
|
-
const maxAttempts = (step.retries ?? this.config.defaultRetries) + 1;
|
|
1223
|
-
const timeout = step.timeout ?? this.config.defaultStepTimeout;
|
|
1224
|
-
let lastError;
|
|
1225
|
-
let totalDurationMs = 0;
|
|
1226
|
-
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
1227
|
-
const startedAt = new Date();
|
|
1228
|
-
try {
|
|
1229
|
-
// Execute with timeout
|
|
1230
|
-
const result = await this.withTimeout(this.executeStep(step, context), timeout, step.id);
|
|
1231
|
-
const completedAt = new Date();
|
|
1232
|
-
const durationMs = completedAt.getTime() - startedAt.getTime();
|
|
1233
|
-
totalDurationMs += durationMs;
|
|
1234
|
-
return {
|
|
1235
|
-
stepId: step.id,
|
|
1236
|
-
stepType: step.type,
|
|
1237
|
-
success: true,
|
|
1238
|
-
durationMs,
|
|
1239
|
-
data: result.data,
|
|
1240
|
-
screenshot: result.screenshot,
|
|
1241
|
-
accessibilityResult: result.accessibilityResult,
|
|
1242
|
-
startedAt,
|
|
1243
|
-
completedAt,
|
|
1244
|
-
retryInfo: attempt > 1
|
|
1245
|
-
? {
|
|
1246
|
-
attempts: attempt,
|
|
1247
|
-
totalDurationMs,
|
|
1248
|
-
}
|
|
1249
|
-
: undefined,
|
|
1250
|
-
};
|
|
1251
|
-
}
|
|
1252
|
-
catch (error) {
|
|
1253
|
-
lastError = error instanceof Error ? error : new Error(String(error));
|
|
1254
|
-
totalDurationMs += Date.now() - startedAt.getTime();
|
|
1255
|
-
if (attempt < maxAttempts) {
|
|
1256
|
-
this.log(`Step "${step.id}" failed (attempt ${attempt}/${maxAttempts}), retrying...`);
|
|
1257
|
-
await this.delay(this.config.retryDelay);
|
|
1258
|
-
}
|
|
1259
|
-
}
|
|
1260
|
-
}
|
|
1261
|
-
// All retries exhausted
|
|
1262
|
-
const completedAt = new Date();
|
|
1263
|
-
return {
|
|
1264
|
-
stepId: step.id,
|
|
1265
|
-
stepType: step.type,
|
|
1266
|
-
success: false,
|
|
1267
|
-
durationMs: totalDurationMs,
|
|
1268
|
-
error: {
|
|
1269
|
-
message: lastError?.message ?? 'Unknown error',
|
|
1270
|
-
code: lastError instanceof E2ERunnerError ? lastError.code : 'UNKNOWN',
|
|
1271
|
-
stack: lastError?.stack,
|
|
1272
|
-
},
|
|
1273
|
-
startedAt: new Date(completedAt.getTime() - totalDurationMs),
|
|
1274
|
-
completedAt,
|
|
1275
|
-
retryInfo: {
|
|
1276
|
-
attempts: maxAttempts,
|
|
1277
|
-
totalDurationMs,
|
|
1278
|
-
},
|
|
1279
|
-
};
|
|
1280
|
-
}
|
|
1281
|
-
/**
|
|
1282
|
-
* Execute a single step based on its type
|
|
1283
|
-
*/
|
|
1284
|
-
async executeStep(step, context) {
|
|
1285
|
-
// Check conditional execution
|
|
1286
|
-
if (step.condition) {
|
|
1287
|
-
const shouldExecute = this.evaluateCondition(step.condition, context);
|
|
1288
|
-
if (!shouldExecute) {
|
|
1289
|
-
return { data: {} };
|
|
1290
|
-
}
|
|
1291
|
-
}
|
|
1292
|
-
// Use the unified client for step execution
|
|
1293
|
-
const client = this.unifiedClient;
|
|
1294
|
-
if (isNavigateStep(step)) {
|
|
1295
|
-
return this.executeNavigateStep(step, client, context);
|
|
1296
|
-
}
|
|
1297
|
-
else if (isClickStep(step)) {
|
|
1298
|
-
return this.executeClickStep(step, client, context);
|
|
1299
|
-
}
|
|
1300
|
-
else if (isTypeStep(step)) {
|
|
1301
|
-
return this.executeTypeStep(step, client, context);
|
|
1302
|
-
}
|
|
1303
|
-
else if (isWaitStep(step)) {
|
|
1304
|
-
return this.executeWaitStep(step, client, context);
|
|
1305
|
-
}
|
|
1306
|
-
else if (isAssertStep(step)) {
|
|
1307
|
-
return this.executeAssertStep(step, client, context);
|
|
1308
|
-
}
|
|
1309
|
-
else if (isScreenshotStep(step)) {
|
|
1310
|
-
return this.executeScreenshotStep(step, client, context);
|
|
1311
|
-
}
|
|
1312
|
-
else if (isA11yCheckStep(step)) {
|
|
1313
|
-
return this.executeA11yCheckStep(step, client, context);
|
|
1314
|
-
}
|
|
1315
|
-
// This should never be reached if all step types are handled
|
|
1316
|
-
const unknownStep = step;
|
|
1317
|
-
throw new E2ERunnerError(`Unknown step type: ${unknownStep.type}`, 'UNKNOWN_STEP_TYPE', unknownStep.id);
|
|
1318
|
-
}
|
|
1319
|
-
/**
|
|
1320
|
-
* Execute hook steps
|
|
1321
|
-
*/
|
|
1322
|
-
async executeHooks(hooks, context, hookType) {
|
|
1323
|
-
const results = [];
|
|
1324
|
-
for (const hook of hooks) {
|
|
1325
|
-
this.log(`Executing ${hookType} hook: ${hook.id}`);
|
|
1326
|
-
const result = await this.executeStepWithRetry(hook, context);
|
|
1327
|
-
results.push(result);
|
|
1328
|
-
if (!result.success && hook.required) {
|
|
1329
|
-
this.log(`${hookType} hook "${hook.id}" failed`);
|
|
1330
|
-
break;
|
|
1331
|
-
}
|
|
1332
|
-
}
|
|
1333
|
-
return results;
|
|
1334
|
-
}
|
|
1335
|
-
/**
|
|
1336
|
-
* Execute tests in parallel with limited concurrency
|
|
1337
|
-
*/
|
|
1338
|
-
async executeInParallel(testCases, maxWorkers) {
|
|
1339
|
-
const workers = maxWorkers ?? this.config.maxParallelWorkers;
|
|
1340
|
-
const results = [];
|
|
1341
|
-
const queue = [...testCases];
|
|
1342
|
-
const executeNext = async () => {
|
|
1343
|
-
while (queue.length > 0) {
|
|
1344
|
-
const testCase = queue.shift();
|
|
1345
|
-
if (testCase) {
|
|
1346
|
-
const result = await this.runTestCase(testCase);
|
|
1347
|
-
results.push(result);
|
|
1348
|
-
}
|
|
1349
|
-
}
|
|
1350
|
-
};
|
|
1351
|
-
// Start workers
|
|
1352
|
-
const workerPromises = [];
|
|
1353
|
-
for (let i = 0; i < Math.min(workers, testCases.length); i++) {
|
|
1354
|
-
workerPromises.push(executeNext());
|
|
1355
|
-
}
|
|
1356
|
-
await Promise.all(workerPromises);
|
|
1357
|
-
return results;
|
|
1358
|
-
}
|
|
1359
|
-
/**
|
|
1360
|
-
* Check if element is visible
|
|
1361
|
-
*/
|
|
1362
|
-
async checkElementVisible(client, selector) {
|
|
1363
|
-
const result = await client.findElement({
|
|
1364
|
-
selector,
|
|
1365
|
-
visible: true,
|
|
1366
|
-
timeout: 1000,
|
|
1367
|
-
});
|
|
1368
|
-
return result.success && result.value.visible;
|
|
1369
|
-
}
|
|
1370
|
-
/**
|
|
1371
|
-
* Check if element is enabled
|
|
1372
|
-
*/
|
|
1373
|
-
async checkElementEnabled(client, selector) {
|
|
1374
|
-
const result = await client.findElement({ selector, timeout: 1000 });
|
|
1375
|
-
return result.success && result.value.enabled;
|
|
1376
|
-
}
|
|
1377
|
-
/**
|
|
1378
|
-
* Check element text against expected value
|
|
1379
|
-
*/
|
|
1380
|
-
async checkElementText(client, selector, expectedText, matchMode) {
|
|
1381
|
-
const result = await client.getText(selector);
|
|
1382
|
-
if (!result.success) {
|
|
1383
|
-
return { matches: false, actualText: '' };
|
|
1384
|
-
}
|
|
1385
|
-
const actualText = result.value;
|
|
1386
|
-
let matches = false;
|
|
1387
|
-
switch (matchMode) {
|
|
1388
|
-
case 'exact':
|
|
1389
|
-
matches = actualText === expectedText;
|
|
1390
|
-
break;
|
|
1391
|
-
case 'contains':
|
|
1392
|
-
matches = actualText.includes(expectedText);
|
|
1393
|
-
break;
|
|
1394
|
-
case 'regex':
|
|
1395
|
-
matches = new RegExp(expectedText).test(actualText);
|
|
1396
|
-
break;
|
|
1397
|
-
}
|
|
1398
|
-
return { matches, actualText };
|
|
1399
|
-
}
|
|
1400
|
-
/**
|
|
1401
|
-
* Check element attribute against expected value
|
|
1402
|
-
*/
|
|
1403
|
-
async checkElementAttribute(client, selector, attributeName, expectedValue) {
|
|
1404
|
-
const result = await client.getAttribute(selector, attributeName);
|
|
1405
|
-
if (!result.success) {
|
|
1406
|
-
return { matches: false, actualValue: '' };
|
|
1407
|
-
}
|
|
1408
|
-
return {
|
|
1409
|
-
matches: result.value === expectedValue,
|
|
1410
|
-
actualValue: result.value,
|
|
1411
|
-
};
|
|
1412
|
-
}
|
|
1413
|
-
/**
|
|
1414
|
-
* Scroll element into view
|
|
1415
|
-
*/
|
|
1416
|
-
async scrollIntoView(client, selector) {
|
|
1417
|
-
// Use findElement which may auto-scroll
|
|
1418
|
-
await client.findElement({ selector, visible: true });
|
|
1419
|
-
}
|
|
1420
|
-
/**
|
|
1421
|
-
* Assert a condition is true
|
|
1422
|
-
*/
|
|
1423
|
-
assertCondition(condition, step, expected, actual) {
|
|
1424
|
-
if (!condition) {
|
|
1425
|
-
const message = step.options.errorMessage ??
|
|
1426
|
-
`Assertion failed: expected ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}`;
|
|
1427
|
-
if (step.options.soft) {
|
|
1428
|
-
this.log(`Soft assertion failed: ${message}`);
|
|
1429
|
-
}
|
|
1430
|
-
else {
|
|
1431
|
-
throw new AssertionError(message, step.id, expected, actual);
|
|
1432
|
-
}
|
|
1433
|
-
}
|
|
1434
|
-
}
|
|
1435
|
-
/**
|
|
1436
|
-
* Assert text matches using specified operator
|
|
1437
|
-
*/
|
|
1438
|
-
assertTextMatch(actual, expected, operator, step) {
|
|
1439
|
-
let matches = false;
|
|
1440
|
-
switch (operator) {
|
|
1441
|
-
case 'eq':
|
|
1442
|
-
case undefined:
|
|
1443
|
-
matches = actual === expected;
|
|
1444
|
-
break;
|
|
1445
|
-
case 'neq':
|
|
1446
|
-
matches = actual !== expected;
|
|
1447
|
-
break;
|
|
1448
|
-
case 'contains':
|
|
1449
|
-
matches = actual.includes(expected);
|
|
1450
|
-
break;
|
|
1451
|
-
case 'matches':
|
|
1452
|
-
matches = new RegExp(expected).test(actual);
|
|
1453
|
-
break;
|
|
1454
|
-
default:
|
|
1455
|
-
matches = actual === expected;
|
|
1456
|
-
}
|
|
1457
|
-
this.assertCondition(matches, step, expected, actual);
|
|
1458
|
-
}
|
|
1459
|
-
/**
|
|
1460
|
-
* Assert numeric condition
|
|
1461
|
-
*/
|
|
1462
|
-
assertNumericCondition(actual, expected, operator, step) {
|
|
1463
|
-
let matches = false;
|
|
1464
|
-
switch (operator) {
|
|
1465
|
-
case 'eq':
|
|
1466
|
-
matches = actual === expected;
|
|
1467
|
-
break;
|
|
1468
|
-
case 'neq':
|
|
1469
|
-
matches = actual !== expected;
|
|
1470
|
-
break;
|
|
1471
|
-
case 'gt':
|
|
1472
|
-
matches = actual > expected;
|
|
1473
|
-
break;
|
|
1474
|
-
case 'gte':
|
|
1475
|
-
matches = actual >= expected;
|
|
1476
|
-
break;
|
|
1477
|
-
case 'lt':
|
|
1478
|
-
matches = actual < expected;
|
|
1479
|
-
break;
|
|
1480
|
-
case 'lte':
|
|
1481
|
-
matches = actual <= expected;
|
|
1482
|
-
break;
|
|
1483
|
-
default:
|
|
1484
|
-
matches = actual === expected;
|
|
1485
|
-
}
|
|
1486
|
-
this.assertCondition(matches, step, expected, actual);
|
|
1487
|
-
}
|
|
1488
|
-
/**
|
|
1489
|
-
* Resolve URL with base URL
|
|
1490
|
-
*/
|
|
1491
|
-
resolveUrl(url, baseUrl) {
|
|
1492
|
-
if (url.startsWith('http://') || url.startsWith('https://')) {
|
|
1493
|
-
return url;
|
|
1494
|
-
}
|
|
1495
|
-
return new URL(url, baseUrl).toString();
|
|
1496
|
-
}
|
|
1497
|
-
/**
|
|
1498
|
-
* Evaluate conditional expression
|
|
1499
|
-
* Uses safe expression evaluator to prevent code injection (CVE fix)
|
|
1500
|
-
*/
|
|
1501
|
-
evaluateCondition(condition, context) {
|
|
1502
|
-
// Build evaluation context from step variables
|
|
1503
|
-
// Note: process.env is excluded for security - only explicit variables allowed
|
|
1504
|
-
const evalContext = {
|
|
1505
|
-
...context.variables,
|
|
1506
|
-
};
|
|
1507
|
-
// Use safe evaluator instead of new Function() - prevents code injection
|
|
1508
|
-
return safeEvaluateBoolean(condition, evalContext, true);
|
|
1509
|
-
}
|
|
1510
|
-
/**
|
|
1511
|
-
* Get browser context options from test case
|
|
1512
|
-
*/
|
|
1513
|
-
getBrowserContextOptions(testCase) {
|
|
1514
|
-
const options = {};
|
|
1515
|
-
if (testCase.browserContext?.userAgent) {
|
|
1516
|
-
options.userAgent = testCase.browserContext.userAgent;
|
|
1517
|
-
}
|
|
1518
|
-
if (testCase.browserContext?.locale) {
|
|
1519
|
-
options.locale = testCase.browserContext.locale;
|
|
1520
|
-
}
|
|
1521
|
-
if (testCase.browserContext?.timezoneId) {
|
|
1522
|
-
options.timezoneId = testCase.browserContext.timezoneId;
|
|
1523
|
-
}
|
|
1524
|
-
return options;
|
|
1525
|
-
}
|
|
1526
|
-
/**
|
|
1527
|
-
* Capture screenshot on failure
|
|
1528
|
-
* Supports both agent-browser and Vibium clients
|
|
1529
|
-
*/
|
|
1530
|
-
async captureFailureScreenshot(stepId) {
|
|
1531
|
-
try {
|
|
1532
|
-
// Use unified browser client if available
|
|
1533
|
-
if (!isVibiumClient(this.unifiedClient)) {
|
|
1534
|
-
const browserClient = this.unifiedClient;
|
|
1535
|
-
const result = await browserClient.screenshot({ fullPage: true });
|
|
1536
|
-
if (result.success) {
|
|
1537
|
-
return toVibiumScreenshotResult(result.value);
|
|
1538
|
-
}
|
|
1539
|
-
return null;
|
|
1540
|
-
}
|
|
1541
|
-
// Legacy Vibium path
|
|
1542
|
-
const result = await this.client.screenshot({
|
|
1543
|
-
fullPage: true,
|
|
1544
|
-
format: 'png',
|
|
1545
|
-
});
|
|
1546
|
-
if (result.success) {
|
|
1547
|
-
return result.value;
|
|
1548
|
-
}
|
|
1549
|
-
}
|
|
1550
|
-
catch {
|
|
1551
|
-
this.log(`Failed to capture failure screenshot for step ${stepId}`);
|
|
1552
|
-
}
|
|
1553
|
-
return null;
|
|
1554
|
-
}
|
|
1555
|
-
/**
|
|
1556
|
-
* Check if any results have failures
|
|
1557
|
-
*/
|
|
1558
|
-
hasFailure(results) {
|
|
1559
|
-
return results.some((r) => !r.success);
|
|
1560
|
-
}
|
|
1561
|
-
/**
|
|
1562
|
-
* Calculate summary statistics
|
|
1563
|
-
*/
|
|
1564
|
-
calculateSummary(results) {
|
|
1565
|
-
return {
|
|
1566
|
-
total: results.length,
|
|
1567
|
-
passed: results.filter((r) => r.status === 'passed').length,
|
|
1568
|
-
failed: results.filter((r) => r.status === 'failed' || r.status === 'error').length,
|
|
1569
|
-
skipped: results.filter((r) => r.status === 'skipped').length,
|
|
1570
|
-
};
|
|
1571
|
-
}
|
|
1572
|
-
/**
|
|
1573
|
-
* Create skipped test result
|
|
1574
|
-
*/
|
|
1575
|
-
createSkippedResult(testCase, startedAt) {
|
|
1576
|
-
return {
|
|
1577
|
-
testCaseId: testCase.id,
|
|
1578
|
-
testCaseName: testCase.name,
|
|
1579
|
-
success: true,
|
|
1580
|
-
status: 'skipped',
|
|
1581
|
-
stepResults: [],
|
|
1582
|
-
totalDurationMs: 0,
|
|
1583
|
-
startedAt,
|
|
1584
|
-
completedAt: new Date(),
|
|
1585
|
-
};
|
|
1586
|
-
}
|
|
1587
|
-
/**
|
|
1588
|
-
* Create error test result
|
|
1589
|
-
*/
|
|
1590
|
-
createErrorResult(testCase, startedAt, errorMessage, stepResults = []) {
|
|
1591
|
-
return {
|
|
1592
|
-
testCaseId: testCase.id,
|
|
1593
|
-
testCaseName: testCase.name,
|
|
1594
|
-
success: false,
|
|
1595
|
-
status: 'error',
|
|
1596
|
-
stepResults,
|
|
1597
|
-
totalDurationMs: Date.now() - startedAt.getTime(),
|
|
1598
|
-
startedAt,
|
|
1599
|
-
completedAt: new Date(),
|
|
1600
|
-
errorSummary: {
|
|
1601
|
-
failedStep: stepResults.length > 0 ? stepResults[stepResults.length - 1].stepId : 'setup',
|
|
1602
|
-
errorMessage,
|
|
1603
|
-
},
|
|
1604
|
-
};
|
|
1605
|
-
}
|
|
1606
|
-
/**
|
|
1607
|
-
* Create test result from step results
|
|
1608
|
-
*/
|
|
1609
|
-
createResult(testCase, startedAt, stepResults, screenshots, accessibilityResults) {
|
|
1610
|
-
const completedAt = new Date();
|
|
1611
|
-
const hasRequiredFailure = stepResults.some((r) => !r.success &&
|
|
1612
|
-
testCase.steps.find((s) => s.id === r.stepId)?.required &&
|
|
1613
|
-
!testCase.steps.find((s) => s.id === r.stepId)?.continueOnFailure);
|
|
1614
|
-
const status = hasRequiredFailure ? 'failed' : 'passed';
|
|
1615
|
-
const failedStep = stepResults.find((r) => !r.success);
|
|
1616
|
-
return {
|
|
1617
|
-
testCaseId: testCase.id,
|
|
1618
|
-
testCaseName: testCase.name,
|
|
1619
|
-
success: status === 'passed',
|
|
1620
|
-
status,
|
|
1621
|
-
stepResults,
|
|
1622
|
-
totalDurationMs: completedAt.getTime() - startedAt.getTime(),
|
|
1623
|
-
screenshots: screenshots.length > 0 ? screenshots : undefined,
|
|
1624
|
-
accessibilityResults: accessibilityResults.length > 0 ? accessibilityResults : undefined,
|
|
1625
|
-
startedAt,
|
|
1626
|
-
completedAt,
|
|
1627
|
-
browserInfo: testCase.viewport
|
|
1628
|
-
? {
|
|
1629
|
-
browserType: 'chromium',
|
|
1630
|
-
viewport: testCase.viewport,
|
|
1631
|
-
userAgent: testCase.browserContext?.userAgent ?? '',
|
|
1632
|
-
}
|
|
1633
|
-
: undefined,
|
|
1634
|
-
errorSummary: failedStep
|
|
1635
|
-
? {
|
|
1636
|
-
failedStep: failedStep.stepId,
|
|
1637
|
-
errorMessage: failedStep.error?.message ?? 'Unknown error',
|
|
1638
|
-
errorCode: failedStep.error?.code,
|
|
1639
|
-
screenshot: failedStep.error?.failureScreenshot,
|
|
1640
|
-
}
|
|
1641
|
-
: undefined,
|
|
1642
|
-
};
|
|
1643
|
-
}
|
|
1644
|
-
/**
|
|
1645
|
-
* Wrap promise with timeout
|
|
1646
|
-
*/
|
|
1647
|
-
async withTimeout(promise, timeout, stepId) {
|
|
1648
|
-
return new Promise((resolve, reject) => {
|
|
1649
|
-
const timer = setTimeout(() => {
|
|
1650
|
-
reject(new StepTimeoutError(stepId, timeout));
|
|
1651
|
-
}, timeout);
|
|
1652
|
-
promise
|
|
1653
|
-
.then((result) => {
|
|
1654
|
-
clearTimeout(timer);
|
|
1655
|
-
resolve(result);
|
|
1656
|
-
})
|
|
1657
|
-
.catch((error) => {
|
|
1658
|
-
clearTimeout(timer);
|
|
1659
|
-
reject(error);
|
|
1660
|
-
});
|
|
1661
|
-
});
|
|
1662
|
-
}
|
|
1663
|
-
/**
|
|
1664
|
-
* Delay execution
|
|
1665
|
-
*/
|
|
1666
|
-
delay(ms) {
|
|
1667
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1668
|
-
}
|
|
1669
|
-
/**
|
|
1670
|
-
* Log message if verbose mode is enabled
|
|
1671
|
-
*/
|
|
1672
|
-
log(message) {
|
|
1673
|
-
if (this.config.verbose) {
|
|
1674
|
-
console.log(`[E2ERunner] ${message}`);
|
|
1675
|
-
}
|
|
1676
|
-
}
|
|
1677
|
-
}
|
|
1678
|
-
// ============================================================================
|
|
1679
|
-
// Factory Functions
|
|
1680
|
-
// ============================================================================
|
|
1681
|
-
/**
|
|
1682
|
-
* Create an E2E Test Runner Service instance with a VibiumClient (legacy)
|
|
1683
|
-
*
|
|
1684
|
-
* @param client - Vibium browser automation client
|
|
1685
|
-
* @param config - Optional runner configuration
|
|
1686
|
-
* @returns E2E Test Runner Service instance
|
|
1687
|
-
*
|
|
1688
|
-
* @example
|
|
1689
|
-
* ```typescript
|
|
1690
|
-
* import { createVibiumClient } from '../../../integrations/vibium';
|
|
1691
|
-
* import { createE2ETestRunnerService } from './e2e-runner';
|
|
1692
|
-
*
|
|
1693
|
-
* const client = await createVibiumClient({ enabled: true });
|
|
1694
|
-
* const runner = createE2ETestRunnerService(client, {
|
|
1695
|
-
* screenshotOnFailure: true,
|
|
1696
|
-
* verbose: true,
|
|
1697
|
-
* });
|
|
1698
|
-
*
|
|
1699
|
-
* const result = await runner.runTestCase(testCase);
|
|
1700
|
-
* ```
|
|
1701
|
-
*/
|
|
1702
|
-
export function createE2ETestRunnerService(client, config) {
|
|
1703
|
-
return new E2ETestRunnerService(client, config);
|
|
1704
|
-
}
|
|
1705
|
-
/**
|
|
1706
|
-
* Create an E2E Test Runner Service instance with a browser client
|
|
1707
|
-
*
|
|
1708
|
-
* This factory supports the unified IBrowserClient interface, including
|
|
1709
|
-
* agent-browser with its enhanced E2E testing capabilities.
|
|
1710
|
-
*
|
|
1711
|
-
* @param client - Browser client (IBrowserClient or IAgentBrowserClient)
|
|
1712
|
-
* @param config - Optional runner configuration
|
|
1713
|
-
* @returns E2E Test Runner Service instance
|
|
1714
|
-
*
|
|
1715
|
-
* @example
|
|
1716
|
-
* ```typescript
|
|
1717
|
-
* import { createAgentBrowserClient } from '../../../integrations/browser';
|
|
1718
|
-
* import { createE2ETestRunnerServiceWithBrowserClient } from './e2e-runner';
|
|
1719
|
-
*
|
|
1720
|
-
* // Using agent-browser (recommended for E2E testing)
|
|
1721
|
-
* const agentClient = await createAgentBrowserClient();
|
|
1722
|
-
* const runner = createE2ETestRunnerServiceWithBrowserClient(agentClient, {
|
|
1723
|
-
* preferAgentBrowser: true,
|
|
1724
|
-
* screenshotOnFailure: true,
|
|
1725
|
-
* });
|
|
1726
|
-
*
|
|
1727
|
-
* // Execute test with snapshot refs
|
|
1728
|
-
* const result = await runner.runTestCase(testCase);
|
|
1729
|
-
* ```
|
|
1730
|
-
*/
|
|
1731
|
-
export function createE2ETestRunnerServiceWithBrowserClient(client, config) {
|
|
1732
|
-
return new E2ETestRunnerService(client, {
|
|
1733
|
-
...config,
|
|
1734
|
-
browserClient: client,
|
|
1735
|
-
});
|
|
1736
|
-
}
|
|
1737
|
-
/**
|
|
1738
|
-
* Create an E2E Test Runner Service with auto-selected browser client
|
|
1739
|
-
*
|
|
1740
|
-
* This factory automatically selects the best available browser client:
|
|
1741
|
-
* - Prefers agent-browser for E2E testing (supports refs, sessions, mocking)
|
|
1742
|
-
* - Falls back to Vibium if agent-browser is unavailable
|
|
1743
|
-
*
|
|
1744
|
-
* @param config - Optional runner configuration
|
|
1745
|
-
* @returns Promise resolving to E2E Test Runner Service instance
|
|
1746
|
-
*
|
|
1747
|
-
* @example
|
|
1748
|
-
* ```typescript
|
|
1749
|
-
* import { createAutoE2ETestRunnerService } from './e2e-runner';
|
|
1750
|
-
*
|
|
1751
|
-
* // Auto-select best browser client for E2E testing
|
|
1752
|
-
* const runner = await createAutoE2ETestRunnerService({
|
|
1753
|
-
* screenshotOnFailure: true,
|
|
1754
|
-
* verbose: true,
|
|
1755
|
-
* });
|
|
1756
|
-
*
|
|
1757
|
-
* const result = await runner.runTestCase(testCase);
|
|
1758
|
-
* ```
|
|
1759
|
-
*/
|
|
1760
|
-
export async function createAutoE2ETestRunnerService(config) {
|
|
1761
|
-
// Get browser client for E2E testing use case
|
|
1762
|
-
const client = await getBrowserClientForUseCase('e2e-testing');
|
|
1763
|
-
return new E2ETestRunnerService(client, {
|
|
1764
|
-
...config,
|
|
1765
|
-
browserClient: client,
|
|
1766
|
-
preferAgentBrowser: true,
|
|
1767
|
-
});
|
|
1768
|
-
}
|
|
29
|
+
// Browser Orchestrator (for testing and extension)
|
|
30
|
+
export { BrowserOrchestrator, createBrowserOrchestrator, isAgentBrowserClient, isVibiumClient, toElementTarget, toVibiumScreenshotResult, toVibiumAccessibilityResult, } from './e2e/browser-orchestrator';
|
|
31
|
+
// Step Executors (for testing and extension)
|
|
32
|
+
export { StepExecutors, createStepExecutors, } from './e2e/step-executors';
|
|
33
|
+
// Step Retry Handler (for testing and extension)
|
|
34
|
+
export { StepRetryHandler, createStepRetryHandler, } from './e2e/step-retry-handler';
|
|
35
|
+
// Result Collector (for testing and extension)
|
|
36
|
+
export { ResultCollector, createResultCollector, } from './e2e/result-collector';
|
|
1769
37
|
//# sourceMappingURL=e2e-runner.js.map
|