tapps-agents 3.5.41__py3-none-any.whl → 3.6.0__py3-none-any.whl
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.
- tapps_agents/__init__.py +2 -2
- tapps_agents/agents/__init__.py +22 -22
- tapps_agents/agents/analyst/__init__.py +5 -5
- tapps_agents/agents/architect/__init__.py +5 -5
- tapps_agents/agents/architect/agent.py +1033 -1033
- tapps_agents/agents/architect/pattern_detector.py +75 -75
- tapps_agents/agents/cleanup/__init__.py +7 -7
- tapps_agents/agents/cleanup/agent.py +445 -445
- tapps_agents/agents/debugger/__init__.py +7 -7
- tapps_agents/agents/debugger/agent.py +310 -310
- tapps_agents/agents/debugger/error_analyzer.py +437 -437
- tapps_agents/agents/designer/__init__.py +5 -5
- tapps_agents/agents/designer/agent.py +786 -786
- tapps_agents/agents/designer/visual_designer.py +638 -638
- tapps_agents/agents/documenter/__init__.py +7 -7
- tapps_agents/agents/documenter/agent.py +531 -531
- tapps_agents/agents/documenter/doc_generator.py +472 -472
- tapps_agents/agents/documenter/doc_validator.py +393 -393
- tapps_agents/agents/documenter/framework_doc_updater.py +493 -493
- tapps_agents/agents/enhancer/__init__.py +7 -7
- tapps_agents/agents/evaluator/__init__.py +7 -7
- tapps_agents/agents/evaluator/agent.py +443 -443
- tapps_agents/agents/evaluator/priority_evaluator.py +641 -641
- tapps_agents/agents/evaluator/quality_analyzer.py +147 -147
- tapps_agents/agents/evaluator/report_generator.py +344 -344
- tapps_agents/agents/evaluator/usage_analyzer.py +192 -192
- tapps_agents/agents/evaluator/workflow_analyzer.py +189 -189
- tapps_agents/agents/implementer/__init__.py +7 -7
- tapps_agents/agents/implementer/agent.py +798 -798
- tapps_agents/agents/implementer/auto_fix.py +1119 -1119
- tapps_agents/agents/implementer/code_generator.py +73 -73
- tapps_agents/agents/improver/__init__.py +1 -1
- tapps_agents/agents/improver/agent.py +753 -753
- tapps_agents/agents/ops/__init__.py +1 -1
- tapps_agents/agents/ops/agent.py +619 -619
- tapps_agents/agents/ops/dependency_analyzer.py +600 -600
- tapps_agents/agents/orchestrator/__init__.py +5 -5
- tapps_agents/agents/orchestrator/agent.py +522 -522
- tapps_agents/agents/planner/__init__.py +7 -7
- tapps_agents/agents/planner/agent.py +1127 -1127
- tapps_agents/agents/reviewer/__init__.py +24 -24
- tapps_agents/agents/reviewer/agent.py +3513 -3513
- tapps_agents/agents/reviewer/aggregator.py +213 -213
- tapps_agents/agents/reviewer/batch_review.py +448 -448
- tapps_agents/agents/reviewer/cache.py +443 -443
- tapps_agents/agents/reviewer/context7_enhancer.py +630 -630
- tapps_agents/agents/reviewer/context_detector.py +203 -203
- tapps_agents/agents/reviewer/docker_compose_validator.py +158 -158
- tapps_agents/agents/reviewer/dockerfile_validator.py +176 -176
- tapps_agents/agents/reviewer/error_handling.py +126 -126
- tapps_agents/agents/reviewer/feedback_generator.py +490 -490
- tapps_agents/agents/reviewer/influxdb_validator.py +316 -316
- tapps_agents/agents/reviewer/issue_tracking.py +169 -169
- tapps_agents/agents/reviewer/library_detector.py +295 -295
- tapps_agents/agents/reviewer/library_patterns.py +268 -268
- tapps_agents/agents/reviewer/maintainability_scorer.py +593 -593
- tapps_agents/agents/reviewer/metric_strategies.py +276 -276
- tapps_agents/agents/reviewer/mqtt_validator.py +160 -160
- tapps_agents/agents/reviewer/output_enhancer.py +105 -105
- tapps_agents/agents/reviewer/pattern_detector.py +241 -241
- tapps_agents/agents/reviewer/performance_scorer.py +357 -357
- tapps_agents/agents/reviewer/phased_review.py +516 -516
- tapps_agents/agents/reviewer/progressive_review.py +435 -435
- tapps_agents/agents/reviewer/react_scorer.py +331 -331
- tapps_agents/agents/reviewer/score_constants.py +228 -228
- tapps_agents/agents/reviewer/score_validator.py +507 -507
- tapps_agents/agents/reviewer/scorer_registry.py +373 -373
- tapps_agents/agents/reviewer/scoring.py +1566 -1566
- tapps_agents/agents/reviewer/service_discovery.py +534 -534
- tapps_agents/agents/reviewer/tools/__init__.py +41 -41
- tapps_agents/agents/reviewer/tools/parallel_executor.py +581 -581
- tapps_agents/agents/reviewer/tools/ruff_grouping.py +250 -250
- tapps_agents/agents/reviewer/tools/scoped_mypy.py +284 -284
- tapps_agents/agents/reviewer/typescript_scorer.py +1142 -1142
- tapps_agents/agents/reviewer/validation.py +208 -208
- tapps_agents/agents/reviewer/websocket_validator.py +132 -132
- tapps_agents/agents/tester/__init__.py +7 -7
- tapps_agents/agents/tester/accessibility_auditor.py +309 -309
- tapps_agents/agents/tester/agent.py +1080 -1080
- tapps_agents/agents/tester/batch_generator.py +54 -54
- tapps_agents/agents/tester/context_learner.py +51 -51
- tapps_agents/agents/tester/coverage_analyzer.py +386 -386
- tapps_agents/agents/tester/coverage_test_generator.py +290 -290
- tapps_agents/agents/tester/debug_enhancer.py +238 -238
- tapps_agents/agents/tester/device_emulator.py +241 -241
- tapps_agents/agents/tester/integration_generator.py +62 -62
- tapps_agents/agents/tester/network_recorder.py +300 -300
- tapps_agents/agents/tester/performance_monitor.py +320 -320
- tapps_agents/agents/tester/test_fixer.py +316 -316
- tapps_agents/agents/tester/test_generator.py +632 -632
- tapps_agents/agents/tester/trace_manager.py +234 -234
- tapps_agents/agents/tester/visual_regression.py +291 -291
- tapps_agents/analysis/pattern_detector.py +36 -36
- tapps_agents/beads/hydration.py +213 -213
- tapps_agents/beads/parse.py +32 -32
- tapps_agents/beads/specs.py +206 -206
- tapps_agents/cli/__init__.py +9 -9
- tapps_agents/cli/__main__.py +8 -8
- tapps_agents/cli/base.py +478 -478
- tapps_agents/cli/command_classifier.py +72 -72
- tapps_agents/cli/commands/__init__.py +2 -2
- tapps_agents/cli/commands/analyst.py +173 -173
- tapps_agents/cli/commands/architect.py +109 -109
- tapps_agents/cli/commands/cleanup_agent.py +92 -92
- tapps_agents/cli/commands/common.py +126 -126
- tapps_agents/cli/commands/debugger.py +90 -90
- tapps_agents/cli/commands/designer.py +112 -112
- tapps_agents/cli/commands/documenter.py +136 -136
- tapps_agents/cli/commands/enhancer.py +110 -110
- tapps_agents/cli/commands/evaluator.py +255 -255
- tapps_agents/cli/commands/health.py +665 -665
- tapps_agents/cli/commands/implementer.py +301 -301
- tapps_agents/cli/commands/improver.py +91 -91
- tapps_agents/cli/commands/knowledge.py +111 -111
- tapps_agents/cli/commands/learning.py +172 -172
- tapps_agents/cli/commands/observability.py +283 -283
- tapps_agents/cli/commands/ops.py +135 -135
- tapps_agents/cli/commands/orchestrator.py +116 -116
- tapps_agents/cli/commands/planner.py +237 -237
- tapps_agents/cli/commands/reviewer.py +1872 -1872
- tapps_agents/cli/commands/status.py +285 -285
- tapps_agents/cli/commands/task.py +227 -227
- tapps_agents/cli/commands/tester.py +191 -191
- tapps_agents/cli/commands/top_level.py +3586 -3586
- tapps_agents/cli/feedback.py +936 -936
- tapps_agents/cli/formatters.py +608 -608
- tapps_agents/cli/help/__init__.py +7 -7
- tapps_agents/cli/help/static_help.py +425 -425
- tapps_agents/cli/network_detection.py +110 -110
- tapps_agents/cli/output_compactor.py +274 -274
- tapps_agents/cli/parsers/__init__.py +2 -2
- tapps_agents/cli/parsers/analyst.py +186 -186
- tapps_agents/cli/parsers/architect.py +167 -167
- tapps_agents/cli/parsers/cleanup_agent.py +228 -228
- tapps_agents/cli/parsers/debugger.py +116 -116
- tapps_agents/cli/parsers/designer.py +182 -182
- tapps_agents/cli/parsers/documenter.py +134 -134
- tapps_agents/cli/parsers/enhancer.py +113 -113
- tapps_agents/cli/parsers/evaluator.py +213 -213
- tapps_agents/cli/parsers/implementer.py +168 -168
- tapps_agents/cli/parsers/improver.py +132 -132
- tapps_agents/cli/parsers/ops.py +159 -159
- tapps_agents/cli/parsers/orchestrator.py +98 -98
- tapps_agents/cli/parsers/planner.py +145 -145
- tapps_agents/cli/parsers/reviewer.py +462 -462
- tapps_agents/cli/parsers/tester.py +124 -124
- tapps_agents/cli/progress_heartbeat.py +254 -254
- tapps_agents/cli/streaming_progress.py +336 -336
- tapps_agents/cli/utils/__init__.py +6 -6
- tapps_agents/cli/utils/agent_lifecycle.py +48 -48
- tapps_agents/cli/utils/error_formatter.py +82 -82
- tapps_agents/cli/utils/error_recovery.py +188 -188
- tapps_agents/cli/utils/output_handler.py +59 -59
- tapps_agents/cli/utils/prompt_enhancer.py +319 -319
- tapps_agents/cli/validators/__init__.py +9 -9
- tapps_agents/cli/validators/command_validator.py +81 -81
- tapps_agents/context7/__init__.py +112 -112
- tapps_agents/context7/agent_integration.py +869 -869
- tapps_agents/context7/analytics.py +382 -382
- tapps_agents/context7/analytics_dashboard.py +299 -299
- tapps_agents/context7/async_cache.py +681 -681
- tapps_agents/context7/backup_client.py +958 -958
- tapps_agents/context7/cache_locking.py +194 -194
- tapps_agents/context7/cache_metadata.py +214 -214
- tapps_agents/context7/cache_prewarm.py +488 -488
- tapps_agents/context7/cache_structure.py +168 -168
- tapps_agents/context7/cache_warming.py +604 -604
- tapps_agents/context7/circuit_breaker.py +376 -376
- tapps_agents/context7/cleanup.py +461 -461
- tapps_agents/context7/commands.py +858 -858
- tapps_agents/context7/credential_validation.py +276 -276
- tapps_agents/context7/cross_reference_resolver.py +168 -168
- tapps_agents/context7/cross_references.py +424 -424
- tapps_agents/context7/doc_manager.py +225 -225
- tapps_agents/context7/fuzzy_matcher.py +369 -369
- tapps_agents/context7/kb_cache.py +404 -404
- tapps_agents/context7/language_detector.py +219 -219
- tapps_agents/context7/library_detector.py +725 -725
- tapps_agents/context7/lookup.py +738 -738
- tapps_agents/context7/metadata.py +258 -258
- tapps_agents/context7/refresh_queue.py +300 -300
- tapps_agents/context7/security.py +373 -373
- tapps_agents/context7/staleness_policies.py +278 -278
- tapps_agents/context7/tiles_integration.py +47 -47
- tapps_agents/continuous_bug_fix/__init__.py +20 -20
- tapps_agents/continuous_bug_fix/bug_finder.py +306 -306
- tapps_agents/continuous_bug_fix/bug_fix_coordinator.py +177 -177
- tapps_agents/continuous_bug_fix/commit_manager.py +178 -178
- tapps_agents/continuous_bug_fix/continuous_bug_fixer.py +322 -322
- tapps_agents/continuous_bug_fix/proactive_bug_finder.py +285 -285
- tapps_agents/core/__init__.py +298 -298
- tapps_agents/core/adaptive_cache_config.py +432 -432
- tapps_agents/core/agent_base.py +647 -647
- tapps_agents/core/agent_cache.py +466 -466
- tapps_agents/core/agent_learning.py +1865 -1865
- tapps_agents/core/analytics_dashboard.py +563 -563
- tapps_agents/core/analytics_enhancements.py +597 -597
- tapps_agents/core/anonymization.py +274 -274
- tapps_agents/core/artifact_context_builder.py +293 -0
- tapps_agents/core/ast_parser.py +228 -228
- tapps_agents/core/async_file_ops.py +402 -402
- tapps_agents/core/best_practice_consultant.py +299 -299
- tapps_agents/core/brownfield_analyzer.py +299 -299
- tapps_agents/core/brownfield_review.py +541 -541
- tapps_agents/core/browser_controller.py +513 -513
- tapps_agents/core/capability_registry.py +418 -418
- tapps_agents/core/change_impact_analyzer.py +190 -190
- tapps_agents/core/checkpoint_manager.py +377 -377
- tapps_agents/core/code_generator.py +329 -329
- tapps_agents/core/code_validator.py +276 -276
- tapps_agents/core/command_registry.py +327 -327
- tapps_agents/core/config.py +33 -0
- tapps_agents/core/context_gathering/__init__.py +2 -2
- tapps_agents/core/context_gathering/repository_explorer.py +28 -28
- tapps_agents/core/context_intelligence/__init__.py +2 -2
- tapps_agents/core/context_intelligence/relevance_scorer.py +24 -24
- tapps_agents/core/context_intelligence/token_budget_manager.py +27 -27
- tapps_agents/core/context_manager.py +240 -240
- tapps_agents/core/cursor_feedback_monitor.py +146 -146
- tapps_agents/core/cursor_verification.py +290 -290
- tapps_agents/core/customization_loader.py +280 -280
- tapps_agents/core/customization_schema.py +260 -260
- tapps_agents/core/customization_template.py +238 -238
- tapps_agents/core/debug_logger.py +124 -124
- tapps_agents/core/design_validator.py +298 -298
- tapps_agents/core/diagram_generator.py +226 -226
- tapps_agents/core/docker_utils.py +232 -232
- tapps_agents/core/document_generator.py +617 -617
- tapps_agents/core/domain_detector.py +30 -30
- tapps_agents/core/error_envelope.py +454 -454
- tapps_agents/core/error_handler.py +270 -270
- tapps_agents/core/estimation_tracker.py +189 -189
- tapps_agents/core/eval_prompt_engine.py +116 -116
- tapps_agents/core/evaluation_base.py +119 -119
- tapps_agents/core/evaluation_models.py +320 -320
- tapps_agents/core/evaluation_orchestrator.py +225 -225
- tapps_agents/core/evaluators/__init__.py +7 -7
- tapps_agents/core/evaluators/architectural_evaluator.py +205 -205
- tapps_agents/core/evaluators/behavioral_evaluator.py +160 -160
- tapps_agents/core/evaluators/performance_profile_evaluator.py +160 -160
- tapps_agents/core/evaluators/security_posture_evaluator.py +148 -148
- tapps_agents/core/evaluators/spec_compliance_evaluator.py +181 -181
- tapps_agents/core/exceptions.py +107 -107
- tapps_agents/core/expert_config_generator.py +293 -293
- tapps_agents/core/export_schema.py +202 -202
- tapps_agents/core/external_feedback_models.py +102 -102
- tapps_agents/core/external_feedback_storage.py +213 -213
- tapps_agents/core/fallback_strategy.py +314 -314
- tapps_agents/core/feedback_analyzer.py +162 -162
- tapps_agents/core/feedback_collector.py +178 -178
- tapps_agents/core/git_operations.py +445 -445
- tapps_agents/core/hardware_profiler.py +151 -151
- tapps_agents/core/instructions.py +324 -324
- tapps_agents/core/io_guardrails.py +69 -69
- tapps_agents/core/issue_manifest.py +249 -249
- tapps_agents/core/issue_schema.py +139 -139
- tapps_agents/core/json_utils.py +128 -128
- tapps_agents/core/knowledge_graph.py +446 -446
- tapps_agents/core/language_detector.py +296 -296
- tapps_agents/core/learning_confidence.py +242 -242
- tapps_agents/core/learning_dashboard.py +246 -246
- tapps_agents/core/learning_decision.py +384 -384
- tapps_agents/core/learning_explainability.py +578 -578
- tapps_agents/core/learning_export.py +287 -287
- tapps_agents/core/learning_integration.py +228 -228
- tapps_agents/core/llm_behavior.py +232 -232
- tapps_agents/core/long_duration_support.py +786 -786
- tapps_agents/core/mcp_setup.py +106 -106
- tapps_agents/core/memory_integration.py +396 -396
- tapps_agents/core/meta_learning.py +666 -666
- tapps_agents/core/module_path_sanitizer.py +199 -199
- tapps_agents/core/multi_agent_orchestrator.py +382 -382
- tapps_agents/core/network_errors.py +125 -125
- tapps_agents/core/nfr_validator.py +336 -336
- tapps_agents/core/offline_mode.py +158 -158
- tapps_agents/core/output_contracts.py +300 -300
- tapps_agents/core/output_formatter.py +300 -300
- tapps_agents/core/path_normalizer.py +174 -174
- tapps_agents/core/path_validator.py +322 -322
- tapps_agents/core/pattern_library.py +250 -250
- tapps_agents/core/performance_benchmark.py +301 -301
- tapps_agents/core/performance_monitor.py +184 -184
- tapps_agents/core/playwright_mcp_controller.py +771 -771
- tapps_agents/core/policy_loader.py +135 -135
- tapps_agents/core/progress.py +166 -166
- tapps_agents/core/project_profile.py +354 -354
- tapps_agents/core/project_type_detector.py +454 -454
- tapps_agents/core/prompt_base.py +223 -223
- tapps_agents/core/prompt_learning/__init__.py +2 -2
- tapps_agents/core/prompt_learning/learning_loop.py +24 -24
- tapps_agents/core/prompt_learning/project_prompt_store.py +25 -25
- tapps_agents/core/prompt_learning/skills_prompt_analyzer.py +35 -35
- tapps_agents/core/prompt_optimization/__init__.py +6 -6
- tapps_agents/core/prompt_optimization/ab_tester.py +114 -114
- tapps_agents/core/prompt_optimization/correlation_analyzer.py +160 -160
- tapps_agents/core/prompt_optimization/progressive_refiner.py +129 -129
- tapps_agents/core/prompt_optimization/prompt_library.py +37 -37
- tapps_agents/core/requirements_evaluator.py +431 -431
- tapps_agents/core/resource_aware_executor.py +449 -449
- tapps_agents/core/resource_monitor.py +343 -343
- tapps_agents/core/resume_handler.py +298 -298
- tapps_agents/core/retry_handler.py +197 -197
- tapps_agents/core/review_checklists.py +479 -479
- tapps_agents/core/role_loader.py +201 -201
- tapps_agents/core/role_template_loader.py +201 -201
- tapps_agents/core/runtime_mode.py +60 -60
- tapps_agents/core/security_scanner.py +342 -342
- tapps_agents/core/skill_agent_registry.py +194 -194
- tapps_agents/core/skill_integration.py +208 -208
- tapps_agents/core/skill_loader.py +492 -492
- tapps_agents/core/skill_template.py +341 -341
- tapps_agents/core/skill_validator.py +478 -478
- tapps_agents/core/stack_analyzer.py +35 -35
- tapps_agents/core/startup.py +174 -174
- tapps_agents/core/storage_manager.py +397 -397
- tapps_agents/core/storage_models.py +166 -166
- tapps_agents/core/story_evaluator.py +410 -410
- tapps_agents/core/subprocess_utils.py +170 -170
- tapps_agents/core/task_duration.py +296 -296
- tapps_agents/core/task_memory.py +582 -582
- tapps_agents/core/task_state.py +226 -226
- tapps_agents/core/tech_stack_priorities.py +208 -208
- tapps_agents/core/temp_directory.py +194 -194
- tapps_agents/core/template_merger.py +600 -600
- tapps_agents/core/template_selector.py +280 -280
- tapps_agents/core/test_generator.py +286 -286
- tapps_agents/core/tiered_context.py +253 -253
- tapps_agents/core/token_monitor.py +345 -345
- tapps_agents/core/traceability.py +254 -254
- tapps_agents/core/trajectory_tracker.py +50 -50
- tapps_agents/core/unicode_safe.py +143 -143
- tapps_agents/core/unified_cache_config.py +170 -170
- tapps_agents/core/unified_state.py +324 -324
- tapps_agents/core/validate_cursor_setup.py +237 -237
- tapps_agents/core/validation_registry.py +136 -136
- tapps_agents/core/validators/__init__.py +4 -4
- tapps_agents/core/validators/python_validator.py +87 -87
- tapps_agents/core/verification_agent.py +90 -90
- tapps_agents/core/visual_feedback.py +644 -644
- tapps_agents/core/workflow_validator.py +197 -197
- tapps_agents/core/worktree.py +367 -367
- tapps_agents/docker/__init__.py +10 -10
- tapps_agents/docker/analyzer.py +186 -186
- tapps_agents/docker/debugger.py +229 -229
- tapps_agents/docker/error_patterns.py +216 -216
- tapps_agents/epic/__init__.py +22 -22
- tapps_agents/epic/beads_sync.py +115 -115
- tapps_agents/epic/markdown_sync.py +105 -105
- tapps_agents/epic/models.py +96 -96
- tapps_agents/experts/__init__.py +163 -163
- tapps_agents/experts/agent_integration.py +243 -243
- tapps_agents/experts/auto_generator.py +331 -331
- tapps_agents/experts/base_expert.py +536 -536
- tapps_agents/experts/builtin_registry.py +261 -261
- tapps_agents/experts/business_metrics.py +565 -565
- tapps_agents/experts/cache.py +266 -266
- tapps_agents/experts/confidence_breakdown.py +306 -306
- tapps_agents/experts/confidence_calculator.py +336 -336
- tapps_agents/experts/confidence_metrics.py +236 -236
- tapps_agents/experts/domain_config.py +311 -311
- tapps_agents/experts/domain_detector.py +550 -550
- tapps_agents/experts/domain_utils.py +84 -84
- tapps_agents/experts/expert_config.py +113 -113
- tapps_agents/experts/expert_engine.py +465 -465
- tapps_agents/experts/expert_registry.py +744 -744
- tapps_agents/experts/expert_synthesizer.py +70 -70
- tapps_agents/experts/governance.py +197 -197
- tapps_agents/experts/history_logger.py +312 -312
- tapps_agents/experts/knowledge/README.md +180 -180
- tapps_agents/experts/knowledge/accessibility/accessible-forms.md +331 -331
- tapps_agents/experts/knowledge/accessibility/aria-patterns.md +344 -344
- tapps_agents/experts/knowledge/accessibility/color-contrast.md +285 -285
- tapps_agents/experts/knowledge/accessibility/keyboard-navigation.md +332 -332
- tapps_agents/experts/knowledge/accessibility/screen-readers.md +282 -282
- tapps_agents/experts/knowledge/accessibility/semantic-html.md +355 -355
- tapps_agents/experts/knowledge/accessibility/testing-accessibility.md +369 -369
- tapps_agents/experts/knowledge/accessibility/wcag-2.1.md +296 -296
- tapps_agents/experts/knowledge/accessibility/wcag-2.2.md +211 -211
- tapps_agents/experts/knowledge/agent-learning/best-practices.md +715 -715
- tapps_agents/experts/knowledge/agent-learning/pattern-extraction.md +282 -282
- tapps_agents/experts/knowledge/agent-learning/prompt-optimization.md +320 -320
- tapps_agents/experts/knowledge/ai-frameworks/model-optimization.md +90 -90
- tapps_agents/experts/knowledge/ai-frameworks/openvino-patterns.md +260 -260
- tapps_agents/experts/knowledge/api-design-integration/api-gateway-patterns.md +309 -309
- tapps_agents/experts/knowledge/api-design-integration/api-security-patterns.md +521 -521
- tapps_agents/experts/knowledge/api-design-integration/api-versioning.md +421 -421
- tapps_agents/experts/knowledge/api-design-integration/async-protocol-patterns.md +61 -61
- tapps_agents/experts/knowledge/api-design-integration/contract-testing.md +221 -221
- tapps_agents/experts/knowledge/api-design-integration/external-api-integration.md +489 -489
- tapps_agents/experts/knowledge/api-design-integration/fastapi-patterns.md +360 -360
- tapps_agents/experts/knowledge/api-design-integration/fastapi-testing.md +262 -262
- tapps_agents/experts/knowledge/api-design-integration/graphql-patterns.md +582 -582
- tapps_agents/experts/knowledge/api-design-integration/grpc-best-practices.md +499 -499
- tapps_agents/experts/knowledge/api-design-integration/mqtt-patterns.md +455 -455
- tapps_agents/experts/knowledge/api-design-integration/rate-limiting.md +507 -507
- tapps_agents/experts/knowledge/api-design-integration/restful-api-design.md +618 -618
- tapps_agents/experts/knowledge/api-design-integration/websocket-patterns.md +480 -480
- tapps_agents/experts/knowledge/cloud-infrastructure/cloud-native-patterns.md +175 -175
- tapps_agents/experts/knowledge/cloud-infrastructure/container-health-checks.md +261 -261
- tapps_agents/experts/knowledge/cloud-infrastructure/containerization.md +222 -222
- tapps_agents/experts/knowledge/cloud-infrastructure/cost-optimization.md +122 -122
- tapps_agents/experts/knowledge/cloud-infrastructure/disaster-recovery.md +153 -153
- tapps_agents/experts/knowledge/cloud-infrastructure/dockerfile-patterns.md +285 -285
- tapps_agents/experts/knowledge/cloud-infrastructure/infrastructure-as-code.md +187 -187
- tapps_agents/experts/knowledge/cloud-infrastructure/kubernetes-patterns.md +253 -253
- tapps_agents/experts/knowledge/cloud-infrastructure/multi-cloud-strategies.md +155 -155
- tapps_agents/experts/knowledge/cloud-infrastructure/serverless-architecture.md +200 -200
- tapps_agents/experts/knowledge/code-quality-analysis/README.md +16 -16
- tapps_agents/experts/knowledge/code-quality-analysis/code-metrics.md +137 -137
- tapps_agents/experts/knowledge/code-quality-analysis/complexity-analysis.md +181 -181
- tapps_agents/experts/knowledge/code-quality-analysis/technical-debt-patterns.md +191 -191
- tapps_agents/experts/knowledge/data-privacy-compliance/anonymization.md +313 -313
- tapps_agents/experts/knowledge/data-privacy-compliance/ccpa.md +255 -255
- tapps_agents/experts/knowledge/data-privacy-compliance/consent-management.md +282 -282
- tapps_agents/experts/knowledge/data-privacy-compliance/data-minimization.md +275 -275
- tapps_agents/experts/knowledge/data-privacy-compliance/data-retention.md +297 -297
- tapps_agents/experts/knowledge/data-privacy-compliance/data-subject-rights.md +383 -383
- tapps_agents/experts/knowledge/data-privacy-compliance/encryption-privacy.md +285 -285
- tapps_agents/experts/knowledge/data-privacy-compliance/gdpr.md +344 -344
- tapps_agents/experts/knowledge/data-privacy-compliance/hipaa.md +385 -385
- tapps_agents/experts/knowledge/data-privacy-compliance/privacy-by-design.md +280 -280
- tapps_agents/experts/knowledge/database-data-management/acid-vs-cap.md +164 -164
- tapps_agents/experts/knowledge/database-data-management/backup-and-recovery.md +182 -182
- tapps_agents/experts/knowledge/database-data-management/data-modeling.md +172 -172
- tapps_agents/experts/knowledge/database-data-management/database-design.md +187 -187
- tapps_agents/experts/knowledge/database-data-management/flux-query-optimization.md +342 -342
- tapps_agents/experts/knowledge/database-data-management/influxdb-connection-patterns.md +432 -432
- tapps_agents/experts/knowledge/database-data-management/influxdb-patterns.md +442 -442
- tapps_agents/experts/knowledge/database-data-management/migration-strategies.md +216 -216
- tapps_agents/experts/knowledge/database-data-management/nosql-patterns.md +259 -259
- tapps_agents/experts/knowledge/database-data-management/scalability-patterns.md +184 -184
- tapps_agents/experts/knowledge/database-data-management/sql-optimization.md +175 -175
- tapps_agents/experts/knowledge/database-data-management/time-series-modeling.md +444 -444
- tapps_agents/experts/knowledge/development-workflow/README.md +16 -16
- tapps_agents/experts/knowledge/development-workflow/automation-best-practices.md +216 -216
- tapps_agents/experts/knowledge/development-workflow/build-strategies.md +198 -198
- tapps_agents/experts/knowledge/development-workflow/deployment-patterns.md +205 -205
- tapps_agents/experts/knowledge/development-workflow/git-workflows.md +205 -205
- tapps_agents/experts/knowledge/documentation-knowledge-management/README.md +16 -16
- tapps_agents/experts/knowledge/documentation-knowledge-management/api-documentation-patterns.md +231 -231
- tapps_agents/experts/knowledge/documentation-knowledge-management/documentation-standards.md +191 -191
- tapps_agents/experts/knowledge/documentation-knowledge-management/knowledge-management.md +171 -171
- tapps_agents/experts/knowledge/documentation-knowledge-management/technical-writing-guide.md +192 -192
- tapps_agents/experts/knowledge/observability-monitoring/alerting-patterns.md +461 -461
- tapps_agents/experts/knowledge/observability-monitoring/apm-tools.md +459 -459
- tapps_agents/experts/knowledge/observability-monitoring/distributed-tracing.md +367 -367
- tapps_agents/experts/knowledge/observability-monitoring/logging-strategies.md +478 -478
- tapps_agents/experts/knowledge/observability-monitoring/metrics-and-monitoring.md +510 -510
- tapps_agents/experts/knowledge/observability-monitoring/observability-best-practices.md +492 -492
- tapps_agents/experts/knowledge/observability-monitoring/open-telemetry.md +573 -573
- tapps_agents/experts/knowledge/observability-monitoring/slo-sli-sla.md +419 -419
- tapps_agents/experts/knowledge/performance/anti-patterns.md +284 -284
- tapps_agents/experts/knowledge/performance/api-performance.md +256 -256
- tapps_agents/experts/knowledge/performance/caching.md +327 -327
- tapps_agents/experts/knowledge/performance/database-performance.md +252 -252
- tapps_agents/experts/knowledge/performance/optimization-patterns.md +327 -327
- tapps_agents/experts/knowledge/performance/profiling.md +297 -297
- tapps_agents/experts/knowledge/performance/resource-management.md +293 -293
- tapps_agents/experts/knowledge/performance/scalability.md +306 -306
- tapps_agents/experts/knowledge/security/owasp-top10.md +209 -209
- tapps_agents/experts/knowledge/security/secure-coding-practices.md +207 -207
- tapps_agents/experts/knowledge/security/threat-modeling.md +220 -220
- tapps_agents/experts/knowledge/security/vulnerability-patterns.md +342 -342
- tapps_agents/experts/knowledge/software-architecture/docker-compose-patterns.md +314 -314
- tapps_agents/experts/knowledge/software-architecture/microservices-patterns.md +379 -379
- tapps_agents/experts/knowledge/software-architecture/service-communication.md +316 -316
- tapps_agents/experts/knowledge/testing/best-practices.md +310 -310
- tapps_agents/experts/knowledge/testing/coverage-analysis.md +293 -293
- tapps_agents/experts/knowledge/testing/mocking.md +256 -256
- tapps_agents/experts/knowledge/testing/test-automation.md +276 -276
- tapps_agents/experts/knowledge/testing/test-data.md +271 -271
- tapps_agents/experts/knowledge/testing/test-design-patterns.md +280 -280
- tapps_agents/experts/knowledge/testing/test-maintenance.md +236 -236
- tapps_agents/experts/knowledge/testing/test-strategies.md +311 -311
- tapps_agents/experts/knowledge/user-experience/information-architecture.md +325 -325
- tapps_agents/experts/knowledge/user-experience/interaction-design.md +363 -363
- tapps_agents/experts/knowledge/user-experience/prototyping.md +293 -293
- tapps_agents/experts/knowledge/user-experience/usability-heuristics.md +337 -337
- tapps_agents/experts/knowledge/user-experience/usability-testing.md +311 -311
- tapps_agents/experts/knowledge/user-experience/user-journeys.md +296 -296
- tapps_agents/experts/knowledge/user-experience/user-research.md +373 -373
- tapps_agents/experts/knowledge/user-experience/ux-principles.md +340 -340
- tapps_agents/experts/knowledge_freshness.py +321 -321
- tapps_agents/experts/knowledge_ingestion.py +438 -438
- tapps_agents/experts/knowledge_need_detector.py +93 -93
- tapps_agents/experts/knowledge_validator.py +382 -382
- tapps_agents/experts/observability.py +440 -440
- tapps_agents/experts/passive_notifier.py +238 -238
- tapps_agents/experts/proactive_orchestrator.py +32 -32
- tapps_agents/experts/rag_chunker.py +205 -205
- tapps_agents/experts/rag_embedder.py +152 -152
- tapps_agents/experts/rag_evaluation.py +299 -299
- tapps_agents/experts/rag_index.py +303 -303
- tapps_agents/experts/rag_metrics.py +293 -293
- tapps_agents/experts/rag_safety.py +263 -263
- tapps_agents/experts/report_generator.py +296 -296
- tapps_agents/experts/setup_wizard.py +441 -441
- tapps_agents/experts/simple_rag.py +431 -431
- tapps_agents/experts/vector_rag.py +354 -354
- tapps_agents/experts/weight_distributor.py +304 -304
- tapps_agents/health/__init__.py +24 -24
- tapps_agents/health/base.py +75 -75
- tapps_agents/health/checks/__init__.py +22 -22
- tapps_agents/health/checks/automation.py +127 -127
- tapps_agents/health/checks/context7_cache.py +210 -210
- tapps_agents/health/checks/environment.py +116 -116
- tapps_agents/health/checks/execution.py +170 -170
- tapps_agents/health/checks/knowledge_base.py +187 -187
- tapps_agents/health/checks/outcomes.py +324 -324
- tapps_agents/health/collector.py +280 -280
- tapps_agents/health/dashboard.py +137 -137
- tapps_agents/health/metrics.py +151 -151
- tapps_agents/health/orchestrator.py +271 -271
- tapps_agents/health/registry.py +166 -166
- tapps_agents/hooks/__init__.py +33 -33
- tapps_agents/hooks/config.py +140 -140
- tapps_agents/hooks/events.py +135 -135
- tapps_agents/hooks/executor.py +128 -128
- tapps_agents/hooks/manager.py +143 -143
- tapps_agents/integration/__init__.py +8 -8
- tapps_agents/integration/service_integrator.py +121 -121
- tapps_agents/integrations/__init__.py +10 -10
- tapps_agents/integrations/clawdbot.py +525 -525
- tapps_agents/integrations/memory_bridge.py +356 -356
- tapps_agents/mcp/__init__.py +18 -18
- tapps_agents/mcp/gateway.py +112 -112
- tapps_agents/mcp/servers/__init__.py +13 -13
- tapps_agents/mcp/servers/analysis.py +204 -204
- tapps_agents/mcp/servers/context7.py +198 -198
- tapps_agents/mcp/servers/filesystem.py +218 -218
- tapps_agents/mcp/servers/git.py +201 -201
- tapps_agents/mcp/tool_registry.py +115 -115
- tapps_agents/quality/__init__.py +54 -54
- tapps_agents/quality/coverage_analyzer.py +379 -379
- tapps_agents/quality/enforcement.py +82 -82
- tapps_agents/quality/gates/__init__.py +37 -37
- tapps_agents/quality/gates/approval_gate.py +255 -255
- tapps_agents/quality/gates/base.py +84 -84
- tapps_agents/quality/gates/exceptions.py +43 -43
- tapps_agents/quality/gates/policy_gate.py +195 -195
- tapps_agents/quality/gates/registry.py +239 -239
- tapps_agents/quality/gates/security_gate.py +156 -156
- tapps_agents/quality/quality_gates.py +369 -369
- tapps_agents/quality/secret_scanner.py +335 -335
- tapps_agents/session/__init__.py +19 -19
- tapps_agents/session/manager.py +256 -256
- tapps_agents/simple_mode/__init__.py +66 -66
- tapps_agents/simple_mode/agent_contracts.py +357 -357
- tapps_agents/simple_mode/beads_hooks.py +151 -151
- tapps_agents/simple_mode/code_snippet_handler.py +382 -382
- tapps_agents/simple_mode/documentation_manager.py +395 -395
- tapps_agents/simple_mode/documentation_reader.py +187 -187
- tapps_agents/simple_mode/file_inference.py +292 -292
- tapps_agents/simple_mode/framework_change_detector.py +268 -268
- tapps_agents/simple_mode/intent_parser.py +510 -510
- tapps_agents/simple_mode/learning_progression.py +358 -358
- tapps_agents/simple_mode/nl_handler.py +700 -700
- tapps_agents/simple_mode/onboarding.py +253 -253
- tapps_agents/simple_mode/orchestrators/__init__.py +38 -38
- tapps_agents/simple_mode/orchestrators/base.py +185 -185
- tapps_agents/simple_mode/orchestrators/breakdown_orchestrator.py +49 -49
- tapps_agents/simple_mode/orchestrators/brownfield_orchestrator.py +135 -135
- tapps_agents/simple_mode/orchestrators/build_orchestrator.py +2700 -2667
- tapps_agents/simple_mode/orchestrators/deliverable_checklist.py +349 -349
- tapps_agents/simple_mode/orchestrators/enhance_orchestrator.py +53 -53
- tapps_agents/simple_mode/orchestrators/epic_orchestrator.py +122 -122
- tapps_agents/simple_mode/orchestrators/explore_orchestrator.py +184 -184
- tapps_agents/simple_mode/orchestrators/fix_orchestrator.py +723 -723
- tapps_agents/simple_mode/orchestrators/plan_analysis_orchestrator.py +206 -206
- tapps_agents/simple_mode/orchestrators/pr_orchestrator.py +237 -237
- tapps_agents/simple_mode/orchestrators/refactor_orchestrator.py +222 -222
- tapps_agents/simple_mode/orchestrators/requirements_tracer.py +262 -262
- tapps_agents/simple_mode/orchestrators/resume_orchestrator.py +210 -210
- tapps_agents/simple_mode/orchestrators/review_orchestrator.py +161 -161
- tapps_agents/simple_mode/orchestrators/test_orchestrator.py +82 -82
- tapps_agents/simple_mode/output_aggregator.py +340 -340
- tapps_agents/simple_mode/result_formatters.py +598 -598
- tapps_agents/simple_mode/step_dependencies.py +382 -382
- tapps_agents/simple_mode/step_results.py +276 -276
- tapps_agents/simple_mode/streaming.py +388 -388
- tapps_agents/simple_mode/variations.py +129 -129
- tapps_agents/simple_mode/visual_feedback.py +238 -238
- tapps_agents/simple_mode/zero_config.py +274 -274
- tapps_agents/suggestions/__init__.py +8 -8
- tapps_agents/suggestions/inline_suggester.py +52 -52
- tapps_agents/templates/__init__.py +8 -8
- tapps_agents/templates/microservice_generator.py +274 -274
- tapps_agents/utils/env_validator.py +291 -291
- tapps_agents/workflow/__init__.py +171 -171
- tapps_agents/workflow/acceptance_verifier.py +132 -132
- tapps_agents/workflow/agent_handlers/__init__.py +41 -41
- tapps_agents/workflow/agent_handlers/analyst_handler.py +75 -75
- tapps_agents/workflow/agent_handlers/architect_handler.py +107 -107
- tapps_agents/workflow/agent_handlers/base.py +84 -84
- tapps_agents/workflow/agent_handlers/debugger_handler.py +100 -100
- tapps_agents/workflow/agent_handlers/designer_handler.py +110 -110
- tapps_agents/workflow/agent_handlers/documenter_handler.py +94 -94
- tapps_agents/workflow/agent_handlers/implementer_handler.py +235 -235
- tapps_agents/workflow/agent_handlers/ops_handler.py +62 -62
- tapps_agents/workflow/agent_handlers/orchestrator_handler.py +43 -43
- tapps_agents/workflow/agent_handlers/planner_handler.py +98 -98
- tapps_agents/workflow/agent_handlers/registry.py +119 -119
- tapps_agents/workflow/agent_handlers/reviewer_handler.py +119 -119
- tapps_agents/workflow/agent_handlers/tester_handler.py +69 -69
- tapps_agents/workflow/analytics_accessor.py +337 -337
- tapps_agents/workflow/analytics_alerts.py +416 -416
- tapps_agents/workflow/analytics_dashboard_cursor.py +281 -281
- tapps_agents/workflow/analytics_dual_write.py +103 -103
- tapps_agents/workflow/analytics_integration.py +119 -119
- tapps_agents/workflow/analytics_query_parser.py +278 -278
- tapps_agents/workflow/analytics_visualizer.py +259 -259
- tapps_agents/workflow/artifact_helper.py +204 -204
- tapps_agents/workflow/audit_logger.py +263 -263
- tapps_agents/workflow/auto_execution_config.py +340 -340
- tapps_agents/workflow/auto_progression.py +586 -586
- tapps_agents/workflow/branch_cleanup.py +349 -349
- tapps_agents/workflow/checkpoint.py +256 -256
- tapps_agents/workflow/checkpoint_manager.py +178 -178
- tapps_agents/workflow/code_artifact.py +179 -179
- tapps_agents/workflow/common_enums.py +96 -96
- tapps_agents/workflow/confirmation_handler.py +130 -130
- tapps_agents/workflow/context_analyzer.py +222 -222
- tapps_agents/workflow/context_artifact.py +230 -230
- tapps_agents/workflow/cursor_chat.py +94 -94
- tapps_agents/workflow/cursor_executor.py +2337 -2337
- tapps_agents/workflow/cursor_skill_helper.py +516 -516
- tapps_agents/workflow/dependency_resolver.py +244 -244
- tapps_agents/workflow/design_artifact.py +156 -156
- tapps_agents/workflow/detector.py +751 -751
- tapps_agents/workflow/direct_execution_fallback.py +301 -301
- tapps_agents/workflow/docs_artifact.py +168 -168
- tapps_agents/workflow/enforcer.py +389 -389
- tapps_agents/workflow/enhancement_artifact.py +142 -142
- tapps_agents/workflow/error_recovery.py +806 -806
- tapps_agents/workflow/event_bus.py +183 -183
- tapps_agents/workflow/event_log.py +612 -612
- tapps_agents/workflow/events.py +63 -63
- tapps_agents/workflow/exceptions.py +43 -43
- tapps_agents/workflow/execution_graph.py +498 -498
- tapps_agents/workflow/execution_plan.py +126 -126
- tapps_agents/workflow/file_utils.py +186 -186
- tapps_agents/workflow/gate_evaluator.py +182 -182
- tapps_agents/workflow/gate_integration.py +200 -200
- tapps_agents/workflow/graph_visualizer.py +130 -130
- tapps_agents/workflow/health_checker.py +206 -206
- tapps_agents/workflow/logging_helper.py +243 -243
- tapps_agents/workflow/manifest.py +582 -582
- tapps_agents/workflow/marker_writer.py +250 -250
- tapps_agents/workflow/message_formatter.py +188 -188
- tapps_agents/workflow/messaging.py +325 -325
- tapps_agents/workflow/metadata_models.py +91 -91
- tapps_agents/workflow/metrics_integration.py +226 -226
- tapps_agents/workflow/migration_utils.py +116 -116
- tapps_agents/workflow/models.py +148 -148
- tapps_agents/workflow/nlp_config.py +198 -198
- tapps_agents/workflow/nlp_error_handler.py +207 -207
- tapps_agents/workflow/nlp_executor.py +163 -163
- tapps_agents/workflow/nlp_parser.py +528 -528
- tapps_agents/workflow/observability_dashboard.py +451 -451
- tapps_agents/workflow/observer.py +170 -170
- tapps_agents/workflow/ops_artifact.py +257 -257
- tapps_agents/workflow/output_passing.py +214 -214
- tapps_agents/workflow/parallel_executor.py +463 -463
- tapps_agents/workflow/planning_artifact.py +179 -179
- tapps_agents/workflow/preset_loader.py +285 -285
- tapps_agents/workflow/preset_recommender.py +270 -270
- tapps_agents/workflow/progress_logger.py +145 -145
- tapps_agents/workflow/progress_manager.py +303 -303
- tapps_agents/workflow/progress_monitor.py +186 -186
- tapps_agents/workflow/progress_updates.py +423 -423
- tapps_agents/workflow/quality_artifact.py +158 -158
- tapps_agents/workflow/quality_loopback.py +101 -101
- tapps_agents/workflow/recommender.py +387 -387
- tapps_agents/workflow/remediation_loop.py +166 -166
- tapps_agents/workflow/result_aggregator.py +300 -300
- tapps_agents/workflow/review_artifact.py +185 -185
- tapps_agents/workflow/schema_validator.py +522 -522
- tapps_agents/workflow/session_handoff.py +178 -178
- tapps_agents/workflow/skill_invoker.py +648 -648
- tapps_agents/workflow/state_manager.py +756 -756
- tapps_agents/workflow/state_persistence_config.py +331 -331
- tapps_agents/workflow/status_monitor.py +449 -449
- tapps_agents/workflow/step_checkpoint.py +314 -314
- tapps_agents/workflow/step_details.py +201 -201
- tapps_agents/workflow/story_models.py +147 -147
- tapps_agents/workflow/streaming.py +416 -416
- tapps_agents/workflow/suggestion_engine.py +552 -552
- tapps_agents/workflow/testing_artifact.py +186 -186
- tapps_agents/workflow/timeline.py +158 -158
- tapps_agents/workflow/token_integration.py +209 -209
- tapps_agents/workflow/validation.py +217 -217
- tapps_agents/workflow/visual_feedback.py +391 -391
- tapps_agents/workflow/workflow_chain.py +95 -95
- tapps_agents/workflow/workflow_summary.py +219 -219
- tapps_agents/workflow/worktree_manager.py +724 -724
- {tapps_agents-3.5.41.dist-info → tapps_agents-3.6.0.dist-info}/METADATA +672 -672
- tapps_agents-3.6.0.dist-info/RECORD +758 -0
- {tapps_agents-3.5.41.dist-info → tapps_agents-3.6.0.dist-info}/licenses/LICENSE +22 -22
- tapps_agents/health/checks/outcomes.backup_20260204_064058.py +0 -324
- tapps_agents/health/checks/outcomes.backup_20260204_064256.py +0 -324
- tapps_agents/health/checks/outcomes.backup_20260204_064600.py +0 -324
- tapps_agents-3.5.41.dist-info/RECORD +0 -760
- {tapps_agents-3.5.41.dist-info → tapps_agents-3.6.0.dist-info}/WHEEL +0 -0
- {tapps_agents-3.5.41.dist-info → tapps_agents-3.6.0.dist-info}/entry_points.txt +0 -0
- {tapps_agents-3.5.41.dist-info → tapps_agents-3.6.0.dist-info}/top_level.txt +0 -0
|
@@ -1,632 +1,632 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Test Generator - Prepares test generation instructions for Cursor Skills
|
|
3
|
-
|
|
4
|
-
Phase 2.1: Enhanced with coverage analysis and language-aware test generation
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
import ast
|
|
8
|
-
from pathlib import Path
|
|
9
|
-
from typing import Any
|
|
10
|
-
|
|
11
|
-
from ...core.instructions import TestGenerationInstruction
|
|
12
|
-
from ...core.language_detector import Language, LanguageDetector
|
|
13
|
-
from .coverage_analyzer import CoverageAnalyzer, CoverageReport
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class TestGenerator:
|
|
17
|
-
"""
|
|
18
|
-
Prepares test generation instructions for Cursor Skills execution.
|
|
19
|
-
|
|
20
|
-
Enhanced with:
|
|
21
|
-
- Language-aware test framework detection
|
|
22
|
-
- Async coverage analysis
|
|
23
|
-
- Coverage measurement for Python (pytest) and TypeScript/React (jest/vitest)
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
def __init__(self):
|
|
27
|
-
"""Initialize test generator."""
|
|
28
|
-
self.language_detector = LanguageDetector()
|
|
29
|
-
self.coverage_analyzer = CoverageAnalyzer()
|
|
30
|
-
|
|
31
|
-
def prepare_unit_tests(
|
|
32
|
-
self,
|
|
33
|
-
code_path: Path,
|
|
34
|
-
test_path: Path | None = None,
|
|
35
|
-
context: str | None = None,
|
|
36
|
-
expert_guidance: str | None = None,
|
|
37
|
-
focus: str | None = None,
|
|
38
|
-
) -> TestGenerationInstruction:
|
|
39
|
-
"""
|
|
40
|
-
Prepare unit test generation instruction for Cursor Skills.
|
|
41
|
-
|
|
42
|
-
Args:
|
|
43
|
-
code_path: Path to the source code file
|
|
44
|
-
test_path: Optional path where test will be written
|
|
45
|
-
context: Optional context (existing tests, patterns, etc.)
|
|
46
|
-
expert_guidance: Optional expert guidance for test generation
|
|
47
|
-
|
|
48
|
-
Returns:
|
|
49
|
-
TestGenerationInstruction object for Cursor Skills execution
|
|
50
|
-
"""
|
|
51
|
-
# Read source code
|
|
52
|
-
code = code_path.read_text(encoding="utf-8")
|
|
53
|
-
|
|
54
|
-
# Detect language
|
|
55
|
-
detection_result = self.language_detector.detect_language(code_path, code)
|
|
56
|
-
language = detection_result.language
|
|
57
|
-
|
|
58
|
-
# Analyze code structure
|
|
59
|
-
analysis = self._analyze_code(code, code_path)
|
|
60
|
-
|
|
61
|
-
# Detect test framework based on language
|
|
62
|
-
test_framework = self._detect_test_framework_for_language(language, code)
|
|
63
|
-
|
|
64
|
-
# Build coverage requirements with focus areas if provided
|
|
65
|
-
coverage_requirements = {
|
|
66
|
-
"target_coverage": 80.0,
|
|
67
|
-
"test_types": ["unit"],
|
|
68
|
-
"context": context,
|
|
69
|
-
"expert_guidance": expert_guidance,
|
|
70
|
-
"language": language.value,
|
|
71
|
-
}
|
|
72
|
-
if focus:
|
|
73
|
-
focus_areas = [area.strip() for area in focus.split(",")]
|
|
74
|
-
coverage_requirements["focus_areas"] = focus_areas
|
|
75
|
-
|
|
76
|
-
return TestGenerationInstruction(
|
|
77
|
-
target_file=str(test_path) if test_path else str(code_path),
|
|
78
|
-
test_framework=test_framework,
|
|
79
|
-
coverage_requirements=coverage_requirements,
|
|
80
|
-
)
|
|
81
|
-
|
|
82
|
-
async def measure_coverage(
|
|
83
|
-
self,
|
|
84
|
-
file_path: Path,
|
|
85
|
-
test_file_path: Path | None = None,
|
|
86
|
-
project_root: Path | None = None,
|
|
87
|
-
) -> CoverageReport:
|
|
88
|
-
"""
|
|
89
|
-
Measure test coverage for a file using language-specific tools.
|
|
90
|
-
|
|
91
|
-
Phase 2.1: Coverage Analysis Integration
|
|
92
|
-
|
|
93
|
-
Args:
|
|
94
|
-
file_path: Path to the source file
|
|
95
|
-
test_file_path: Optional path to test file
|
|
96
|
-
project_root: Optional project root directory
|
|
97
|
-
|
|
98
|
-
Returns:
|
|
99
|
-
CoverageReport with coverage percentage and metrics
|
|
100
|
-
"""
|
|
101
|
-
# Detect language
|
|
102
|
-
code = file_path.read_text(encoding="utf-8") if file_path.exists() else ""
|
|
103
|
-
detection_result = self.language_detector.detect_language(file_path, code)
|
|
104
|
-
language = detection_result.language
|
|
105
|
-
|
|
106
|
-
# Measure coverage using language-specific analyzer
|
|
107
|
-
return await self.coverage_analyzer.measure_coverage(
|
|
108
|
-
file_path, language, test_file_path, project_root
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
def _detect_test_framework_for_language(
|
|
112
|
-
self, language: Language, code: str
|
|
113
|
-
) -> str:
|
|
114
|
-
"""
|
|
115
|
-
Detect test framework based on language.
|
|
116
|
-
|
|
117
|
-
Args:
|
|
118
|
-
language: Detected language
|
|
119
|
-
code: Source code content
|
|
120
|
-
|
|
121
|
-
Returns:
|
|
122
|
-
Test framework name (pytest, jest, vitest, etc.)
|
|
123
|
-
"""
|
|
124
|
-
if language == Language.PYTHON:
|
|
125
|
-
# Check code for framework hints
|
|
126
|
-
if "import pytest" in code or "from pytest" in code:
|
|
127
|
-
return "pytest"
|
|
128
|
-
elif "import unittest" in code or "from unittest" in code:
|
|
129
|
-
return "unittest"
|
|
130
|
-
return "pytest" # Default for Python
|
|
131
|
-
|
|
132
|
-
elif language in [Language.TYPESCRIPT, Language.JAVASCRIPT, Language.REACT]:
|
|
133
|
-
# Check package.json or code for framework
|
|
134
|
-
# This is a basic check - full detection is in CoverageAnalyzer
|
|
135
|
-
if "vitest" in code.lower():
|
|
136
|
-
return "vitest"
|
|
137
|
-
return "jest" # Default for TypeScript/JavaScript
|
|
138
|
-
|
|
139
|
-
return "pytest" # Fallback default
|
|
140
|
-
|
|
141
|
-
def prepare_integration_tests(
|
|
142
|
-
self,
|
|
143
|
-
file_paths: list[Path],
|
|
144
|
-
test_path: Path | None = None,
|
|
145
|
-
context: str | None = None,
|
|
146
|
-
expert_guidance: str | None = None,
|
|
147
|
-
focus: str | None = None,
|
|
148
|
-
) -> TestGenerationInstruction:
|
|
149
|
-
"""
|
|
150
|
-
Prepare integration test generation instruction for Cursor Skills.
|
|
151
|
-
|
|
152
|
-
Args:
|
|
153
|
-
file_paths: List of source code file paths
|
|
154
|
-
test_path: Optional path where test will be written
|
|
155
|
-
context: Optional context
|
|
156
|
-
expert_guidance: Optional expert guidance
|
|
157
|
-
focus: Optional comma-separated focus areas
|
|
158
|
-
|
|
159
|
-
Returns:
|
|
160
|
-
TestGenerationInstruction object for Cursor Skills execution
|
|
161
|
-
"""
|
|
162
|
-
# Use first file path or test_path as target
|
|
163
|
-
target_file = str(test_path) if test_path else str(file_paths[0]) if file_paths else ""
|
|
164
|
-
|
|
165
|
-
coverage_requirements = {
|
|
166
|
-
"target_coverage": 80.0,
|
|
167
|
-
"test_types": ["integration"],
|
|
168
|
-
"file_paths": [str(p) for p in file_paths],
|
|
169
|
-
"context": context,
|
|
170
|
-
"expert_guidance": expert_guidance,
|
|
171
|
-
}
|
|
172
|
-
if focus:
|
|
173
|
-
focus_areas = [area.strip() for area in focus.split(",")]
|
|
174
|
-
coverage_requirements["focus_areas"] = focus_areas
|
|
175
|
-
|
|
176
|
-
return TestGenerationInstruction(
|
|
177
|
-
target_file=target_file,
|
|
178
|
-
test_framework="pytest",
|
|
179
|
-
coverage_requirements=coverage_requirements,
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
def prepare_e2e_tests(
|
|
183
|
-
self,
|
|
184
|
-
project_root: Path,
|
|
185
|
-
test_path: Path | None = None,
|
|
186
|
-
context: str | None = None,
|
|
187
|
-
expert_guidance: str | None = None,
|
|
188
|
-
) -> TestGenerationInstruction | None:
|
|
189
|
-
"""
|
|
190
|
-
Prepare end-to-end (E2E) test generation instruction for Cursor Skills.
|
|
191
|
-
|
|
192
|
-
Args:
|
|
193
|
-
project_root: Root directory of the project
|
|
194
|
-
test_path: Optional path where test will be written
|
|
195
|
-
context: Optional context
|
|
196
|
-
expert_guidance: Optional expert guidance
|
|
197
|
-
|
|
198
|
-
Returns:
|
|
199
|
-
TestGenerationInstruction object for Cursor Skills execution, or None if E2E framework not detected
|
|
200
|
-
"""
|
|
201
|
-
# Detect E2E framework
|
|
202
|
-
e2e_framework = self._detect_e2e_framework(project_root)
|
|
203
|
-
if not e2e_framework:
|
|
204
|
-
return None
|
|
205
|
-
|
|
206
|
-
# Analyze project structure
|
|
207
|
-
project_analysis = self._analyze_project_structure(project_root)
|
|
208
|
-
|
|
209
|
-
target_file = str(test_path) if test_path else str(project_root)
|
|
210
|
-
|
|
211
|
-
coverage_requirements = {
|
|
212
|
-
"target_coverage": 80.0,
|
|
213
|
-
"test_types": ["e2e"],
|
|
214
|
-
"e2e_framework": e2e_framework,
|
|
215
|
-
"project_analysis": project_analysis,
|
|
216
|
-
"context": context,
|
|
217
|
-
"expert_guidance": expert_guidance,
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
return TestGenerationInstruction(
|
|
221
|
-
target_file=target_file,
|
|
222
|
-
test_framework=e2e_framework,
|
|
223
|
-
coverage_requirements=coverage_requirements,
|
|
224
|
-
)
|
|
225
|
-
|
|
226
|
-
def _detect_e2e_framework(self, project_root: Path) -> str | None:
|
|
227
|
-
"""
|
|
228
|
-
Detect E2E testing framework in the project.
|
|
229
|
-
|
|
230
|
-
Returns:
|
|
231
|
-
Framework name ("playwright", "selenium", "cypress", "pytest-playwright") or None
|
|
232
|
-
"""
|
|
233
|
-
project_root = Path(project_root)
|
|
234
|
-
|
|
235
|
-
# Check for Playwright
|
|
236
|
-
playwright_config = project_root / "playwright.config.js"
|
|
237
|
-
playwright_config_ts = project_root / "playwright.config.ts"
|
|
238
|
-
playwright_pyproject = project_root / "pyproject.toml"
|
|
239
|
-
if (
|
|
240
|
-
playwright_config.exists()
|
|
241
|
-
or playwright_config_ts.exists()
|
|
242
|
-
or (playwright_pyproject.exists() and "playwright" in playwright_pyproject.read_text())
|
|
243
|
-
):
|
|
244
|
-
return "playwright"
|
|
245
|
-
|
|
246
|
-
# Check for pytest-playwright
|
|
247
|
-
if (project_root / "pytest.ini").exists():
|
|
248
|
-
pytest_ini_content = (project_root / "pytest.ini").read_text()
|
|
249
|
-
if "playwright" in pytest_ini_content.lower():
|
|
250
|
-
return "pytest-playwright"
|
|
251
|
-
|
|
252
|
-
# Check requirements.txt or pyproject.toml for pytest-playwright
|
|
253
|
-
for req_file in [project_root / "requirements.txt", project_root / "pyproject.toml"]:
|
|
254
|
-
if req_file.exists():
|
|
255
|
-
content = req_file.read_text().lower()
|
|
256
|
-
if "pytest-playwright" in content or "playwright" in content:
|
|
257
|
-
return "pytest-playwright"
|
|
258
|
-
|
|
259
|
-
# Check for Selenium
|
|
260
|
-
selenium_config = project_root / "selenium.config.js"
|
|
261
|
-
for req_file in [project_root / "requirements.txt", project_root / "pyproject.toml"]:
|
|
262
|
-
if req_file.exists():
|
|
263
|
-
content = req_file.read_text().lower()
|
|
264
|
-
if "selenium" in content:
|
|
265
|
-
return "selenium"
|
|
266
|
-
if selenium_config.exists():
|
|
267
|
-
return "selenium"
|
|
268
|
-
|
|
269
|
-
# Check for Cypress (JavaScript/TypeScript projects)
|
|
270
|
-
cypress_config = project_root / "cypress.config.js"
|
|
271
|
-
cypress_config_ts = project_root / "cypress.config.ts"
|
|
272
|
-
if cypress_config.exists() or cypress_config_ts.exists():
|
|
273
|
-
return "cypress"
|
|
274
|
-
|
|
275
|
-
return None
|
|
276
|
-
|
|
277
|
-
def _analyze_project_structure(self, project_root: Path) -> dict[str, Any]:
|
|
278
|
-
"""Analyze project structure for E2E test generation."""
|
|
279
|
-
project_root = Path(project_root)
|
|
280
|
-
analysis: dict[str, Any] = {
|
|
281
|
-
"entry_points": [],
|
|
282
|
-
"main_modules": [],
|
|
283
|
-
"api_endpoints": [],
|
|
284
|
-
"test_directories": [],
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
# Find entry points (main.py, app.py, __main__.py, etc.)
|
|
288
|
-
entry_patterns = ["main.py", "app.py", "__main__.py", "server.py", "run.py"]
|
|
289
|
-
for pattern in entry_patterns:
|
|
290
|
-
for entry_file in project_root.rglob(pattern):
|
|
291
|
-
if "test" not in str(entry_file):
|
|
292
|
-
analysis["entry_points"].append(str(entry_file.relative_to(project_root)))
|
|
293
|
-
|
|
294
|
-
# Find main modules (directories with __init__.py)
|
|
295
|
-
for init_file in project_root.rglob("__init__.py"):
|
|
296
|
-
module_dir = init_file.parent
|
|
297
|
-
if "test" not in str(module_dir):
|
|
298
|
-
rel_path = module_dir.relative_to(project_root)
|
|
299
|
-
if str(rel_path) != ".":
|
|
300
|
-
analysis["main_modules"].append(str(rel_path))
|
|
301
|
-
|
|
302
|
-
# Find API endpoints (common patterns)
|
|
303
|
-
api_patterns = ["api", "routes", "endpoints", "controllers"]
|
|
304
|
-
for pattern in api_patterns:
|
|
305
|
-
api_dir = project_root / pattern
|
|
306
|
-
if api_dir.exists() and api_dir.is_dir():
|
|
307
|
-
analysis["api_endpoints"].append(pattern)
|
|
308
|
-
|
|
309
|
-
# Find existing test directories
|
|
310
|
-
test_dirs = ["tests", "test", "tests/e2e", "tests/integration"]
|
|
311
|
-
for test_dir in test_dirs:
|
|
312
|
-
test_path = project_root / test_dir
|
|
313
|
-
if test_path.exists() and test_path.is_dir():
|
|
314
|
-
analysis["test_directories"].append(test_dir)
|
|
315
|
-
|
|
316
|
-
return analysis
|
|
317
|
-
|
|
318
|
-
def _analyze_code(self, code: str, file_path: Path) -> dict[str, Any]:
|
|
319
|
-
"""Analyze code structure to extract functions, classes, etc."""
|
|
320
|
-
functions: list[dict[str, Any]] = []
|
|
321
|
-
classes: list[dict[str, Any]] = []
|
|
322
|
-
imports: list[str] = []
|
|
323
|
-
|
|
324
|
-
analysis: dict[str, Any] = {
|
|
325
|
-
"file_name": file_path.name,
|
|
326
|
-
"functions": functions,
|
|
327
|
-
"classes": classes,
|
|
328
|
-
"imports": imports,
|
|
329
|
-
"test_framework": self._detect_test_framework(code),
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
try:
|
|
333
|
-
tree = ast.parse(code)
|
|
334
|
-
|
|
335
|
-
for node in ast.walk(tree):
|
|
336
|
-
if isinstance(node, ast.FunctionDef):
|
|
337
|
-
functions.append(
|
|
338
|
-
{
|
|
339
|
-
"name": node.name,
|
|
340
|
-
"args": [arg.arg for arg in node.args.args],
|
|
341
|
-
"decorators": [
|
|
342
|
-
ast.unparse(d) if hasattr(ast, "unparse") else str(d)
|
|
343
|
-
for d in node.decorator_list
|
|
344
|
-
],
|
|
345
|
-
}
|
|
346
|
-
)
|
|
347
|
-
elif isinstance(node, ast.ClassDef):
|
|
348
|
-
methods = [
|
|
349
|
-
n.name for n in node.body if isinstance(n, ast.FunctionDef)
|
|
350
|
-
]
|
|
351
|
-
classes.append({"name": node.name, "methods": methods})
|
|
352
|
-
elif isinstance(node, (ast.Import, ast.ImportFrom)):
|
|
353
|
-
if isinstance(node, ast.Import):
|
|
354
|
-
imports.extend([alias.name for alias in node.names])
|
|
355
|
-
else:
|
|
356
|
-
imports.append(node.module or "")
|
|
357
|
-
except SyntaxError:
|
|
358
|
-
# If code has syntax errors, return basic analysis
|
|
359
|
-
pass
|
|
360
|
-
|
|
361
|
-
return analysis
|
|
362
|
-
|
|
363
|
-
def _detect_test_framework(self, code: str) -> str:
|
|
364
|
-
"""
|
|
365
|
-
Detect which test framework is being used (legacy method).
|
|
366
|
-
|
|
367
|
-
Note: Use _detect_test_framework_for_language() for language-aware detection.
|
|
368
|
-
"""
|
|
369
|
-
if "import pytest" in code or "from pytest" in code:
|
|
370
|
-
return "pytest"
|
|
371
|
-
elif "import unittest" in code or "from unittest" in code:
|
|
372
|
-
return "unittest"
|
|
373
|
-
elif "import nose" in code or "from nose" in code:
|
|
374
|
-
return "nose"
|
|
375
|
-
else:
|
|
376
|
-
return "pytest" # Default
|
|
377
|
-
|
|
378
|
-
def _build_unit_test_prompt(
|
|
379
|
-
self,
|
|
380
|
-
code: str,
|
|
381
|
-
analysis: dict[str, Any],
|
|
382
|
-
test_path: Path | None,
|
|
383
|
-
context: str | None,
|
|
384
|
-
expert_guidance: str | None = None,
|
|
385
|
-
) -> str:
|
|
386
|
-
"""Build prompt for unit test generation."""
|
|
387
|
-
prompt_parts = [
|
|
388
|
-
"Generate comprehensive unit tests for the following Python code.",
|
|
389
|
-
"",
|
|
390
|
-
f"Source file: {analysis['file_name']}",
|
|
391
|
-
"",
|
|
392
|
-
"Code structure:",
|
|
393
|
-
f"- Functions: {', '.join([f['name'] for f in analysis['functions']]) if analysis['functions'] else 'None'}",
|
|
394
|
-
f"- Classes: {', '.join([c['name'] for c in analysis['classes']]) if analysis['classes'] else 'None'}",
|
|
395
|
-
f"- Imports: {', '.join(analysis['imports'][:10]) if analysis['imports'] else 'None'}",
|
|
396
|
-
"",
|
|
397
|
-
f"Use {analysis['test_framework']} framework.",
|
|
398
|
-
"",
|
|
399
|
-
"Source code:",
|
|
400
|
-
"```python",
|
|
401
|
-
code[:5000], # Limit code size
|
|
402
|
-
"```",
|
|
403
|
-
"",
|
|
404
|
-
]
|
|
405
|
-
|
|
406
|
-
if test_path:
|
|
407
|
-
prompt_parts.append(f"Write tests to: {test_path}")
|
|
408
|
-
prompt_parts.append("")
|
|
409
|
-
|
|
410
|
-
if context:
|
|
411
|
-
prompt_parts.append("Context:")
|
|
412
|
-
prompt_parts.append(context)
|
|
413
|
-
prompt_parts.append("")
|
|
414
|
-
|
|
415
|
-
if expert_guidance:
|
|
416
|
-
prompt_parts.append("Expert Guidance:")
|
|
417
|
-
prompt_parts.append(expert_guidance)
|
|
418
|
-
prompt_parts.append("")
|
|
419
|
-
|
|
420
|
-
prompt_parts.extend(
|
|
421
|
-
[
|
|
422
|
-
"Requirements:",
|
|
423
|
-
"- Test all public functions and methods",
|
|
424
|
-
"- Include edge cases and error handling",
|
|
425
|
-
"- Use descriptive test names",
|
|
426
|
-
"- Include docstrings for test functions",
|
|
427
|
-
"- Mock external dependencies",
|
|
428
|
-
"- Ensure 80%+ coverage",
|
|
429
|
-
"",
|
|
430
|
-
"Generate only the test code (no explanations):",
|
|
431
|
-
]
|
|
432
|
-
)
|
|
433
|
-
|
|
434
|
-
return "\n".join(prompt_parts)
|
|
435
|
-
|
|
436
|
-
def _build_integration_test_prompt(
|
|
437
|
-
self,
|
|
438
|
-
code: str,
|
|
439
|
-
test_path: Path | None,
|
|
440
|
-
context: str | None,
|
|
441
|
-
expert_guidance: str | None = None,
|
|
442
|
-
) -> str:
|
|
443
|
-
"""Build prompt for integration test generation."""
|
|
444
|
-
prompt_parts = [
|
|
445
|
-
"Generate comprehensive integration tests for the following Python code.",
|
|
446
|
-
"",
|
|
447
|
-
"The code consists of multiple modules that work together.",
|
|
448
|
-
"",
|
|
449
|
-
"Source code:",
|
|
450
|
-
"```python",
|
|
451
|
-
code[:8000], # Larger limit for integration tests
|
|
452
|
-
"```",
|
|
453
|
-
"",
|
|
454
|
-
]
|
|
455
|
-
|
|
456
|
-
if test_path:
|
|
457
|
-
prompt_parts.append(f"Write tests to: {test_path}")
|
|
458
|
-
prompt_parts.append("")
|
|
459
|
-
|
|
460
|
-
if context:
|
|
461
|
-
prompt_parts.append("Context:")
|
|
462
|
-
prompt_parts.append(context)
|
|
463
|
-
prompt_parts.append("")
|
|
464
|
-
|
|
465
|
-
if expert_guidance:
|
|
466
|
-
prompt_parts.append("Expert Guidance:")
|
|
467
|
-
prompt_parts.append(expert_guidance)
|
|
468
|
-
prompt_parts.append("")
|
|
469
|
-
|
|
470
|
-
prompt_parts.extend(
|
|
471
|
-
[
|
|
472
|
-
"Requirements:",
|
|
473
|
-
"- Test interactions between modules",
|
|
474
|
-
"- Test end-to-end workflows",
|
|
475
|
-
"- Include setup and teardown",
|
|
476
|
-
"- Use descriptive test names",
|
|
477
|
-
"- Mock external services",
|
|
478
|
-
"",
|
|
479
|
-
"Generate only the test code (no explanations):",
|
|
480
|
-
]
|
|
481
|
-
)
|
|
482
|
-
|
|
483
|
-
return "\n".join(prompt_parts)
|
|
484
|
-
|
|
485
|
-
def _build_e2e_test_prompt(
|
|
486
|
-
self,
|
|
487
|
-
project_root: Path,
|
|
488
|
-
e2e_framework: str,
|
|
489
|
-
project_analysis: dict[str, Any],
|
|
490
|
-
test_path: Path | None,
|
|
491
|
-
context: str | None,
|
|
492
|
-
expert_guidance: str | None = None,
|
|
493
|
-
) -> str:
|
|
494
|
-
"""Build prompt for E2E test generation."""
|
|
495
|
-
prompt_parts = [
|
|
496
|
-
f"Generate comprehensive end-to-end (E2E) tests for this project using {e2e_framework}.",
|
|
497
|
-
"",
|
|
498
|
-
"Project structure:",
|
|
499
|
-
]
|
|
500
|
-
|
|
501
|
-
if project_analysis["entry_points"]:
|
|
502
|
-
prompt_parts.append(
|
|
503
|
-
f"- Entry points: {', '.join(project_analysis['entry_points'][:5])}"
|
|
504
|
-
)
|
|
505
|
-
if project_analysis["main_modules"]:
|
|
506
|
-
prompt_parts.append(
|
|
507
|
-
f"- Main modules: {', '.join(project_analysis['main_modules'][:10])}"
|
|
508
|
-
)
|
|
509
|
-
if project_analysis["api_endpoints"]:
|
|
510
|
-
prompt_parts.append(
|
|
511
|
-
f"- API endpoints: {', '.join(project_analysis['api_endpoints'])}"
|
|
512
|
-
)
|
|
513
|
-
|
|
514
|
-
prompt_parts.append("")
|
|
515
|
-
|
|
516
|
-
if test_path:
|
|
517
|
-
prompt_parts.append(f"Write tests to: {test_path}")
|
|
518
|
-
prompt_parts.append("")
|
|
519
|
-
|
|
520
|
-
if context:
|
|
521
|
-
prompt_parts.append("Context:")
|
|
522
|
-
prompt_parts.append(context)
|
|
523
|
-
prompt_parts.append("")
|
|
524
|
-
|
|
525
|
-
if expert_guidance:
|
|
526
|
-
prompt_parts.append("Expert Guidance:")
|
|
527
|
-
prompt_parts.append(expert_guidance)
|
|
528
|
-
prompt_parts.append("")
|
|
529
|
-
|
|
530
|
-
# Check for Playwright MCP availability (for Playwright-based frameworks)
|
|
531
|
-
playwright_mcp_available = False
|
|
532
|
-
if e2e_framework in ("playwright", "pytest-playwright"):
|
|
533
|
-
try:
|
|
534
|
-
from ...core.init_project import detect_mcp_servers
|
|
535
|
-
mcp_status = detect_mcp_servers(project_root)
|
|
536
|
-
playwright_mcp_available = any(
|
|
537
|
-
s.get("id") == "Playwright" and s.get("status") == "installed"
|
|
538
|
-
for s in mcp_status.get("detected_servers", [])
|
|
539
|
-
)
|
|
540
|
-
except Exception:
|
|
541
|
-
pass # If detection fails, assume not available
|
|
542
|
-
|
|
543
|
-
# Framework-specific requirements
|
|
544
|
-
framework_requirements = {
|
|
545
|
-
"playwright": [
|
|
546
|
-
"- Use Playwright's page object model pattern",
|
|
547
|
-
"- Test user workflows and interactions",
|
|
548
|
-
"- Include browser automation (navigation, clicks, form fills)",
|
|
549
|
-
"- Test across different browsers if configured",
|
|
550
|
-
"- Include accessibility testing: Use page.snapshot() to get accessibility tree and verify WCAG 2.2 compliance",
|
|
551
|
-
"- Include performance testing: Collect Core Web Vitals (LCP, FID, CLS) and verify thresholds",
|
|
552
|
-
"- Use browser_network_requests to analyze network performance",
|
|
553
|
-
"- Use browser_console_messages to check for errors and warnings",
|
|
554
|
-
"- Network Mocking: Use page.route() to intercept and mock API requests for reliable offline testing",
|
|
555
|
-
"- Trace Generation: Enable context.tracing.start() before test, context.tracing.stop() on failure with path",
|
|
556
|
-
"- Error Reporting: Include trace viewer command (npx playwright show-trace <path>) in failure messages",
|
|
557
|
-
"- Visual Regression: Capture screenshots and compare with baselines using visual regression testing",
|
|
558
|
-
"- Multi-Tab: Test scenarios requiring multiple tabs (OAuth flows, popups) using browser_tabs or context.newPage()",
|
|
559
|
-
"- Device Emulation: Test responsive designs using context.emulate() with device profiles (iPhone, iPad, Desktop)",
|
|
560
|
-
] + (["- Note: Playwright MCP server is available - use browser_snapshot, browser_network_requests, browser_console_messages tools"] if playwright_mcp_available else []),
|
|
561
|
-
"pytest-playwright": [
|
|
562
|
-
"- Use pytest fixtures for setup/teardown",
|
|
563
|
-
"- Use Playwright's async API",
|
|
564
|
-
"- Test user workflows end-to-end",
|
|
565
|
-
"- Include proper async/await patterns",
|
|
566
|
-
"- Include accessibility testing: Use page.snapshot() to get accessibility tree and verify WCAG 2.2 compliance",
|
|
567
|
-
"- Include performance testing: Collect Core Web Vitals (LCP, FID, CLS) and verify thresholds",
|
|
568
|
-
"- Use page.request.response() to analyze network performance",
|
|
569
|
-
"- Use page.on('console') to check for errors and warnings",
|
|
570
|
-
"- Network Mocking: Use page.route() to intercept and mock API requests in async context",
|
|
571
|
-
"- Trace Generation: Use context.tracing.start() in fixture, context.tracing.stop() in teardown or on failure",
|
|
572
|
-
"- Error Reporting: Include trace viewer command in pytest failure output",
|
|
573
|
-
"- Visual Regression: Use pytest fixtures for screenshot comparison and baseline management",
|
|
574
|
-
"- Multi-Tab: Test multi-tab scenarios in async context using await context.newPage()",
|
|
575
|
-
"- Device Emulation: Use pytest fixtures with device profiles for responsive design testing",
|
|
576
|
-
] + (["- Note: Playwright MCP server is available - use browser_snapshot, browser_network_requests, browser_console_messages tools"] if playwright_mcp_available else []),
|
|
577
|
-
"selenium": [
|
|
578
|
-
"- Use Selenium WebDriver patterns",
|
|
579
|
-
"- Test user interactions and workflows",
|
|
580
|
-
"- Include proper wait strategies",
|
|
581
|
-
"- Test across different browsers",
|
|
582
|
-
"- Include basic accessibility checks where possible",
|
|
583
|
-
],
|
|
584
|
-
"cypress": [
|
|
585
|
-
"- Use Cypress commands and patterns",
|
|
586
|
-
"- Test user journeys end-to-end",
|
|
587
|
-
"- Include proper assertions",
|
|
588
|
-
"- Use Cypress best practices",
|
|
589
|
-
"- Include accessibility testing using cypress-axe if available",
|
|
590
|
-
],
|
|
591
|
-
}
|
|
592
|
-
|
|
593
|
-
requirements = framework_requirements.get(
|
|
594
|
-
e2e_framework,
|
|
595
|
-
[
|
|
596
|
-
"- Test complete user workflows",
|
|
597
|
-
"- Include setup and teardown",
|
|
598
|
-
"- Test critical paths",
|
|
599
|
-
],
|
|
600
|
-
)
|
|
601
|
-
|
|
602
|
-
# Add accessibility and performance requirements for Playwright-based tests
|
|
603
|
-
additional_requirements = []
|
|
604
|
-
if e2e_framework in ("playwright", "pytest-playwright"):
|
|
605
|
-
additional_requirements.extend([
|
|
606
|
-
"- Accessibility: Verify WCAG 2.2 Level AA compliance (alt text, heading structure, form labels, keyboard navigation)",
|
|
607
|
-
"- Performance: Assert Core Web Vitals meet thresholds (LCP < 2.5s, FID < 100ms, CLS < 0.1)",
|
|
608
|
-
"- Network: Verify no failed requests, check request count and response times",
|
|
609
|
-
"- Console: Check for JavaScript errors and warnings",
|
|
610
|
-
"- Network Mocking: Use page.route() to mock API calls for offline testing and faster execution",
|
|
611
|
-
"- Trace Generation: Enable tracing with context.tracing.start() and save trace on failure for debugging",
|
|
612
|
-
"- Error Handling: On test failure, save trace file and include trace viewer command in error message",
|
|
613
|
-
"- Visual Regression: Use screenshot comparison to detect UI changes (create baselines, compare on test runs)",
|
|
614
|
-
"- Multi-Tab Testing: Test multi-tab scenarios using page.context().newPage() or browser_tabs MCP tool",
|
|
615
|
-
"- Device Emulation: Test responsive designs using device profiles (mobile, tablet, desktop)",
|
|
616
|
-
])
|
|
617
|
-
|
|
618
|
-
prompt_parts.extend(
|
|
619
|
-
[
|
|
620
|
-
"Requirements:",
|
|
621
|
-
*requirements,
|
|
622
|
-
*additional_requirements,
|
|
623
|
-
"- Test critical user journeys",
|
|
624
|
-
"- Include error scenarios",
|
|
625
|
-
"- Use descriptive test names",
|
|
626
|
-
"- Ensure tests are deterministic and repeatable",
|
|
627
|
-
"",
|
|
628
|
-
"Generate only the test code (no explanations):",
|
|
629
|
-
]
|
|
630
|
-
)
|
|
631
|
-
|
|
632
|
-
return "\n".join(prompt_parts)
|
|
1
|
+
"""
|
|
2
|
+
Test Generator - Prepares test generation instructions for Cursor Skills
|
|
3
|
+
|
|
4
|
+
Phase 2.1: Enhanced with coverage analysis and language-aware test generation
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import ast
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
from ...core.instructions import TestGenerationInstruction
|
|
12
|
+
from ...core.language_detector import Language, LanguageDetector
|
|
13
|
+
from .coverage_analyzer import CoverageAnalyzer, CoverageReport
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class TestGenerator:
|
|
17
|
+
"""
|
|
18
|
+
Prepares test generation instructions for Cursor Skills execution.
|
|
19
|
+
|
|
20
|
+
Enhanced with:
|
|
21
|
+
- Language-aware test framework detection
|
|
22
|
+
- Async coverage analysis
|
|
23
|
+
- Coverage measurement for Python (pytest) and TypeScript/React (jest/vitest)
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(self):
|
|
27
|
+
"""Initialize test generator."""
|
|
28
|
+
self.language_detector = LanguageDetector()
|
|
29
|
+
self.coverage_analyzer = CoverageAnalyzer()
|
|
30
|
+
|
|
31
|
+
def prepare_unit_tests(
|
|
32
|
+
self,
|
|
33
|
+
code_path: Path,
|
|
34
|
+
test_path: Path | None = None,
|
|
35
|
+
context: str | None = None,
|
|
36
|
+
expert_guidance: str | None = None,
|
|
37
|
+
focus: str | None = None,
|
|
38
|
+
) -> TestGenerationInstruction:
|
|
39
|
+
"""
|
|
40
|
+
Prepare unit test generation instruction for Cursor Skills.
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
code_path: Path to the source code file
|
|
44
|
+
test_path: Optional path where test will be written
|
|
45
|
+
context: Optional context (existing tests, patterns, etc.)
|
|
46
|
+
expert_guidance: Optional expert guidance for test generation
|
|
47
|
+
|
|
48
|
+
Returns:
|
|
49
|
+
TestGenerationInstruction object for Cursor Skills execution
|
|
50
|
+
"""
|
|
51
|
+
# Read source code
|
|
52
|
+
code = code_path.read_text(encoding="utf-8")
|
|
53
|
+
|
|
54
|
+
# Detect language
|
|
55
|
+
detection_result = self.language_detector.detect_language(code_path, code)
|
|
56
|
+
language = detection_result.language
|
|
57
|
+
|
|
58
|
+
# Analyze code structure
|
|
59
|
+
analysis = self._analyze_code(code, code_path)
|
|
60
|
+
|
|
61
|
+
# Detect test framework based on language
|
|
62
|
+
test_framework = self._detect_test_framework_for_language(language, code)
|
|
63
|
+
|
|
64
|
+
# Build coverage requirements with focus areas if provided
|
|
65
|
+
coverage_requirements = {
|
|
66
|
+
"target_coverage": 80.0,
|
|
67
|
+
"test_types": ["unit"],
|
|
68
|
+
"context": context,
|
|
69
|
+
"expert_guidance": expert_guidance,
|
|
70
|
+
"language": language.value,
|
|
71
|
+
}
|
|
72
|
+
if focus:
|
|
73
|
+
focus_areas = [area.strip() for area in focus.split(",")]
|
|
74
|
+
coverage_requirements["focus_areas"] = focus_areas
|
|
75
|
+
|
|
76
|
+
return TestGenerationInstruction(
|
|
77
|
+
target_file=str(test_path) if test_path else str(code_path),
|
|
78
|
+
test_framework=test_framework,
|
|
79
|
+
coverage_requirements=coverage_requirements,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
async def measure_coverage(
|
|
83
|
+
self,
|
|
84
|
+
file_path: Path,
|
|
85
|
+
test_file_path: Path | None = None,
|
|
86
|
+
project_root: Path | None = None,
|
|
87
|
+
) -> CoverageReport:
|
|
88
|
+
"""
|
|
89
|
+
Measure test coverage for a file using language-specific tools.
|
|
90
|
+
|
|
91
|
+
Phase 2.1: Coverage Analysis Integration
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
file_path: Path to the source file
|
|
95
|
+
test_file_path: Optional path to test file
|
|
96
|
+
project_root: Optional project root directory
|
|
97
|
+
|
|
98
|
+
Returns:
|
|
99
|
+
CoverageReport with coverage percentage and metrics
|
|
100
|
+
"""
|
|
101
|
+
# Detect language
|
|
102
|
+
code = file_path.read_text(encoding="utf-8") if file_path.exists() else ""
|
|
103
|
+
detection_result = self.language_detector.detect_language(file_path, code)
|
|
104
|
+
language = detection_result.language
|
|
105
|
+
|
|
106
|
+
# Measure coverage using language-specific analyzer
|
|
107
|
+
return await self.coverage_analyzer.measure_coverage(
|
|
108
|
+
file_path, language, test_file_path, project_root
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
def _detect_test_framework_for_language(
|
|
112
|
+
self, language: Language, code: str
|
|
113
|
+
) -> str:
|
|
114
|
+
"""
|
|
115
|
+
Detect test framework based on language.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
language: Detected language
|
|
119
|
+
code: Source code content
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
Test framework name (pytest, jest, vitest, etc.)
|
|
123
|
+
"""
|
|
124
|
+
if language == Language.PYTHON:
|
|
125
|
+
# Check code for framework hints
|
|
126
|
+
if "import pytest" in code or "from pytest" in code:
|
|
127
|
+
return "pytest"
|
|
128
|
+
elif "import unittest" in code or "from unittest" in code:
|
|
129
|
+
return "unittest"
|
|
130
|
+
return "pytest" # Default for Python
|
|
131
|
+
|
|
132
|
+
elif language in [Language.TYPESCRIPT, Language.JAVASCRIPT, Language.REACT]:
|
|
133
|
+
# Check package.json or code for framework
|
|
134
|
+
# This is a basic check - full detection is in CoverageAnalyzer
|
|
135
|
+
if "vitest" in code.lower():
|
|
136
|
+
return "vitest"
|
|
137
|
+
return "jest" # Default for TypeScript/JavaScript
|
|
138
|
+
|
|
139
|
+
return "pytest" # Fallback default
|
|
140
|
+
|
|
141
|
+
def prepare_integration_tests(
|
|
142
|
+
self,
|
|
143
|
+
file_paths: list[Path],
|
|
144
|
+
test_path: Path | None = None,
|
|
145
|
+
context: str | None = None,
|
|
146
|
+
expert_guidance: str | None = None,
|
|
147
|
+
focus: str | None = None,
|
|
148
|
+
) -> TestGenerationInstruction:
|
|
149
|
+
"""
|
|
150
|
+
Prepare integration test generation instruction for Cursor Skills.
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
file_paths: List of source code file paths
|
|
154
|
+
test_path: Optional path where test will be written
|
|
155
|
+
context: Optional context
|
|
156
|
+
expert_guidance: Optional expert guidance
|
|
157
|
+
focus: Optional comma-separated focus areas
|
|
158
|
+
|
|
159
|
+
Returns:
|
|
160
|
+
TestGenerationInstruction object for Cursor Skills execution
|
|
161
|
+
"""
|
|
162
|
+
# Use first file path or test_path as target
|
|
163
|
+
target_file = str(test_path) if test_path else str(file_paths[0]) if file_paths else ""
|
|
164
|
+
|
|
165
|
+
coverage_requirements = {
|
|
166
|
+
"target_coverage": 80.0,
|
|
167
|
+
"test_types": ["integration"],
|
|
168
|
+
"file_paths": [str(p) for p in file_paths],
|
|
169
|
+
"context": context,
|
|
170
|
+
"expert_guidance": expert_guidance,
|
|
171
|
+
}
|
|
172
|
+
if focus:
|
|
173
|
+
focus_areas = [area.strip() for area in focus.split(",")]
|
|
174
|
+
coverage_requirements["focus_areas"] = focus_areas
|
|
175
|
+
|
|
176
|
+
return TestGenerationInstruction(
|
|
177
|
+
target_file=target_file,
|
|
178
|
+
test_framework="pytest",
|
|
179
|
+
coverage_requirements=coverage_requirements,
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
def prepare_e2e_tests(
|
|
183
|
+
self,
|
|
184
|
+
project_root: Path,
|
|
185
|
+
test_path: Path | None = None,
|
|
186
|
+
context: str | None = None,
|
|
187
|
+
expert_guidance: str | None = None,
|
|
188
|
+
) -> TestGenerationInstruction | None:
|
|
189
|
+
"""
|
|
190
|
+
Prepare end-to-end (E2E) test generation instruction for Cursor Skills.
|
|
191
|
+
|
|
192
|
+
Args:
|
|
193
|
+
project_root: Root directory of the project
|
|
194
|
+
test_path: Optional path where test will be written
|
|
195
|
+
context: Optional context
|
|
196
|
+
expert_guidance: Optional expert guidance
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
TestGenerationInstruction object for Cursor Skills execution, or None if E2E framework not detected
|
|
200
|
+
"""
|
|
201
|
+
# Detect E2E framework
|
|
202
|
+
e2e_framework = self._detect_e2e_framework(project_root)
|
|
203
|
+
if not e2e_framework:
|
|
204
|
+
return None
|
|
205
|
+
|
|
206
|
+
# Analyze project structure
|
|
207
|
+
project_analysis = self._analyze_project_structure(project_root)
|
|
208
|
+
|
|
209
|
+
target_file = str(test_path) if test_path else str(project_root)
|
|
210
|
+
|
|
211
|
+
coverage_requirements = {
|
|
212
|
+
"target_coverage": 80.0,
|
|
213
|
+
"test_types": ["e2e"],
|
|
214
|
+
"e2e_framework": e2e_framework,
|
|
215
|
+
"project_analysis": project_analysis,
|
|
216
|
+
"context": context,
|
|
217
|
+
"expert_guidance": expert_guidance,
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return TestGenerationInstruction(
|
|
221
|
+
target_file=target_file,
|
|
222
|
+
test_framework=e2e_framework,
|
|
223
|
+
coverage_requirements=coverage_requirements,
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
def _detect_e2e_framework(self, project_root: Path) -> str | None:
|
|
227
|
+
"""
|
|
228
|
+
Detect E2E testing framework in the project.
|
|
229
|
+
|
|
230
|
+
Returns:
|
|
231
|
+
Framework name ("playwright", "selenium", "cypress", "pytest-playwright") or None
|
|
232
|
+
"""
|
|
233
|
+
project_root = Path(project_root)
|
|
234
|
+
|
|
235
|
+
# Check for Playwright
|
|
236
|
+
playwright_config = project_root / "playwright.config.js"
|
|
237
|
+
playwright_config_ts = project_root / "playwright.config.ts"
|
|
238
|
+
playwright_pyproject = project_root / "pyproject.toml"
|
|
239
|
+
if (
|
|
240
|
+
playwright_config.exists()
|
|
241
|
+
or playwright_config_ts.exists()
|
|
242
|
+
or (playwright_pyproject.exists() and "playwright" in playwright_pyproject.read_text())
|
|
243
|
+
):
|
|
244
|
+
return "playwright"
|
|
245
|
+
|
|
246
|
+
# Check for pytest-playwright
|
|
247
|
+
if (project_root / "pytest.ini").exists():
|
|
248
|
+
pytest_ini_content = (project_root / "pytest.ini").read_text()
|
|
249
|
+
if "playwright" in pytest_ini_content.lower():
|
|
250
|
+
return "pytest-playwright"
|
|
251
|
+
|
|
252
|
+
# Check requirements.txt or pyproject.toml for pytest-playwright
|
|
253
|
+
for req_file in [project_root / "requirements.txt", project_root / "pyproject.toml"]:
|
|
254
|
+
if req_file.exists():
|
|
255
|
+
content = req_file.read_text().lower()
|
|
256
|
+
if "pytest-playwright" in content or "playwright" in content:
|
|
257
|
+
return "pytest-playwright"
|
|
258
|
+
|
|
259
|
+
# Check for Selenium
|
|
260
|
+
selenium_config = project_root / "selenium.config.js"
|
|
261
|
+
for req_file in [project_root / "requirements.txt", project_root / "pyproject.toml"]:
|
|
262
|
+
if req_file.exists():
|
|
263
|
+
content = req_file.read_text().lower()
|
|
264
|
+
if "selenium" in content:
|
|
265
|
+
return "selenium"
|
|
266
|
+
if selenium_config.exists():
|
|
267
|
+
return "selenium"
|
|
268
|
+
|
|
269
|
+
# Check for Cypress (JavaScript/TypeScript projects)
|
|
270
|
+
cypress_config = project_root / "cypress.config.js"
|
|
271
|
+
cypress_config_ts = project_root / "cypress.config.ts"
|
|
272
|
+
if cypress_config.exists() or cypress_config_ts.exists():
|
|
273
|
+
return "cypress"
|
|
274
|
+
|
|
275
|
+
return None
|
|
276
|
+
|
|
277
|
+
def _analyze_project_structure(self, project_root: Path) -> dict[str, Any]:
|
|
278
|
+
"""Analyze project structure for E2E test generation."""
|
|
279
|
+
project_root = Path(project_root)
|
|
280
|
+
analysis: dict[str, Any] = {
|
|
281
|
+
"entry_points": [],
|
|
282
|
+
"main_modules": [],
|
|
283
|
+
"api_endpoints": [],
|
|
284
|
+
"test_directories": [],
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
# Find entry points (main.py, app.py, __main__.py, etc.)
|
|
288
|
+
entry_patterns = ["main.py", "app.py", "__main__.py", "server.py", "run.py"]
|
|
289
|
+
for pattern in entry_patterns:
|
|
290
|
+
for entry_file in project_root.rglob(pattern):
|
|
291
|
+
if "test" not in str(entry_file):
|
|
292
|
+
analysis["entry_points"].append(str(entry_file.relative_to(project_root)))
|
|
293
|
+
|
|
294
|
+
# Find main modules (directories with __init__.py)
|
|
295
|
+
for init_file in project_root.rglob("__init__.py"):
|
|
296
|
+
module_dir = init_file.parent
|
|
297
|
+
if "test" not in str(module_dir):
|
|
298
|
+
rel_path = module_dir.relative_to(project_root)
|
|
299
|
+
if str(rel_path) != ".":
|
|
300
|
+
analysis["main_modules"].append(str(rel_path))
|
|
301
|
+
|
|
302
|
+
# Find API endpoints (common patterns)
|
|
303
|
+
api_patterns = ["api", "routes", "endpoints", "controllers"]
|
|
304
|
+
for pattern in api_patterns:
|
|
305
|
+
api_dir = project_root / pattern
|
|
306
|
+
if api_dir.exists() and api_dir.is_dir():
|
|
307
|
+
analysis["api_endpoints"].append(pattern)
|
|
308
|
+
|
|
309
|
+
# Find existing test directories
|
|
310
|
+
test_dirs = ["tests", "test", "tests/e2e", "tests/integration"]
|
|
311
|
+
for test_dir in test_dirs:
|
|
312
|
+
test_path = project_root / test_dir
|
|
313
|
+
if test_path.exists() and test_path.is_dir():
|
|
314
|
+
analysis["test_directories"].append(test_dir)
|
|
315
|
+
|
|
316
|
+
return analysis
|
|
317
|
+
|
|
318
|
+
def _analyze_code(self, code: str, file_path: Path) -> dict[str, Any]:
|
|
319
|
+
"""Analyze code structure to extract functions, classes, etc."""
|
|
320
|
+
functions: list[dict[str, Any]] = []
|
|
321
|
+
classes: list[dict[str, Any]] = []
|
|
322
|
+
imports: list[str] = []
|
|
323
|
+
|
|
324
|
+
analysis: dict[str, Any] = {
|
|
325
|
+
"file_name": file_path.name,
|
|
326
|
+
"functions": functions,
|
|
327
|
+
"classes": classes,
|
|
328
|
+
"imports": imports,
|
|
329
|
+
"test_framework": self._detect_test_framework(code),
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
try:
|
|
333
|
+
tree = ast.parse(code)
|
|
334
|
+
|
|
335
|
+
for node in ast.walk(tree):
|
|
336
|
+
if isinstance(node, ast.FunctionDef):
|
|
337
|
+
functions.append(
|
|
338
|
+
{
|
|
339
|
+
"name": node.name,
|
|
340
|
+
"args": [arg.arg for arg in node.args.args],
|
|
341
|
+
"decorators": [
|
|
342
|
+
ast.unparse(d) if hasattr(ast, "unparse") else str(d)
|
|
343
|
+
for d in node.decorator_list
|
|
344
|
+
],
|
|
345
|
+
}
|
|
346
|
+
)
|
|
347
|
+
elif isinstance(node, ast.ClassDef):
|
|
348
|
+
methods = [
|
|
349
|
+
n.name for n in node.body if isinstance(n, ast.FunctionDef)
|
|
350
|
+
]
|
|
351
|
+
classes.append({"name": node.name, "methods": methods})
|
|
352
|
+
elif isinstance(node, (ast.Import, ast.ImportFrom)):
|
|
353
|
+
if isinstance(node, ast.Import):
|
|
354
|
+
imports.extend([alias.name for alias in node.names])
|
|
355
|
+
else:
|
|
356
|
+
imports.append(node.module or "")
|
|
357
|
+
except SyntaxError:
|
|
358
|
+
# If code has syntax errors, return basic analysis
|
|
359
|
+
pass
|
|
360
|
+
|
|
361
|
+
return analysis
|
|
362
|
+
|
|
363
|
+
def _detect_test_framework(self, code: str) -> str:
|
|
364
|
+
"""
|
|
365
|
+
Detect which test framework is being used (legacy method).
|
|
366
|
+
|
|
367
|
+
Note: Use _detect_test_framework_for_language() for language-aware detection.
|
|
368
|
+
"""
|
|
369
|
+
if "import pytest" in code or "from pytest" in code:
|
|
370
|
+
return "pytest"
|
|
371
|
+
elif "import unittest" in code or "from unittest" in code:
|
|
372
|
+
return "unittest"
|
|
373
|
+
elif "import nose" in code or "from nose" in code:
|
|
374
|
+
return "nose"
|
|
375
|
+
else:
|
|
376
|
+
return "pytest" # Default
|
|
377
|
+
|
|
378
|
+
def _build_unit_test_prompt(
|
|
379
|
+
self,
|
|
380
|
+
code: str,
|
|
381
|
+
analysis: dict[str, Any],
|
|
382
|
+
test_path: Path | None,
|
|
383
|
+
context: str | None,
|
|
384
|
+
expert_guidance: str | None = None,
|
|
385
|
+
) -> str:
|
|
386
|
+
"""Build prompt for unit test generation."""
|
|
387
|
+
prompt_parts = [
|
|
388
|
+
"Generate comprehensive unit tests for the following Python code.",
|
|
389
|
+
"",
|
|
390
|
+
f"Source file: {analysis['file_name']}",
|
|
391
|
+
"",
|
|
392
|
+
"Code structure:",
|
|
393
|
+
f"- Functions: {', '.join([f['name'] for f in analysis['functions']]) if analysis['functions'] else 'None'}",
|
|
394
|
+
f"- Classes: {', '.join([c['name'] for c in analysis['classes']]) if analysis['classes'] else 'None'}",
|
|
395
|
+
f"- Imports: {', '.join(analysis['imports'][:10]) if analysis['imports'] else 'None'}",
|
|
396
|
+
"",
|
|
397
|
+
f"Use {analysis['test_framework']} framework.",
|
|
398
|
+
"",
|
|
399
|
+
"Source code:",
|
|
400
|
+
"```python",
|
|
401
|
+
code[:5000], # Limit code size
|
|
402
|
+
"```",
|
|
403
|
+
"",
|
|
404
|
+
]
|
|
405
|
+
|
|
406
|
+
if test_path:
|
|
407
|
+
prompt_parts.append(f"Write tests to: {test_path}")
|
|
408
|
+
prompt_parts.append("")
|
|
409
|
+
|
|
410
|
+
if context:
|
|
411
|
+
prompt_parts.append("Context:")
|
|
412
|
+
prompt_parts.append(context)
|
|
413
|
+
prompt_parts.append("")
|
|
414
|
+
|
|
415
|
+
if expert_guidance:
|
|
416
|
+
prompt_parts.append("Expert Guidance:")
|
|
417
|
+
prompt_parts.append(expert_guidance)
|
|
418
|
+
prompt_parts.append("")
|
|
419
|
+
|
|
420
|
+
prompt_parts.extend(
|
|
421
|
+
[
|
|
422
|
+
"Requirements:",
|
|
423
|
+
"- Test all public functions and methods",
|
|
424
|
+
"- Include edge cases and error handling",
|
|
425
|
+
"- Use descriptive test names",
|
|
426
|
+
"- Include docstrings for test functions",
|
|
427
|
+
"- Mock external dependencies",
|
|
428
|
+
"- Ensure 80%+ coverage",
|
|
429
|
+
"",
|
|
430
|
+
"Generate only the test code (no explanations):",
|
|
431
|
+
]
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
return "\n".join(prompt_parts)
|
|
435
|
+
|
|
436
|
+
def _build_integration_test_prompt(
|
|
437
|
+
self,
|
|
438
|
+
code: str,
|
|
439
|
+
test_path: Path | None,
|
|
440
|
+
context: str | None,
|
|
441
|
+
expert_guidance: str | None = None,
|
|
442
|
+
) -> str:
|
|
443
|
+
"""Build prompt for integration test generation."""
|
|
444
|
+
prompt_parts = [
|
|
445
|
+
"Generate comprehensive integration tests for the following Python code.",
|
|
446
|
+
"",
|
|
447
|
+
"The code consists of multiple modules that work together.",
|
|
448
|
+
"",
|
|
449
|
+
"Source code:",
|
|
450
|
+
"```python",
|
|
451
|
+
code[:8000], # Larger limit for integration tests
|
|
452
|
+
"```",
|
|
453
|
+
"",
|
|
454
|
+
]
|
|
455
|
+
|
|
456
|
+
if test_path:
|
|
457
|
+
prompt_parts.append(f"Write tests to: {test_path}")
|
|
458
|
+
prompt_parts.append("")
|
|
459
|
+
|
|
460
|
+
if context:
|
|
461
|
+
prompt_parts.append("Context:")
|
|
462
|
+
prompt_parts.append(context)
|
|
463
|
+
prompt_parts.append("")
|
|
464
|
+
|
|
465
|
+
if expert_guidance:
|
|
466
|
+
prompt_parts.append("Expert Guidance:")
|
|
467
|
+
prompt_parts.append(expert_guidance)
|
|
468
|
+
prompt_parts.append("")
|
|
469
|
+
|
|
470
|
+
prompt_parts.extend(
|
|
471
|
+
[
|
|
472
|
+
"Requirements:",
|
|
473
|
+
"- Test interactions between modules",
|
|
474
|
+
"- Test end-to-end workflows",
|
|
475
|
+
"- Include setup and teardown",
|
|
476
|
+
"- Use descriptive test names",
|
|
477
|
+
"- Mock external services",
|
|
478
|
+
"",
|
|
479
|
+
"Generate only the test code (no explanations):",
|
|
480
|
+
]
|
|
481
|
+
)
|
|
482
|
+
|
|
483
|
+
return "\n".join(prompt_parts)
|
|
484
|
+
|
|
485
|
+
def _build_e2e_test_prompt(
|
|
486
|
+
self,
|
|
487
|
+
project_root: Path,
|
|
488
|
+
e2e_framework: str,
|
|
489
|
+
project_analysis: dict[str, Any],
|
|
490
|
+
test_path: Path | None,
|
|
491
|
+
context: str | None,
|
|
492
|
+
expert_guidance: str | None = None,
|
|
493
|
+
) -> str:
|
|
494
|
+
"""Build prompt for E2E test generation."""
|
|
495
|
+
prompt_parts = [
|
|
496
|
+
f"Generate comprehensive end-to-end (E2E) tests for this project using {e2e_framework}.",
|
|
497
|
+
"",
|
|
498
|
+
"Project structure:",
|
|
499
|
+
]
|
|
500
|
+
|
|
501
|
+
if project_analysis["entry_points"]:
|
|
502
|
+
prompt_parts.append(
|
|
503
|
+
f"- Entry points: {', '.join(project_analysis['entry_points'][:5])}"
|
|
504
|
+
)
|
|
505
|
+
if project_analysis["main_modules"]:
|
|
506
|
+
prompt_parts.append(
|
|
507
|
+
f"- Main modules: {', '.join(project_analysis['main_modules'][:10])}"
|
|
508
|
+
)
|
|
509
|
+
if project_analysis["api_endpoints"]:
|
|
510
|
+
prompt_parts.append(
|
|
511
|
+
f"- API endpoints: {', '.join(project_analysis['api_endpoints'])}"
|
|
512
|
+
)
|
|
513
|
+
|
|
514
|
+
prompt_parts.append("")
|
|
515
|
+
|
|
516
|
+
if test_path:
|
|
517
|
+
prompt_parts.append(f"Write tests to: {test_path}")
|
|
518
|
+
prompt_parts.append("")
|
|
519
|
+
|
|
520
|
+
if context:
|
|
521
|
+
prompt_parts.append("Context:")
|
|
522
|
+
prompt_parts.append(context)
|
|
523
|
+
prompt_parts.append("")
|
|
524
|
+
|
|
525
|
+
if expert_guidance:
|
|
526
|
+
prompt_parts.append("Expert Guidance:")
|
|
527
|
+
prompt_parts.append(expert_guidance)
|
|
528
|
+
prompt_parts.append("")
|
|
529
|
+
|
|
530
|
+
# Check for Playwright MCP availability (for Playwright-based frameworks)
|
|
531
|
+
playwright_mcp_available = False
|
|
532
|
+
if e2e_framework in ("playwright", "pytest-playwright"):
|
|
533
|
+
try:
|
|
534
|
+
from ...core.init_project import detect_mcp_servers
|
|
535
|
+
mcp_status = detect_mcp_servers(project_root)
|
|
536
|
+
playwright_mcp_available = any(
|
|
537
|
+
s.get("id") == "Playwright" and s.get("status") == "installed"
|
|
538
|
+
for s in mcp_status.get("detected_servers", [])
|
|
539
|
+
)
|
|
540
|
+
except Exception:
|
|
541
|
+
pass # If detection fails, assume not available
|
|
542
|
+
|
|
543
|
+
# Framework-specific requirements
|
|
544
|
+
framework_requirements = {
|
|
545
|
+
"playwright": [
|
|
546
|
+
"- Use Playwright's page object model pattern",
|
|
547
|
+
"- Test user workflows and interactions",
|
|
548
|
+
"- Include browser automation (navigation, clicks, form fills)",
|
|
549
|
+
"- Test across different browsers if configured",
|
|
550
|
+
"- Include accessibility testing: Use page.snapshot() to get accessibility tree and verify WCAG 2.2 compliance",
|
|
551
|
+
"- Include performance testing: Collect Core Web Vitals (LCP, FID, CLS) and verify thresholds",
|
|
552
|
+
"- Use browser_network_requests to analyze network performance",
|
|
553
|
+
"- Use browser_console_messages to check for errors and warnings",
|
|
554
|
+
"- Network Mocking: Use page.route() to intercept and mock API requests for reliable offline testing",
|
|
555
|
+
"- Trace Generation: Enable context.tracing.start() before test, context.tracing.stop() on failure with path",
|
|
556
|
+
"- Error Reporting: Include trace viewer command (npx playwright show-trace <path>) in failure messages",
|
|
557
|
+
"- Visual Regression: Capture screenshots and compare with baselines using visual regression testing",
|
|
558
|
+
"- Multi-Tab: Test scenarios requiring multiple tabs (OAuth flows, popups) using browser_tabs or context.newPage()",
|
|
559
|
+
"- Device Emulation: Test responsive designs using context.emulate() with device profiles (iPhone, iPad, Desktop)",
|
|
560
|
+
] + (["- Note: Playwright MCP server is available - use browser_snapshot, browser_network_requests, browser_console_messages tools"] if playwright_mcp_available else []),
|
|
561
|
+
"pytest-playwright": [
|
|
562
|
+
"- Use pytest fixtures for setup/teardown",
|
|
563
|
+
"- Use Playwright's async API",
|
|
564
|
+
"- Test user workflows end-to-end",
|
|
565
|
+
"- Include proper async/await patterns",
|
|
566
|
+
"- Include accessibility testing: Use page.snapshot() to get accessibility tree and verify WCAG 2.2 compliance",
|
|
567
|
+
"- Include performance testing: Collect Core Web Vitals (LCP, FID, CLS) and verify thresholds",
|
|
568
|
+
"- Use page.request.response() to analyze network performance",
|
|
569
|
+
"- Use page.on('console') to check for errors and warnings",
|
|
570
|
+
"- Network Mocking: Use page.route() to intercept and mock API requests in async context",
|
|
571
|
+
"- Trace Generation: Use context.tracing.start() in fixture, context.tracing.stop() in teardown or on failure",
|
|
572
|
+
"- Error Reporting: Include trace viewer command in pytest failure output",
|
|
573
|
+
"- Visual Regression: Use pytest fixtures for screenshot comparison and baseline management",
|
|
574
|
+
"- Multi-Tab: Test multi-tab scenarios in async context using await context.newPage()",
|
|
575
|
+
"- Device Emulation: Use pytest fixtures with device profiles for responsive design testing",
|
|
576
|
+
] + (["- Note: Playwright MCP server is available - use browser_snapshot, browser_network_requests, browser_console_messages tools"] if playwright_mcp_available else []),
|
|
577
|
+
"selenium": [
|
|
578
|
+
"- Use Selenium WebDriver patterns",
|
|
579
|
+
"- Test user interactions and workflows",
|
|
580
|
+
"- Include proper wait strategies",
|
|
581
|
+
"- Test across different browsers",
|
|
582
|
+
"- Include basic accessibility checks where possible",
|
|
583
|
+
],
|
|
584
|
+
"cypress": [
|
|
585
|
+
"- Use Cypress commands and patterns",
|
|
586
|
+
"- Test user journeys end-to-end",
|
|
587
|
+
"- Include proper assertions",
|
|
588
|
+
"- Use Cypress best practices",
|
|
589
|
+
"- Include accessibility testing using cypress-axe if available",
|
|
590
|
+
],
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
requirements = framework_requirements.get(
|
|
594
|
+
e2e_framework,
|
|
595
|
+
[
|
|
596
|
+
"- Test complete user workflows",
|
|
597
|
+
"- Include setup and teardown",
|
|
598
|
+
"- Test critical paths",
|
|
599
|
+
],
|
|
600
|
+
)
|
|
601
|
+
|
|
602
|
+
# Add accessibility and performance requirements for Playwright-based tests
|
|
603
|
+
additional_requirements = []
|
|
604
|
+
if e2e_framework in ("playwright", "pytest-playwright"):
|
|
605
|
+
additional_requirements.extend([
|
|
606
|
+
"- Accessibility: Verify WCAG 2.2 Level AA compliance (alt text, heading structure, form labels, keyboard navigation)",
|
|
607
|
+
"- Performance: Assert Core Web Vitals meet thresholds (LCP < 2.5s, FID < 100ms, CLS < 0.1)",
|
|
608
|
+
"- Network: Verify no failed requests, check request count and response times",
|
|
609
|
+
"- Console: Check for JavaScript errors and warnings",
|
|
610
|
+
"- Network Mocking: Use page.route() to mock API calls for offline testing and faster execution",
|
|
611
|
+
"- Trace Generation: Enable tracing with context.tracing.start() and save trace on failure for debugging",
|
|
612
|
+
"- Error Handling: On test failure, save trace file and include trace viewer command in error message",
|
|
613
|
+
"- Visual Regression: Use screenshot comparison to detect UI changes (create baselines, compare on test runs)",
|
|
614
|
+
"- Multi-Tab Testing: Test multi-tab scenarios using page.context().newPage() or browser_tabs MCP tool",
|
|
615
|
+
"- Device Emulation: Test responsive designs using device profiles (mobile, tablet, desktop)",
|
|
616
|
+
])
|
|
617
|
+
|
|
618
|
+
prompt_parts.extend(
|
|
619
|
+
[
|
|
620
|
+
"Requirements:",
|
|
621
|
+
*requirements,
|
|
622
|
+
*additional_requirements,
|
|
623
|
+
"- Test critical user journeys",
|
|
624
|
+
"- Include error scenarios",
|
|
625
|
+
"- Use descriptive test names",
|
|
626
|
+
"- Ensure tests are deterministic and repeatable",
|
|
627
|
+
"",
|
|
628
|
+
"Generate only the test code (no explanations):",
|
|
629
|
+
]
|
|
630
|
+
)
|
|
631
|
+
|
|
632
|
+
return "\n".join(prompt_parts)
|