claude-mpm 4.21.3__py3-none-any.whl → 5.0.2__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.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/BASE_PM.md +12 -0
- claude_mpm/agents/OUTPUT_STYLE.md +3 -48
- claude_mpm/agents/PM_INSTRUCTIONS.md +632 -334
- claude_mpm/agents/WORKFLOW.md +75 -2
- claude_mpm/agents/__init__.py +6 -0
- claude_mpm/agents/agent_loader.py +1 -4
- claude_mpm/agents/base_agent.json +6 -3
- claude_mpm/agents/frontmatter_validator.py +1 -1
- claude_mpm/agents/templates/{circuit_breakers.md → circuit-breakers.md} +370 -3
- claude_mpm/agents/templates/context-management-examples.md +544 -0
- claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +89 -19
- claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
- claude_mpm/agents/templates/research-gate-examples.md +669 -0
- claude_mpm/agents/templates/structured-questions-examples.md +615 -0
- claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
- claude_mpm/agents/templates/ticketing-examples.md +277 -0
- claude_mpm/cli/__init__.py +38 -2
- claude_mpm/cli/commands/agent_source.py +774 -0
- claude_mpm/cli/commands/agent_state_manager.py +125 -20
- claude_mpm/cli/commands/agents.py +684 -13
- claude_mpm/cli/commands/agents_cleanup.py +210 -0
- claude_mpm/cli/commands/agents_discover.py +338 -0
- claude_mpm/cli/commands/aggregate.py +1 -1
- claude_mpm/cli/commands/analyze.py +3 -3
- claude_mpm/cli/commands/auto_configure.py +2 -6
- claude_mpm/cli/commands/cleanup.py +1 -1
- claude_mpm/cli/commands/config.py +7 -4
- claude_mpm/cli/commands/configure.py +478 -44
- claude_mpm/cli/commands/configure_agent_display.py +4 -4
- claude_mpm/cli/commands/configure_navigation.py +63 -46
- claude_mpm/cli/commands/debug.py +12 -12
- claude_mpm/cli/commands/doctor.py +10 -2
- claude_mpm/cli/commands/hook_errors.py +277 -0
- claude_mpm/cli/commands/local_deploy.py +1 -4
- claude_mpm/cli/commands/mcp_install_commands.py +1 -1
- claude_mpm/cli/commands/mpm_init/core.py +50 -2
- claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
- claude_mpm/cli/commands/mpm_init/prompts.py +6 -6
- claude_mpm/cli/commands/run.py +124 -128
- claude_mpm/cli/commands/skill_source.py +694 -0
- claude_mpm/cli/commands/skills.py +435 -1
- claude_mpm/cli/executor.py +78 -3
- claude_mpm/cli/interactive/agent_wizard.py +919 -41
- claude_mpm/cli/parsers/agent_source_parser.py +171 -0
- claude_mpm/cli/parsers/agents_parser.py +173 -4
- claude_mpm/cli/parsers/base_parser.py +49 -0
- claude_mpm/cli/parsers/config_parser.py +96 -43
- claude_mpm/cli/parsers/skill_source_parser.py +169 -0
- claude_mpm/cli/parsers/skills_parser.py +138 -0
- claude_mpm/cli/parsers/source_parser.py +138 -0
- claude_mpm/cli/startup.py +499 -84
- claude_mpm/cli/startup_display.py +480 -0
- claude_mpm/cli/utils.py +1 -1
- claude_mpm/cli_module/commands.py +1 -1
- claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
- claude_mpm/commands/mpm-agents-detect.md +9 -0
- claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
- claude_mpm/commands/mpm-agents-recommend.md +9 -0
- claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
- claude_mpm/commands/mpm-doctor.md +9 -0
- claude_mpm/commands/mpm-help.md +11 -2
- claude_mpm/commands/mpm-init.md +27 -2
- claude_mpm/commands/mpm-monitor.md +9 -0
- claude_mpm/commands/{mpm-resume.md → mpm-session-resume.md} +9 -0
- claude_mpm/commands/mpm-status.md +9 -0
- claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
- claude_mpm/commands/mpm-ticket-view.md +552 -0
- claude_mpm/commands/mpm-version.md +9 -0
- claude_mpm/commands/mpm.md +10 -0
- claude_mpm/config/agent_presets.py +258 -0
- claude_mpm/config/agent_sources.py +325 -0
- claude_mpm/config/skill_sources.py +590 -0
- claude_mpm/constants.py +12 -0
- claude_mpm/core/api_validator.py +1 -1
- claude_mpm/core/claude_runner.py +17 -10
- claude_mpm/core/config.py +24 -0
- claude_mpm/core/constants.py +1 -1
- claude_mpm/core/framework/__init__.py +3 -16
- claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
- claude_mpm/core/framework/processors/metadata_processor.py +1 -1
- claude_mpm/core/hook_error_memory.py +381 -0
- claude_mpm/core/hook_manager.py +41 -2
- claude_mpm/core/interactive_session.py +112 -5
- claude_mpm/core/logger.py +3 -1
- claude_mpm/core/oneshot_session.py +94 -4
- claude_mpm/dashboard/static/css/activity.css +69 -69
- claude_mpm/dashboard/static/css/connection-status.css +10 -10
- claude_mpm/dashboard/static/css/dashboard.css +15 -15
- claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
- claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
- claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
- claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
- claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
- claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
- claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
- claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
- claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
- claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
- claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
- claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
- claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
- claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
- claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
- claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
- claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
- claude_mpm/dashboard/static/js/connection-manager.js +76 -76
- claude_mpm/dashboard/static/js/dashboard.js +76 -58
- claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
- claude_mpm/dashboard/static/js/socket-client.js +138 -121
- claude_mpm/dashboard/templates/code_simple.html +23 -23
- claude_mpm/dashboard/templates/index.html +18 -18
- claude_mpm/experimental/cli_enhancements.py +1 -5
- claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
- claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
- claude_mpm/hooks/claude_hooks/installer.py +45 -0
- claude_mpm/hooks/failure_learning/__init__.py +2 -8
- claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
- claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
- claude_mpm/hooks/kuzu_response_hook.py +1 -5
- claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
- claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
- claude_mpm/models/git_repository.py +198 -0
- claude_mpm/scripts/claude-hook-handler.sh +3 -3
- claude_mpm/scripts/start_activity_logging.py +3 -1
- claude_mpm/services/agents/agent_builder.py +45 -9
- claude_mpm/services/agents/agent_preset_service.py +238 -0
- claude_mpm/services/agents/agent_selection_service.py +484 -0
- claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
- claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
- claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
- claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
- claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
- claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
- claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
- claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
- claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
- claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
- claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
- claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
- claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
- claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
- claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
- claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
- claude_mpm/services/agents/git_source_manager.py +629 -0
- claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
- claude_mpm/services/agents/local_template_manager.py +50 -10
- claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
- claude_mpm/services/agents/sources/__init__.py +13 -0
- claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
- claude_mpm/services/agents/sources/git_source_sync_service.py +1055 -0
- claude_mpm/services/agents/startup_sync.py +239 -0
- claude_mpm/services/agents/toolchain_detector.py +474 -0
- claude_mpm/services/cli/session_pause_manager.py +1 -1
- claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
- claude_mpm/services/command_deployment_service.py +92 -1
- claude_mpm/services/core/interfaces/__init__.py +1 -3
- claude_mpm/services/core/interfaces/health.py +1 -4
- claude_mpm/services/core/models/__init__.py +2 -11
- claude_mpm/services/diagnostics/checks/__init__.py +4 -0
- claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
- claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
- claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
- claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
- claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
- claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
- claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
- claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
- claude_mpm/services/event_bus/direct_relay.py +3 -3
- claude_mpm/services/event_bus/event_bus.py +36 -3
- claude_mpm/services/events/consumers/logging.py +1 -2
- claude_mpm/services/git/__init__.py +21 -0
- claude_mpm/services/git/git_operations_service.py +494 -0
- claude_mpm/services/github/__init__.py +21 -0
- claude_mpm/services/github/github_cli_service.py +397 -0
- claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
- claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
- claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
- claude_mpm/services/instructions/__init__.py +9 -0
- claude_mpm/services/instructions/instruction_cache_service.py +374 -0
- claude_mpm/services/local_ops/__init__.py +3 -13
- claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
- claude_mpm/services/local_ops/health_manager.py +1 -4
- claude_mpm/services/local_ops/process_manager.py +1 -1
- claude_mpm/services/local_ops/resource_monitor.py +2 -2
- claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
- claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
- claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
- claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
- claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
- claude_mpm/services/memory/optimizer.py +1 -1
- claude_mpm/services/model/model_router.py +8 -9
- claude_mpm/services/monitor/daemon.py +1 -1
- claude_mpm/services/monitor/server.py +2 -2
- claude_mpm/services/native_agent_converter.py +356 -0
- claude_mpm/services/port_manager.py +1 -1
- claude_mpm/services/pr/__init__.py +14 -0
- claude_mpm/services/pr/pr_template_service.py +329 -0
- claude_mpm/services/project/documentation_manager.py +2 -1
- claude_mpm/services/project/toolchain_analyzer.py +3 -1
- claude_mpm/services/runner_configuration_service.py +1 -0
- claude_mpm/services/self_upgrade_service.py +165 -7
- claude_mpm/services/skills/__init__.py +18 -0
- claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
- claude_mpm/services/skills/skill_discovery_service.py +568 -0
- claude_mpm/services/skills_config.py +547 -0
- claude_mpm/services/skills_deployer.py +955 -0
- claude_mpm/services/socketio/handlers/connection.py +1 -1
- claude_mpm/services/socketio/handlers/git.py +2 -2
- claude_mpm/services/socketio/server/core.py +1 -4
- claude_mpm/services/socketio/server/main.py +1 -3
- claude_mpm/services/system_instructions_service.py +1 -3
- claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
- claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
- claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
- claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
- claude_mpm/services/unified/unified_deployment.py +1 -5
- claude_mpm/services/version_control/conflict_resolution.py +6 -4
- claude_mpm/services/visualization/__init__.py +1 -5
- claude_mpm/services/visualization/mermaid_generator.py +2 -3
- claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
- claude_mpm/skills/bundled/performance-profiling.md +6 -0
- claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
- claude_mpm/skills/skills_registry.py +0 -1
- claude_mpm/templates/questions/__init__.py +38 -0
- claude_mpm/templates/questions/base.py +193 -0
- claude_mpm/templates/questions/pr_strategy.py +311 -0
- claude_mpm/templates/questions/project_init.py +385 -0
- claude_mpm/templates/questions/ticket_mgmt.py +394 -0
- claude_mpm/tools/__main__.py +8 -8
- claude_mpm/tools/code_tree_analyzer/analysis.py +1 -1
- claude_mpm/utils/agent_dependency_loader.py +80 -13
- claude_mpm/utils/dependency_cache.py +3 -1
- claude_mpm/utils/gitignore.py +241 -0
- claude_mpm/utils/log_cleanup.py +3 -3
- claude_mpm/utils/progress.py +383 -0
- claude_mpm/utils/robust_installer.py +3 -5
- claude_mpm/utils/structured_questions.py +619 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/METADATA +429 -59
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/RECORD +252 -425
- claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
- claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
- claude_mpm/agents/templates/agent-manager.json +0 -273
- claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
- claude_mpm/agents/templates/api_qa.json +0 -180
- claude_mpm/agents/templates/clerk-ops.json +0 -235
- claude_mpm/agents/templates/code_analyzer.json +0 -101
- claude_mpm/agents/templates/content-agent.json +0 -358
- claude_mpm/agents/templates/dart_engineer.json +0 -307
- claude_mpm/agents/templates/data_engineer.json +0 -225
- claude_mpm/agents/templates/documentation.json +0 -211
- claude_mpm/agents/templates/engineer.json +0 -210
- claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
- claude_mpm/agents/templates/golang_engineer.json +0 -270
- claude_mpm/agents/templates/imagemagick.json +0 -264
- claude_mpm/agents/templates/java_engineer.json +0 -346
- claude_mpm/agents/templates/local_ops_agent.json +0 -1840
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
- claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
- claude_mpm/agents/templates/memory_manager.json +0 -158
- claude_mpm/agents/templates/nextjs_engineer.json +0 -285
- claude_mpm/agents/templates/ops.json +0 -185
- claude_mpm/agents/templates/php-engineer.json +0 -287
- claude_mpm/agents/templates/product_owner.json +0 -338
- claude_mpm/agents/templates/project_organizer.json +0 -140
- claude_mpm/agents/templates/prompt-engineer.json +0 -737
- claude_mpm/agents/templates/python_engineer.json +0 -387
- claude_mpm/agents/templates/qa.json +0 -242
- claude_mpm/agents/templates/react_engineer.json +0 -238
- claude_mpm/agents/templates/refactoring_engineer.json +0 -276
- claude_mpm/agents/templates/research.json +0 -188
- claude_mpm/agents/templates/ruby-engineer.json +0 -280
- claude_mpm/agents/templates/rust_engineer.json +0 -275
- claude_mpm/agents/templates/security.json +0 -202
- claude_mpm/agents/templates/svelte-engineer.json +0 -225
- claude_mpm/agents/templates/ticketing.json +0 -177
- claude_mpm/agents/templates/typescript_engineer.json +0 -285
- claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
- claude_mpm/agents/templates/version_control.json +0 -157
- claude_mpm/agents/templates/web_qa.json +0 -399
- claude_mpm/agents/templates/web_ui.json +0 -189
- claude_mpm/commands/mpm-tickets.md +0 -102
- claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
- claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
- claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
- claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
- claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
- claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
- claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
- claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
- claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
- claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
- claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
- claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
- claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
- claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
- claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
- claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
- claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
- claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
- claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
- claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
- claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
- claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
- claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
- claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
- claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
- claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
- claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
- claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
- claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
- claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
- claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
- claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
- claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
- claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/built/connection-manager.js +0 -536
- claude_mpm/dashboard/static/built/dashboard.js +0 -2
- claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
- claude_mpm/dashboard/static/built/react/events.js +0 -30
- claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
- claude_mpm/dashboard/static/built/shared/logger.js +0 -385
- claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
- claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/built/socket-client.js +0 -2
- claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
- claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
- claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
- claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
- claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
- claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
- claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
- claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
- claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
- claude_mpm/dashboard/static/dist/dashboard.js +0 -2
- claude_mpm/dashboard/static/dist/react/events.js +0 -30
- claude_mpm/dashboard/static/dist/socket-client.js +0 -2
- claude_mpm/dashboard/static/events.html +0 -607
- claude_mpm/dashboard/static/index.html +0 -635
- claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
- claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
- claude_mpm/dashboard/static/js/shared/logger.js +0 -385
- claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
- claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
- claude_mpm/dashboard/static/legacy/activity.html +0 -736
- claude_mpm/dashboard/static/legacy/agents.html +0 -786
- claude_mpm/dashboard/static/legacy/files.html +0 -747
- claude_mpm/dashboard/static/legacy/tools.html +0 -831
- claude_mpm/dashboard/static/monitors.html +0 -431
- claude_mpm/dashboard/static/production/events.html +0 -659
- claude_mpm/dashboard/static/production/main.html +0 -698
- claude_mpm/dashboard/static/production/monitors.html +0 -483
- claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
- claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
- claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
- claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
- claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
- claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
- claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
- claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
- claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
- claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
- claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
- claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
- claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
- claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
- claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
- claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
- claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
- claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
- claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
- claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
- claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
- claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
- claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
- claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
- claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
- claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
- claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
- claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
- claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
- claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
- claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
- claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
- claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
- claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
- claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
- claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
- claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
- claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
- claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
- claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
- claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
- claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
- claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
- claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
- claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
- claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
- claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
- claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
- claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
- claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
- claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
- claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
- claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
- claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
- claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
- claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
- claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
- claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
- claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
- claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
- claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
- claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
- claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
- claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
- claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
- claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
- claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
- claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
- claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
- /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
- /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
- /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
- /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/WHEEL +0 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/entry_points.txt +0 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-4.21.3.dist-info → claude_mpm-5.0.2.dist-info}/top_level.txt +0 -0
|
@@ -1,868 +0,0 @@
|
|
|
1
|
-
# Troubleshooting Reference
|
|
2
|
-
|
|
3
|
-
Complete guide to diagnosing and solving common webapp testing problems.
|
|
4
|
-
|
|
5
|
-
## Table of Contents
|
|
6
|
-
|
|
7
|
-
- [Timeout Issues](#timeout-issues)
|
|
8
|
-
- [Selector Issues](#selector-issues)
|
|
9
|
-
- [Server Issues](#server-issues)
|
|
10
|
-
- [Network Issues](#network-issues)
|
|
11
|
-
- [Environment Issues](#environment-issues)
|
|
12
|
-
- [Playwright-Specific Issues](#playwright-specific-issues)
|
|
13
|
-
- [Performance Issues](#performance-issues)
|
|
14
|
-
- [Debugging Workflow](#debugging-workflow)
|
|
15
|
-
|
|
16
|
-
## Timeout Issues
|
|
17
|
-
|
|
18
|
-
### Symptom: page.goto() Timeout
|
|
19
|
-
|
|
20
|
-
**Error message:**
|
|
21
|
-
```
|
|
22
|
-
TimeoutError: page.goto: Timeout 30000ms exceeded
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
**Possible causes and solutions:**
|
|
26
|
-
|
|
27
|
-
**1. Server not running**
|
|
28
|
-
```bash
|
|
29
|
-
# Check server status
|
|
30
|
-
lsof -i :3000 -sTCP:LISTEN
|
|
31
|
-
|
|
32
|
-
# If no output, start server
|
|
33
|
-
python scripts/with_server.py --server "npm start" --port 3000 -- python test.py
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
**2. Server slow to respond**
|
|
37
|
-
```bash
|
|
38
|
-
# Check response time
|
|
39
|
-
curl -w "Time: %{time_total}s\n" -o /dev/null -s http://localhost:3000
|
|
40
|
-
|
|
41
|
-
# If slow, increase timeout
|
|
42
|
-
page.goto('http://localhost:3000', timeout=60000) # 60 seconds
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
**3. Network connectivity issue**
|
|
46
|
-
```bash
|
|
47
|
-
# Test connection
|
|
48
|
-
curl http://localhost:3000
|
|
49
|
-
|
|
50
|
-
# Try different host format
|
|
51
|
-
page.goto('http://127.0.0.1:3000') # Instead of localhost
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
**4. Port incorrect**
|
|
55
|
-
```bash
|
|
56
|
-
# List all listening ports
|
|
57
|
-
lsof -i -sTCP:LISTEN
|
|
58
|
-
|
|
59
|
-
# Use correct port
|
|
60
|
-
page.goto('http://localhost:CORRECT_PORT')
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
### Symptom: wait_for_selector() Timeout
|
|
64
|
-
|
|
65
|
-
**Error message:**
|
|
66
|
-
```
|
|
67
|
-
TimeoutError: waiting for selector "button.submit" failed: timeout 30000ms exceeded
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
**Possible causes and solutions:**
|
|
71
|
-
|
|
72
|
-
**1. Page not fully loaded**
|
|
73
|
-
```python
|
|
74
|
-
# ❌ BAD: Missing wait
|
|
75
|
-
page.goto('http://localhost:3000')
|
|
76
|
-
page.click('button.submit') # Fails
|
|
77
|
-
|
|
78
|
-
# ✅ GOOD: Wait for networkidle
|
|
79
|
-
page.goto('http://localhost:3000')
|
|
80
|
-
page.wait_for_load_state('networkidle')
|
|
81
|
-
page.click('button.submit') # Works
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
**2. Selector doesn't match**
|
|
85
|
-
```python
|
|
86
|
-
# Take screenshot to see actual page
|
|
87
|
-
page.screenshot(path='/tmp/debug.png', full_page=True)
|
|
88
|
-
|
|
89
|
-
# Inspect DOM
|
|
90
|
-
content = page.content()
|
|
91
|
-
print('button' in content.lower()) # Does 'button' exist?
|
|
92
|
-
|
|
93
|
-
# Try different selector
|
|
94
|
-
page.wait_for_selector('text=Submit') # Text selector
|
|
95
|
-
page.wait_for_selector('role=button') # Role selector
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
**3. Element conditionally rendered**
|
|
99
|
-
```python
|
|
100
|
-
# Check if element appears after action
|
|
101
|
-
page.click('text=Show Form')
|
|
102
|
-
page.wait_for_selector('button.submit') # Now appears
|
|
103
|
-
|
|
104
|
-
# Or check application state
|
|
105
|
-
page.wait_for_function('() => window.formReady === true')
|
|
106
|
-
page.wait_for_selector('button.submit')
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
**4. Element in iframe**
|
|
110
|
-
```python
|
|
111
|
-
# Regular selector won't work for iframe content
|
|
112
|
-
# ❌ page.wait_for_selector('.iframe-button')
|
|
113
|
-
|
|
114
|
-
# ✅ Access iframe first
|
|
115
|
-
frame = page.frame_locator('iframe#myframe')
|
|
116
|
-
frame.locator('.iframe-button').wait_for()
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
### Symptom: wait_for_load_state('networkidle') Never Completes
|
|
120
|
-
|
|
121
|
-
**Error message:**
|
|
122
|
-
```
|
|
123
|
-
TimeoutError: page.wait_for_load_state: Timeout 30000ms exceeded
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
**Possible causes and solutions:**
|
|
127
|
-
|
|
128
|
-
**1. Polling API or WebSocket**
|
|
129
|
-
```python
|
|
130
|
-
# Page constantly makes requests, never idle
|
|
131
|
-
# ❌ page.wait_for_load_state('networkidle')
|
|
132
|
-
|
|
133
|
-
# ✅ Use 'load' instead
|
|
134
|
-
page.wait_for_load_state('load')
|
|
135
|
-
|
|
136
|
-
# Or wait for specific element
|
|
137
|
-
page.wait_for_selector('.content')
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
**2. Long-running request**
|
|
141
|
-
```python
|
|
142
|
-
# Some API call takes very long
|
|
143
|
-
# ✅ Wait for specific element instead
|
|
144
|
-
page.wait_for_selector('.data-loaded')
|
|
145
|
-
|
|
146
|
-
# Or increase timeout
|
|
147
|
-
page.wait_for_load_state('networkidle', timeout=60000)
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
**3. Failed request keeps retrying**
|
|
151
|
-
```python
|
|
152
|
-
# Check console for errors
|
|
153
|
-
page.on("console", lambda msg: print(f"[{msg.type}] {msg.text}"))
|
|
154
|
-
|
|
155
|
-
# Check network errors
|
|
156
|
-
def handle_response(response):
|
|
157
|
-
if response.status >= 400:
|
|
158
|
-
print(f"Failed: {response.url} - {response.status}")
|
|
159
|
-
page.on("response", handle_response)
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
## Selector Issues
|
|
163
|
-
|
|
164
|
-
### Symptom: Element Not Found
|
|
165
|
-
|
|
166
|
-
**Error message:**
|
|
167
|
-
```
|
|
168
|
-
Error: Element not found
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
**Diagnosis and solutions:**
|
|
172
|
-
|
|
173
|
-
**1. Verify element exists in DOM**
|
|
174
|
-
```python
|
|
175
|
-
# Get full HTML
|
|
176
|
-
content = page.content()
|
|
177
|
-
|
|
178
|
-
# Search for expected text/class/id
|
|
179
|
-
print('submit' in content.lower())
|
|
180
|
-
print('class="submit"' in content)
|
|
181
|
-
print('id="submit-button"' in content)
|
|
182
|
-
|
|
183
|
-
# Save HTML for inspection
|
|
184
|
-
with open('/tmp/page.html', 'w') as f:
|
|
185
|
-
f.write(content)
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
**2. Try different selector strategies**
|
|
189
|
-
```python
|
|
190
|
-
# Text selector (most readable)
|
|
191
|
-
page.click('text=Submit')
|
|
192
|
-
|
|
193
|
-
# Role selector (semantic)
|
|
194
|
-
page.click('role=button[name="Submit"]')
|
|
195
|
-
|
|
196
|
-
# CSS selector
|
|
197
|
-
page.click('button.submit')
|
|
198
|
-
page.click('#submit-button')
|
|
199
|
-
|
|
200
|
-
# Data attribute (most stable)
|
|
201
|
-
page.click('[data-testid="submit"]')
|
|
202
|
-
|
|
203
|
-
# XPath (last resort)
|
|
204
|
-
page.click('xpath=//button[contains(text(), "Submit")]')
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
**3. Count matching elements**
|
|
208
|
-
```python
|
|
209
|
-
# How many elements match?
|
|
210
|
-
elements = page.locator('button').all()
|
|
211
|
-
print(f"Found {len(elements)} buttons:")
|
|
212
|
-
for i, btn in enumerate(elements):
|
|
213
|
-
text = btn.inner_text() if btn.is_visible() else "[hidden]"
|
|
214
|
-
print(f" [{i}] {text}")
|
|
215
|
-
|
|
216
|
-
# If multiple matches, make selector more specific
|
|
217
|
-
page.click('form.login >> button.submit')
|
|
218
|
-
```
|
|
219
|
-
|
|
220
|
-
### Symptom: Element Not Visible
|
|
221
|
-
|
|
222
|
-
**Error message:**
|
|
223
|
-
```
|
|
224
|
-
Error: Element is not visible
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
**Diagnosis and solutions:**
|
|
228
|
-
|
|
229
|
-
**1. Check if element exists but hidden**
|
|
230
|
-
```python
|
|
231
|
-
# Check visibility
|
|
232
|
-
element = page.locator('button.submit')
|
|
233
|
-
print(f"Exists: {element.count() > 0}")
|
|
234
|
-
print(f"Visible: {element.is_visible()}")
|
|
235
|
-
|
|
236
|
-
# Check CSS
|
|
237
|
-
print(f"Display: {element.evaluate('el => getComputedStyle(el).display')}")
|
|
238
|
-
print(f"Visibility: {element.evaluate('el => getComputedStyle(el).visibility')}")
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
**2. Scroll element into view**
|
|
242
|
-
```python
|
|
243
|
-
# Element might be below fold
|
|
244
|
-
page.locator('button.submit').scroll_into_view_if_needed()
|
|
245
|
-
page.click('button.submit')
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
**3. Wait for element to become visible**
|
|
249
|
-
```python
|
|
250
|
-
# Element may be hidden initially
|
|
251
|
-
page.wait_for_selector('button.submit', state='visible')
|
|
252
|
-
page.click('button.submit')
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
**4. Check for overlapping elements**
|
|
256
|
-
```python
|
|
257
|
-
# Take screenshot to see layout
|
|
258
|
-
page.screenshot(path='/tmp/layout.png')
|
|
259
|
-
|
|
260
|
-
# Check if modal/overlay is blocking
|
|
261
|
-
page.wait_for_selector('.modal', state='hidden')
|
|
262
|
-
page.click('button.submit')
|
|
263
|
-
|
|
264
|
-
# Or force click (bypass visibility check)
|
|
265
|
-
page.click('button.submit', force=True)
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
### Symptom: Stale Element
|
|
269
|
-
|
|
270
|
-
**Error message:**
|
|
271
|
-
```
|
|
272
|
-
Error: Element is not attached to the DOM
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
**Solution:**
|
|
276
|
-
```python
|
|
277
|
-
# Don't store element references across page changes
|
|
278
|
-
# ❌ BAD
|
|
279
|
-
button = page.locator('button.submit')
|
|
280
|
-
page.goto('http://localhost:3000/other')
|
|
281
|
-
button.click() # Stale element
|
|
282
|
-
|
|
283
|
-
# ✅ GOOD
|
|
284
|
-
page.goto('http://localhost:3000/other')
|
|
285
|
-
page.locator('button.submit').click() # Query again
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
## Server Issues
|
|
289
|
-
|
|
290
|
-
### Symptom: Port Already in Use
|
|
291
|
-
|
|
292
|
-
**Error message:**
|
|
293
|
-
```
|
|
294
|
-
Error: listen EADDRINUSE: address already in use :::3000
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
**Diagnosis and solutions:**
|
|
298
|
-
|
|
299
|
-
**1. Find process using port**
|
|
300
|
-
```bash
|
|
301
|
-
# macOS/Linux
|
|
302
|
-
lsof -i :3000
|
|
303
|
-
|
|
304
|
-
# Get PID
|
|
305
|
-
lsof -t -i :3000
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
**2. Kill process**
|
|
309
|
-
```bash
|
|
310
|
-
# Graceful kill
|
|
311
|
-
lsof -t -i :3000 | xargs kill
|
|
312
|
-
|
|
313
|
-
# Force kill if needed
|
|
314
|
-
lsof -t -i :3000 | xargs kill -9
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
**3. Use different port**
|
|
318
|
-
```bash
|
|
319
|
-
# Node.js
|
|
320
|
-
PORT=3001 npm start
|
|
321
|
-
|
|
322
|
-
# Python
|
|
323
|
-
python manage.py runserver 3001
|
|
324
|
-
|
|
325
|
-
# Update test
|
|
326
|
-
page.goto('http://localhost:3001')
|
|
327
|
-
```
|
|
328
|
-
|
|
329
|
-
### Symptom: Server Crashes During Test
|
|
330
|
-
|
|
331
|
-
**Error message:**
|
|
332
|
-
```
|
|
333
|
-
Error: Connection refused / ECONNREFUSED
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
**Diagnosis and solutions:**
|
|
337
|
-
|
|
338
|
-
**1. Check if process still running**
|
|
339
|
-
```bash
|
|
340
|
-
# Check by port
|
|
341
|
-
lsof -i :3000
|
|
342
|
-
|
|
343
|
-
# Check by process name
|
|
344
|
-
ps aux | grep node
|
|
345
|
-
ps aux | grep python
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
**2. Check server logs**
|
|
349
|
-
```bash
|
|
350
|
-
# If started with with_server.py, check stderr
|
|
351
|
-
python scripts/with_server.py --server "npm start" --port 3000 -- python test.py 2>&1 | tee full.log
|
|
352
|
-
|
|
353
|
-
# Check application log file
|
|
354
|
-
tail -f server.log
|
|
355
|
-
tail -f /tmp/server.log
|
|
356
|
-
```
|
|
357
|
-
|
|
358
|
-
**3. Common crash causes**
|
|
359
|
-
```python
|
|
360
|
-
# Memory leak
|
|
361
|
-
# Solution: Restart server between test suites
|
|
362
|
-
|
|
363
|
-
# Unhandled exception
|
|
364
|
-
# Solution: Add error handling in server code
|
|
365
|
-
|
|
366
|
-
# Database connection lost
|
|
367
|
-
# Solution: Implement connection pooling and retry logic
|
|
368
|
-
|
|
369
|
-
# Port conflict
|
|
370
|
-
# Solution: Use unique port for each test run
|
|
371
|
-
```
|
|
372
|
-
|
|
373
|
-
### Symptom: Server Won't Start
|
|
374
|
-
|
|
375
|
-
**Error message:**
|
|
376
|
-
```
|
|
377
|
-
RuntimeError: Server failed to start on port 3000 within 30s
|
|
378
|
-
```
|
|
379
|
-
|
|
380
|
-
**Diagnosis and solutions:**
|
|
381
|
-
|
|
382
|
-
**1. Check startup logs**
|
|
383
|
-
```bash
|
|
384
|
-
# Start server manually to see errors
|
|
385
|
-
npm start
|
|
386
|
-
python manage.py runserver
|
|
387
|
-
|
|
388
|
-
# Look for:
|
|
389
|
-
# - Missing dependencies
|
|
390
|
-
# - Configuration errors
|
|
391
|
-
# - Permission issues
|
|
392
|
-
```
|
|
393
|
-
|
|
394
|
-
**2. Increase timeout**
|
|
395
|
-
```bash
|
|
396
|
-
# Server might be slow to start
|
|
397
|
-
python scripts/with_server.py --server "npm start" --port 3000 --timeout 60 -- python test.py
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
**3. Check dependencies**
|
|
401
|
-
```bash
|
|
402
|
-
# Node.js
|
|
403
|
-
npm install
|
|
404
|
-
|
|
405
|
-
# Python
|
|
406
|
-
pip install -r requirements.txt
|
|
407
|
-
|
|
408
|
-
# Check for peer dependency warnings
|
|
409
|
-
npm ls
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
## Network Issues
|
|
413
|
-
|
|
414
|
-
### Symptom: CORS Error
|
|
415
|
-
|
|
416
|
-
**Error in console:**
|
|
417
|
-
```
|
|
418
|
-
Access to fetch at 'http://localhost:4000/api' from origin 'http://localhost:3000'
|
|
419
|
-
has been blocked by CORS policy
|
|
420
|
-
```
|
|
421
|
-
|
|
422
|
-
**Solutions:**
|
|
423
|
-
|
|
424
|
-
**1. Configure server CORS (development)**
|
|
425
|
-
```javascript
|
|
426
|
-
// Express.js
|
|
427
|
-
const cors = require('cors');
|
|
428
|
-
app.use(cors());
|
|
429
|
-
|
|
430
|
-
// Or specific origin
|
|
431
|
-
app.use(cors({
|
|
432
|
-
origin: 'http://localhost:3000'
|
|
433
|
-
}));
|
|
434
|
-
```
|
|
435
|
-
|
|
436
|
-
**2. Use proxy in development**
|
|
437
|
-
```javascript
|
|
438
|
-
// package.json (Create React App)
|
|
439
|
-
{
|
|
440
|
-
"proxy": "http://localhost:4000"
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
// Now fetch('/api/data') goes to http://localhost:4000/api/data
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
**3. Start servers on same origin (testing)**
|
|
447
|
-
```bash
|
|
448
|
-
# Use reverse proxy or configure servers to run on same port with different paths
|
|
449
|
-
```
|
|
450
|
-
|
|
451
|
-
### Symptom: Request Timeout
|
|
452
|
-
|
|
453
|
-
**Error message:**
|
|
454
|
-
```
|
|
455
|
-
TimeoutError: waiting for response to **/api/data
|
|
456
|
-
```
|
|
457
|
-
|
|
458
|
-
**Diagnosis and solutions:**
|
|
459
|
-
|
|
460
|
-
**1. Check API server is running**
|
|
461
|
-
```bash
|
|
462
|
-
# If using multiple servers
|
|
463
|
-
python scripts/with_server.py \
|
|
464
|
-
--server "cd backend && npm start" --port 4000 \
|
|
465
|
-
--server "cd frontend && npm start" --port 3000 \
|
|
466
|
-
-- python test.py
|
|
467
|
-
```
|
|
468
|
-
|
|
469
|
-
**2. Check response time**
|
|
470
|
-
```bash
|
|
471
|
-
curl -w "Time: %{time_total}s\n" http://localhost:4000/api/data
|
|
472
|
-
```
|
|
473
|
-
|
|
474
|
-
**3. Increase timeout**
|
|
475
|
-
```python
|
|
476
|
-
# Wait for slow API
|
|
477
|
-
with page.expect_response('**/api/data', timeout=60000) as response_info:
|
|
478
|
-
page.click('button.load')
|
|
479
|
-
```
|
|
480
|
-
|
|
481
|
-
**4. Mock slow API**
|
|
482
|
-
```python
|
|
483
|
-
# Mock API for faster tests
|
|
484
|
-
def handle_route(route):
|
|
485
|
-
route.fulfill(
|
|
486
|
-
status=200,
|
|
487
|
-
body='{"data": "mocked"}',
|
|
488
|
-
headers={'Content-Type': 'application/json'}
|
|
489
|
-
)
|
|
490
|
-
|
|
491
|
-
page.route('**/api/data', handle_route)
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
### Symptom: SSL/TLS Error
|
|
495
|
-
|
|
496
|
-
**Error message:**
|
|
497
|
-
```
|
|
498
|
-
Error: certificate not trusted
|
|
499
|
-
```
|
|
500
|
-
|
|
501
|
-
**Solutions:**
|
|
502
|
-
|
|
503
|
-
**1. Use HTTP for local development**
|
|
504
|
-
```python
|
|
505
|
-
page.goto('http://localhost:3000') # Not https://
|
|
506
|
-
```
|
|
507
|
-
|
|
508
|
-
**2. Ignore HTTPS errors (testing only)**
|
|
509
|
-
```python
|
|
510
|
-
browser = p.chromium.launch(headless=True)
|
|
511
|
-
context = browser.new_context(ignore_https_errors=True)
|
|
512
|
-
page = context.new_page()
|
|
513
|
-
```
|
|
514
|
-
|
|
515
|
-
## Environment Issues
|
|
516
|
-
|
|
517
|
-
### Symptom: Missing Environment Variables
|
|
518
|
-
|
|
519
|
-
**Error in server logs:**
|
|
520
|
-
```
|
|
521
|
-
Error: DATABASE_URL is not defined
|
|
522
|
-
```
|
|
523
|
-
|
|
524
|
-
**Solutions:**
|
|
525
|
-
|
|
526
|
-
**1. Create .env file**
|
|
527
|
-
```bash
|
|
528
|
-
# .env
|
|
529
|
-
PORT=3000
|
|
530
|
-
NODE_ENV=development
|
|
531
|
-
DATABASE_URL=postgresql://localhost/mydb
|
|
532
|
-
API_KEY=test123
|
|
533
|
-
```
|
|
534
|
-
|
|
535
|
-
**2. Load environment variables**
|
|
536
|
-
```bash
|
|
537
|
-
# Node.js with dotenv
|
|
538
|
-
npm install dotenv
|
|
539
|
-
|
|
540
|
-
# In server code
|
|
541
|
-
require('dotenv').config();
|
|
542
|
-
|
|
543
|
-
# Python with python-dotenv
|
|
544
|
-
pip install python-dotenv
|
|
545
|
-
|
|
546
|
-
# In server code
|
|
547
|
-
from dotenv import load_dotenv
|
|
548
|
-
load_dotenv()
|
|
549
|
-
```
|
|
550
|
-
|
|
551
|
-
**3. Set environment variables before starting**
|
|
552
|
-
```bash
|
|
553
|
-
# Linux/macOS
|
|
554
|
-
export PORT=3000
|
|
555
|
-
npm start
|
|
556
|
-
|
|
557
|
-
# Windows
|
|
558
|
-
set PORT=3000
|
|
559
|
-
npm start
|
|
560
|
-
|
|
561
|
-
# Or inline
|
|
562
|
-
PORT=3000 npm start
|
|
563
|
-
```
|
|
564
|
-
|
|
565
|
-
### Symptom: Wrong Node/Python Version
|
|
566
|
-
|
|
567
|
-
**Error message:**
|
|
568
|
-
```
|
|
569
|
-
SyntaxError: Unexpected token '??' (nullish coalescing)
|
|
570
|
-
```
|
|
571
|
-
|
|
572
|
-
**Solutions:**
|
|
573
|
-
|
|
574
|
-
**1. Check version**
|
|
575
|
-
```bash
|
|
576
|
-
node --version
|
|
577
|
-
python --version
|
|
578
|
-
```
|
|
579
|
-
|
|
580
|
-
**2. Use correct version**
|
|
581
|
-
```bash
|
|
582
|
-
# Node.js with nvm
|
|
583
|
-
nvm install 18
|
|
584
|
-
nvm use 18
|
|
585
|
-
|
|
586
|
-
# Python with pyenv
|
|
587
|
-
pyenv install 3.11
|
|
588
|
-
pyenv local 3.11
|
|
589
|
-
```
|
|
590
|
-
|
|
591
|
-
**3. Check project requirements**
|
|
592
|
-
```json
|
|
593
|
-
// package.json
|
|
594
|
-
{
|
|
595
|
-
"engines": {
|
|
596
|
-
"node": ">=18.0.0"
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
```
|
|
600
|
-
|
|
601
|
-
## Playwright-Specific Issues
|
|
602
|
-
|
|
603
|
-
### Symptom: Browser Download Failed
|
|
604
|
-
|
|
605
|
-
**Error message:**
|
|
606
|
-
```
|
|
607
|
-
Error: Executable doesn't exist at /path/to/browsers/chromium-xxx
|
|
608
|
-
```
|
|
609
|
-
|
|
610
|
-
**Solution:**
|
|
611
|
-
```bash
|
|
612
|
-
# Install browsers
|
|
613
|
-
playwright install chromium
|
|
614
|
-
|
|
615
|
-
# Or all browsers
|
|
616
|
-
playwright install
|
|
617
|
-
|
|
618
|
-
# With specific version
|
|
619
|
-
pip install playwright==1.40.0
|
|
620
|
-
playwright install chromium
|
|
621
|
-
```
|
|
622
|
-
|
|
623
|
-
### Symptom: Headless vs Headed Differences
|
|
624
|
-
|
|
625
|
-
**Issue:** Test passes in headless but fails in headed (or vice versa)
|
|
626
|
-
|
|
627
|
-
**Solutions:**
|
|
628
|
-
|
|
629
|
-
**1. Viewport size differences**
|
|
630
|
-
```python
|
|
631
|
-
# Set consistent viewport
|
|
632
|
-
page.set_viewport_size({'width': 1920, 'height': 1080})
|
|
633
|
-
```
|
|
634
|
-
|
|
635
|
-
**2. Timing differences**
|
|
636
|
-
```python
|
|
637
|
-
# Headed mode is often slower
|
|
638
|
-
# Always use wait_for_load_state
|
|
639
|
-
page.wait_for_load_state('networkidle')
|
|
640
|
-
```
|
|
641
|
-
|
|
642
|
-
**3. Debug with headed mode**
|
|
643
|
-
```python
|
|
644
|
-
# Run in headed to see what's happening
|
|
645
|
-
browser = p.chromium.launch(headless=False, slow_mo=1000)
|
|
646
|
-
```
|
|
647
|
-
|
|
648
|
-
### Symptom: Element Screenshot is Blank
|
|
649
|
-
|
|
650
|
-
**Issue:** `element.screenshot()` produces blank image
|
|
651
|
-
|
|
652
|
-
**Solutions:**
|
|
653
|
-
|
|
654
|
-
**1. Wait for element to be visible**
|
|
655
|
-
```python
|
|
656
|
-
element = page.locator('.chart')
|
|
657
|
-
element.wait_for()
|
|
658
|
-
page.wait_for_timeout(500) # Wait for rendering
|
|
659
|
-
element.screenshot(path='/tmp/chart.png')
|
|
660
|
-
```
|
|
661
|
-
|
|
662
|
-
**2. Check element has size**
|
|
663
|
-
```python
|
|
664
|
-
box = element.bounding_box()
|
|
665
|
-
print(f"Size: {box['width']}x{box['height']}")
|
|
666
|
-
```
|
|
667
|
-
|
|
668
|
-
**3. Capture full page instead**
|
|
669
|
-
```python
|
|
670
|
-
page.screenshot(path='/tmp/full.png', full_page=True)
|
|
671
|
-
```
|
|
672
|
-
|
|
673
|
-
## Performance Issues
|
|
674
|
-
|
|
675
|
-
### Symptom: Tests Run Very Slowly
|
|
676
|
-
|
|
677
|
-
**Diagnosis and solutions:**
|
|
678
|
-
|
|
679
|
-
**1. Remove unnecessary waits**
|
|
680
|
-
```python
|
|
681
|
-
# ❌ BAD: Fixed delays
|
|
682
|
-
page.click('button')
|
|
683
|
-
page.wait_for_timeout(5000) # Slow!
|
|
684
|
-
|
|
685
|
-
# ✅ GOOD: Wait for specific condition
|
|
686
|
-
page.click('button')
|
|
687
|
-
page.wait_for_selector('.result') # Fast
|
|
688
|
-
```
|
|
689
|
-
|
|
690
|
-
**2. Use networkidle only when needed**
|
|
691
|
-
```python
|
|
692
|
-
# For static pages or SSR
|
|
693
|
-
page.wait_for_load_state('load') # Faster than networkidle
|
|
694
|
-
|
|
695
|
-
# For dynamic pages with APIs
|
|
696
|
-
page.wait_for_load_state('networkidle') # Necessary
|
|
697
|
-
```
|
|
698
|
-
|
|
699
|
-
**3. Block unnecessary resources**
|
|
700
|
-
```python
|
|
701
|
-
# Block images, fonts, stylesheets for faster tests
|
|
702
|
-
page.route('**/*.{png,jpg,jpeg,gif,svg,woff,woff2,ttf,css}', lambda route: route.abort())
|
|
703
|
-
```
|
|
704
|
-
|
|
705
|
-
**4. Reuse browser context**
|
|
706
|
-
```python
|
|
707
|
-
# ❌ Slow: New browser per test
|
|
708
|
-
def test_1():
|
|
709
|
-
with sync_playwright() as p:
|
|
710
|
-
browser = p.chromium.launch()
|
|
711
|
-
# ...
|
|
712
|
-
|
|
713
|
-
# ✅ Fast: Reuse browser
|
|
714
|
-
@pytest.fixture(scope="session")
|
|
715
|
-
def browser():
|
|
716
|
-
with sync_playwright() as p:
|
|
717
|
-
browser = p.chromium.launch()
|
|
718
|
-
yield browser
|
|
719
|
-
```
|
|
720
|
-
|
|
721
|
-
### Symptom: High Memory Usage
|
|
722
|
-
|
|
723
|
-
**Solutions:**
|
|
724
|
-
|
|
725
|
-
**1. Close pages after use**
|
|
726
|
-
```python
|
|
727
|
-
page = browser.new_page()
|
|
728
|
-
# ... test ...
|
|
729
|
-
page.close()
|
|
730
|
-
```
|
|
731
|
-
|
|
732
|
-
**2. Clear context between tests**
|
|
733
|
-
```python
|
|
734
|
-
@pytest.fixture
|
|
735
|
-
def context(browser):
|
|
736
|
-
context = browser.new_context()
|
|
737
|
-
yield context
|
|
738
|
-
context.close()
|
|
739
|
-
```
|
|
740
|
-
|
|
741
|
-
**3. Limit parallel tests**
|
|
742
|
-
```bash
|
|
743
|
-
# Don't run too many in parallel
|
|
744
|
-
pytest -n 4 # Limit to 4 workers
|
|
745
|
-
```
|
|
746
|
-
|
|
747
|
-
## Debugging Workflow
|
|
748
|
-
|
|
749
|
-
### Step 1: Reproduce the Issue
|
|
750
|
-
|
|
751
|
-
```python
|
|
752
|
-
# Create minimal reproduction script
|
|
753
|
-
from playwright.sync_api import sync_playwright
|
|
754
|
-
|
|
755
|
-
with sync_playwright() as p:
|
|
756
|
-
browser = p.chromium.launch(headless=True)
|
|
757
|
-
page = browser.new_page()
|
|
758
|
-
|
|
759
|
-
# Minimal steps to reproduce
|
|
760
|
-
page.goto('http://localhost:3000')
|
|
761
|
-
page.wait_for_load_state('networkidle')
|
|
762
|
-
page.click('button.submit') # Fails here
|
|
763
|
-
|
|
764
|
-
browser.close()
|
|
765
|
-
```
|
|
766
|
-
|
|
767
|
-
### Step 2: Gather Evidence
|
|
768
|
-
|
|
769
|
-
```python
|
|
770
|
-
# Add reconnaissance
|
|
771
|
-
page.goto('http://localhost:3000')
|
|
772
|
-
page.wait_for_load_state('networkidle')
|
|
773
|
-
|
|
774
|
-
# Screenshot
|
|
775
|
-
page.screenshot(path='/tmp/before-click.png', full_page=True)
|
|
776
|
-
|
|
777
|
-
# Console logs
|
|
778
|
-
console_logs = []
|
|
779
|
-
page.on("console", lambda msg: console_logs.append(f"[{msg.type}] {msg.text}"))
|
|
780
|
-
|
|
781
|
-
# DOM content
|
|
782
|
-
with open('/tmp/dom.html', 'w') as f:
|
|
783
|
-
f.write(page.content())
|
|
784
|
-
|
|
785
|
-
# Try action
|
|
786
|
-
try:
|
|
787
|
-
page.click('button.submit')
|
|
788
|
-
except Exception as e:
|
|
789
|
-
print(f"Error: {e}")
|
|
790
|
-
page.screenshot(path='/tmp/error.png', full_page=True)
|
|
791
|
-
|
|
792
|
-
# Save console logs
|
|
793
|
-
with open('/tmp/console.log', 'w') as f:
|
|
794
|
-
f.write('\n'.join(console_logs))
|
|
795
|
-
```
|
|
796
|
-
|
|
797
|
-
### Step 3: Analyze Evidence
|
|
798
|
-
|
|
799
|
-
```bash
|
|
800
|
-
# View screenshots
|
|
801
|
-
open /tmp/before-click.png
|
|
802
|
-
open /tmp/error.png
|
|
803
|
-
|
|
804
|
-
# Search DOM
|
|
805
|
-
grep -i "submit" /tmp/dom.html
|
|
806
|
-
grep -i "button" /tmp/dom.html
|
|
807
|
-
|
|
808
|
-
# Check console
|
|
809
|
-
cat /tmp/console.log | grep -i error
|
|
810
|
-
```
|
|
811
|
-
|
|
812
|
-
### Step 4: Form Hypothesis
|
|
813
|
-
|
|
814
|
-
Based on evidence:
|
|
815
|
-
- Screenshot shows page loaded correctly? → Selector issue
|
|
816
|
-
- Screenshot shows blank page? → Loading issue
|
|
817
|
-
- Screenshot shows error message? → Server issue
|
|
818
|
-
- Console shows errors? → JavaScript issue
|
|
819
|
-
- Element exists in DOM but not visible? → CSS issue
|
|
820
|
-
|
|
821
|
-
### Step 5: Test Hypothesis
|
|
822
|
-
|
|
823
|
-
```python
|
|
824
|
-
# Hypothesis: Selector is wrong
|
|
825
|
-
# Test: Try different selectors
|
|
826
|
-
page.click('text=Submit') # Try text
|
|
827
|
-
page.click('role=button') # Try role
|
|
828
|
-
page.click('#submit') # Try ID
|
|
829
|
-
|
|
830
|
-
# Hypothesis: Need to wait longer
|
|
831
|
-
# Test: Add explicit wait
|
|
832
|
-
page.wait_for_selector('button.submit', state='visible')
|
|
833
|
-
page.click('button.submit')
|
|
834
|
-
|
|
835
|
-
# Hypothesis: Element obscured
|
|
836
|
-
# Test: Force click
|
|
837
|
-
page.click('button.submit', force=True)
|
|
838
|
-
```
|
|
839
|
-
|
|
840
|
-
### Step 6: Verify Fix
|
|
841
|
-
|
|
842
|
-
```python
|
|
843
|
-
# Once fixed, verify with full test
|
|
844
|
-
page.goto('http://localhost:3000')
|
|
845
|
-
page.wait_for_load_state('networkidle')
|
|
846
|
-
page.wait_for_selector('button.submit', state='visible')
|
|
847
|
-
page.click('button.submit')
|
|
848
|
-
page.wait_for_selector('.success-message')
|
|
849
|
-
print("✅ Test passed")
|
|
850
|
-
```
|
|
851
|
-
|
|
852
|
-
### Step 7: Prevent Regression
|
|
853
|
-
|
|
854
|
-
```python
|
|
855
|
-
# Add to test suite with proper waits and assertions
|
|
856
|
-
def test_submit_button():
|
|
857
|
-
page.goto('http://localhost:3000')
|
|
858
|
-
page.wait_for_load_state('networkidle')
|
|
859
|
-
|
|
860
|
-
# Verify button exists and is clickable
|
|
861
|
-
submit_btn = page.locator('button.submit')
|
|
862
|
-
expect(submit_btn).to_be_visible()
|
|
863
|
-
expect(submit_btn).to_be_enabled()
|
|
864
|
-
|
|
865
|
-
# Click and verify result
|
|
866
|
-
submit_btn.click()
|
|
867
|
-
expect(page.locator('.success-message')).to_be_visible()
|
|
868
|
-
```
|