claude-autopm 2.8.1 → 2.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +399 -529
- package/bin/autopm.js +2 -0
- package/bin/commands/plugin.js +395 -0
- package/bin/commands/team.js +184 -10
- package/install/install.js +223 -4
- package/lib/plugins/PluginManager.js +1328 -0
- package/lib/plugins/PluginManager.old.js +400 -0
- package/package.json +5 -1
- package/packages/plugin-ai/LICENSE +21 -0
- package/packages/plugin-ai/README.md +316 -0
- package/packages/plugin-ai/agents/anthropic-claude-expert.md +579 -0
- package/packages/plugin-ai/agents/azure-openai-expert.md +1411 -0
- package/packages/plugin-ai/agents/google-a2a-expert.md +1445 -0
- package/packages/plugin-ai/agents/huggingface-expert.md +2131 -0
- package/packages/plugin-ai/agents/langchain-expert.md +1427 -0
- package/packages/plugin-ai/commands/a2a-setup.md +886 -0
- package/packages/plugin-ai/commands/ai-model-deployment.md +481 -0
- package/packages/plugin-ai/commands/anthropic-optimize.md +793 -0
- package/packages/plugin-ai/commands/huggingface-deploy.md +789 -0
- package/packages/plugin-ai/commands/langchain-optimize.md +807 -0
- package/packages/plugin-ai/commands/llm-optimize.md +348 -0
- package/packages/plugin-ai/commands/openai-optimize.md +863 -0
- package/packages/plugin-ai/commands/rag-optimize.md +841 -0
- package/packages/plugin-ai/commands/rag-setup-scaffold.md +382 -0
- package/packages/plugin-ai/package.json +66 -0
- package/packages/plugin-ai/plugin.json +519 -0
- package/packages/plugin-ai/rules/ai-model-standards.md +449 -0
- package/packages/plugin-ai/rules/prompt-engineering-standards.md +509 -0
- package/packages/plugin-ai/scripts/examples/huggingface-inference-example.py +145 -0
- package/packages/plugin-ai/scripts/examples/langchain-rag-example.py +366 -0
- package/packages/plugin-ai/scripts/examples/mlflow-tracking-example.py +224 -0
- package/packages/plugin-ai/scripts/examples/openai-chat-example.py +425 -0
- package/packages/plugin-cloud/README.md +268 -0
- package/packages/plugin-cloud/agents/gemini-api-expert.md +880 -0
- package/packages/plugin-cloud/agents/openai-python-expert.md +1087 -0
- package/packages/plugin-cloud/commands/cloud-cost-optimize.md +243 -0
- package/packages/plugin-cloud/commands/cloud-validate.md +196 -0
- package/packages/plugin-cloud/hooks/pre-cloud-deploy.js +456 -0
- package/packages/plugin-cloud/package.json +64 -0
- package/packages/plugin-cloud/plugin.json +338 -0
- package/packages/plugin-cloud/rules/cloud-security-compliance.md +313 -0
- package/packages/plugin-cloud/scripts/examples/aws-validate.sh +30 -0
- package/packages/plugin-cloud/scripts/examples/azure-setup.sh +33 -0
- package/packages/plugin-cloud/scripts/examples/gcp-setup.sh +39 -0
- package/packages/plugin-cloud/scripts/examples/k8s-validate.sh +40 -0
- package/packages/plugin-cloud/scripts/examples/terraform-init.sh +26 -0
- package/packages/plugin-core/README.md +274 -0
- package/packages/plugin-core/commands/code-rabbit.md +128 -0
- package/packages/plugin-core/commands/prompt.md +9 -0
- package/packages/plugin-core/commands/re-init.md +9 -0
- package/packages/plugin-core/hooks/context7-reminder.md +29 -0
- package/packages/plugin-core/hooks/enforce-agents.js +125 -0
- package/packages/plugin-core/hooks/enforce-agents.sh +35 -0
- package/packages/plugin-core/hooks/pre-agent-context7.js +224 -0
- package/packages/plugin-core/hooks/pre-command-context7.js +229 -0
- package/packages/plugin-core/hooks/strict-enforce-agents.sh +39 -0
- package/packages/plugin-core/hooks/test-hook.sh +21 -0
- package/packages/plugin-core/hooks/unified-context7-enforcement.sh +38 -0
- package/packages/plugin-core/package.json +45 -0
- package/packages/plugin-core/plugin.json +387 -0
- package/packages/plugin-core/rules/agent-coordination.md +549 -0
- package/packages/plugin-core/rules/agent-mandatory.md +170 -0
- package/packages/plugin-core/rules/command-pipelines.md +208 -0
- package/packages/plugin-core/rules/context-optimization.md +176 -0
- package/packages/plugin-core/rules/context7-enforcement.md +327 -0
- package/packages/plugin-core/rules/datetime.md +122 -0
- package/packages/plugin-core/rules/definition-of-done.md +272 -0
- package/packages/plugin-core/rules/development-environments.md +19 -0
- package/packages/plugin-core/rules/development-workflow.md +198 -0
- package/packages/plugin-core/rules/framework-path-rules.md +180 -0
- package/packages/plugin-core/rules/frontmatter-operations.md +64 -0
- package/packages/plugin-core/rules/git-strategy.md +237 -0
- package/packages/plugin-core/rules/golden-rules.md +181 -0
- package/packages/plugin-core/rules/naming-conventions.md +111 -0
- package/packages/plugin-core/rules/no-pr-workflow.md +183 -0
- package/packages/plugin-core/rules/pipeline-mandatory.md +109 -0
- package/packages/plugin-core/rules/security-checklist.md +318 -0
- package/packages/plugin-core/rules/standard-patterns.md +197 -0
- package/packages/plugin-core/rules/strip-frontmatter.md +85 -0
- package/packages/plugin-core/rules/tdd.enforcement.md +103 -0
- package/packages/plugin-core/rules/use-ast-grep.md +113 -0
- package/packages/plugin-core/scripts/lib/datetime-utils.sh +254 -0
- package/packages/plugin-core/scripts/lib/frontmatter-utils.sh +294 -0
- package/packages/plugin-core/scripts/lib/github-utils.sh +221 -0
- package/packages/plugin-core/scripts/lib/logging-utils.sh +199 -0
- package/packages/plugin-core/scripts/lib/validation-utils.sh +339 -0
- package/packages/plugin-core/scripts/mcp/add.sh +7 -0
- package/packages/plugin-core/scripts/mcp/disable.sh +12 -0
- package/packages/plugin-core/scripts/mcp/enable.sh +12 -0
- package/packages/plugin-core/scripts/mcp/list.sh +7 -0
- package/packages/plugin-core/scripts/mcp/sync.sh +8 -0
- package/packages/plugin-data/README.md +315 -0
- package/packages/plugin-data/agents/airflow-orchestration-expert.md +158 -0
- package/packages/plugin-data/agents/kedro-pipeline-expert.md +304 -0
- package/packages/plugin-data/agents/langgraph-workflow-expert.md +530 -0
- package/packages/plugin-data/commands/airflow-dag-scaffold.md +413 -0
- package/packages/plugin-data/commands/kafka-pipeline-scaffold.md +503 -0
- package/packages/plugin-data/package.json +66 -0
- package/packages/plugin-data/plugin.json +294 -0
- package/packages/plugin-data/rules/data-quality-standards.md +373 -0
- package/packages/plugin-data/rules/etl-pipeline-standards.md +255 -0
- package/packages/plugin-data/scripts/examples/airflow-dag-example.py +245 -0
- package/packages/plugin-data/scripts/examples/dbt-transform-example.sql +238 -0
- package/packages/plugin-data/scripts/examples/kafka-streaming-example.py +257 -0
- package/packages/plugin-data/scripts/examples/pandas-etl-example.py +332 -0
- package/packages/plugin-databases/README.md +330 -0
- package/{autopm/.claude/agents/databases → packages/plugin-databases/agents}/bigquery-expert.md +24 -15
- package/{autopm/.claude/agents/databases → packages/plugin-databases/agents}/cosmosdb-expert.md +22 -15
- package/{autopm/.claude/agents/databases → packages/plugin-databases/agents}/mongodb-expert.md +24 -15
- package/{autopm/.claude/agents/databases → packages/plugin-databases/agents}/postgresql-expert.md +23 -15
- package/{autopm/.claude/agents/databases → packages/plugin-databases/agents}/redis-expert.md +29 -7
- package/packages/plugin-databases/commands/db-optimize.md +612 -0
- package/packages/plugin-databases/package.json +60 -0
- package/packages/plugin-databases/plugin.json +237 -0
- package/packages/plugin-databases/rules/database-management-strategy.md +146 -0
- package/packages/plugin-databases/rules/database-pipeline.md +316 -0
- package/packages/plugin-databases/scripts/examples/bigquery-cost-analyze.sh +160 -0
- package/packages/plugin-databases/scripts/examples/cosmosdb-ru-optimize.sh +163 -0
- package/packages/plugin-databases/scripts/examples/mongodb-shard-check.sh +120 -0
- package/packages/plugin-databases/scripts/examples/postgres-index-analyze.sh +95 -0
- package/packages/plugin-databases/scripts/examples/redis-cache-stats.sh +121 -0
- package/packages/plugin-devops/README.md +367 -0
- package/{autopm/.claude/agents/devops → packages/plugin-devops/agents}/github-operations-specialist.md +1 -1
- package/packages/plugin-devops/commands/ci-pipeline-create.md +581 -0
- package/packages/plugin-devops/commands/docker-optimize.md +493 -0
- package/packages/plugin-devops/hooks/pre-docker-build.js +472 -0
- package/packages/plugin-devops/package.json +61 -0
- package/packages/plugin-devops/plugin.json +302 -0
- package/packages/plugin-devops/rules/github-operations.md +92 -0
- package/packages/plugin-devops/scripts/examples/docker-build-multistage.sh +43 -0
- package/packages/plugin-devops/scripts/examples/docker-compose-validate.sh +74 -0
- package/packages/plugin-devops/scripts/examples/github-workflow-validate.sh +48 -0
- package/packages/plugin-devops/scripts/examples/prometheus-health-check.sh +58 -0
- package/packages/plugin-devops/scripts/examples/ssh-key-setup.sh +74 -0
- package/packages/plugin-frameworks/README.md +309 -0
- package/{autopm/.claude/agents/frameworks → packages/plugin-frameworks/agents}/e2e-test-engineer.md +219 -0
- package/{autopm/.claude/agents/frameworks → packages/plugin-frameworks/agents}/react-frontend-engineer.md +176 -0
- package/{autopm/.claude/agents/frameworks → packages/plugin-frameworks/agents}/tailwindcss-expert.md +251 -0
- package/packages/plugin-frameworks/commands/nextjs-optimize.md +692 -0
- package/packages/plugin-frameworks/commands/react-optimize.md +583 -0
- package/packages/plugin-frameworks/package.json +59 -0
- package/packages/plugin-frameworks/plugin.json +224 -0
- package/packages/plugin-frameworks/rules/performance-guidelines.md +403 -0
- package/packages/plugin-frameworks/scripts/examples/react-component-perf.sh +34 -0
- package/packages/plugin-frameworks/scripts/examples/tailwind-optimize.sh +44 -0
- package/packages/plugin-frameworks/scripts/examples/vue-composition-check.sh +41 -0
- package/packages/plugin-languages/README.md +333 -0
- package/packages/plugin-languages/commands/javascript-optimize.md +636 -0
- package/packages/plugin-languages/commands/nodejs-api-scaffold.md +341 -0
- package/packages/plugin-languages/commands/nodejs-optimize.md +689 -0
- package/packages/plugin-languages/commands/python-api-scaffold.md +261 -0
- package/packages/plugin-languages/commands/python-optimize.md +593 -0
- package/packages/plugin-languages/package.json +65 -0
- package/packages/plugin-languages/plugin.json +265 -0
- package/packages/plugin-languages/rules/code-quality-standards.md +496 -0
- package/packages/plugin-languages/rules/testing-standards.md +768 -0
- package/packages/plugin-languages/scripts/examples/bash-production-script.sh +520 -0
- package/packages/plugin-languages/scripts/examples/javascript-es6-patterns.js +291 -0
- package/packages/plugin-languages/scripts/examples/nodejs-async-iteration.js +360 -0
- package/packages/plugin-languages/scripts/examples/python-async-patterns.py +289 -0
- package/packages/plugin-languages/scripts/examples/typescript-patterns.ts +432 -0
- package/packages/plugin-ml/README.md +430 -0
- package/packages/plugin-ml/agents/automl-expert.md +326 -0
- package/packages/plugin-ml/agents/computer-vision-expert.md +550 -0
- package/packages/plugin-ml/agents/gradient-boosting-expert.md +455 -0
- package/packages/plugin-ml/agents/neural-network-architect.md +1228 -0
- package/packages/plugin-ml/agents/nlp-transformer-expert.md +584 -0
- package/packages/plugin-ml/agents/pytorch-expert.md +412 -0
- package/packages/plugin-ml/agents/reinforcement-learning-expert.md +2088 -0
- package/packages/plugin-ml/agents/scikit-learn-expert.md +228 -0
- package/packages/plugin-ml/agents/tensorflow-keras-expert.md +509 -0
- package/packages/plugin-ml/agents/time-series-expert.md +303 -0
- package/packages/plugin-ml/commands/ml-automl.md +572 -0
- package/packages/plugin-ml/commands/ml-train-optimize.md +657 -0
- package/packages/plugin-ml/package.json +52 -0
- package/packages/plugin-ml/plugin.json +338 -0
- package/packages/plugin-pm/README.md +368 -0
- package/packages/plugin-pm/claudeautopm-plugin-pm-2.0.0.tgz +0 -0
- package/packages/plugin-pm/commands/github/workflow-create.md +42 -0
- package/packages/plugin-pm/package.json +57 -0
- package/packages/plugin-pm/plugin.json +503 -0
- package/packages/plugin-testing/README.md +401 -0
- package/{autopm/.claude/agents/testing → packages/plugin-testing/agents}/frontend-testing-engineer.md +373 -0
- package/packages/plugin-testing/commands/jest-optimize.md +800 -0
- package/packages/plugin-testing/commands/playwright-optimize.md +887 -0
- package/packages/plugin-testing/commands/test-coverage.md +512 -0
- package/packages/plugin-testing/commands/test-performance.md +1041 -0
- package/packages/plugin-testing/commands/test-setup.md +414 -0
- package/packages/plugin-testing/package.json +40 -0
- package/packages/plugin-testing/plugin.json +197 -0
- package/packages/plugin-testing/rules/test-coverage-requirements.md +581 -0
- package/packages/plugin-testing/rules/testing-standards.md +529 -0
- package/packages/plugin-testing/scripts/examples/react-testing-example.test.jsx +460 -0
- package/packages/plugin-testing/scripts/examples/vitest-config-example.js +352 -0
- package/packages/plugin-testing/scripts/examples/vue-testing-example.test.js +586 -0
- package/scripts/publish-plugins.sh +166 -0
- package/autopm/.claude/agents/data/airflow-orchestration-expert.md +0 -52
- package/autopm/.claude/agents/data/kedro-pipeline-expert.md +0 -50
- package/autopm/.claude/agents/integration/message-queue-engineer.md +0 -794
- package/autopm/.claude/commands/ai/langgraph-workflow.md +0 -65
- package/autopm/.claude/commands/ai/openai-chat.md +0 -65
- package/autopm/.claude/commands/playwright/test-scaffold.md +0 -38
- package/autopm/.claude/commands/python/api-scaffold.md +0 -50
- package/autopm/.claude/commands/python/docs-query.md +0 -48
- package/autopm/.claude/commands/testing/prime.md +0 -314
- package/autopm/.claude/commands/testing/run.md +0 -125
- package/autopm/.claude/commands/ui/bootstrap-scaffold.md +0 -65
- package/autopm/.claude/rules/database-management-strategy.md +0 -17
- package/autopm/.claude/rules/database-pipeline.md +0 -94
- package/autopm/.claude/rules/ux-design-rules.md +0 -209
- package/autopm/.claude/rules/visual-testing.md +0 -223
- package/autopm/.claude/scripts/azure/README.md +0 -192
- package/autopm/.claude/scripts/azure/active-work.js +0 -524
- package/autopm/.claude/scripts/azure/active-work.sh +0 -20
- package/autopm/.claude/scripts/azure/blocked.js +0 -520
- package/autopm/.claude/scripts/azure/blocked.sh +0 -20
- package/autopm/.claude/scripts/azure/daily.js +0 -533
- package/autopm/.claude/scripts/azure/daily.sh +0 -20
- package/autopm/.claude/scripts/azure/dashboard.js +0 -970
- package/autopm/.claude/scripts/azure/dashboard.sh +0 -20
- package/autopm/.claude/scripts/azure/feature-list.js +0 -254
- package/autopm/.claude/scripts/azure/feature-list.sh +0 -20
- package/autopm/.claude/scripts/azure/feature-show.js +0 -7
- package/autopm/.claude/scripts/azure/feature-show.sh +0 -20
- package/autopm/.claude/scripts/azure/feature-status.js +0 -604
- package/autopm/.claude/scripts/azure/feature-status.sh +0 -20
- package/autopm/.claude/scripts/azure/help.js +0 -342
- package/autopm/.claude/scripts/azure/help.sh +0 -20
- package/autopm/.claude/scripts/azure/next-task.js +0 -508
- package/autopm/.claude/scripts/azure/next-task.sh +0 -20
- package/autopm/.claude/scripts/azure/search.js +0 -469
- package/autopm/.claude/scripts/azure/search.sh +0 -20
- package/autopm/.claude/scripts/azure/setup.js +0 -745
- package/autopm/.claude/scripts/azure/setup.sh +0 -20
- package/autopm/.claude/scripts/azure/sprint-report.js +0 -1012
- package/autopm/.claude/scripts/azure/sprint-report.sh +0 -20
- package/autopm/.claude/scripts/azure/sync.js +0 -563
- package/autopm/.claude/scripts/azure/sync.sh +0 -20
- package/autopm/.claude/scripts/azure/us-list.js +0 -210
- package/autopm/.claude/scripts/azure/us-list.sh +0 -20
- package/autopm/.claude/scripts/azure/us-status.js +0 -238
- package/autopm/.claude/scripts/azure/us-status.sh +0 -20
- package/autopm/.claude/scripts/azure/validate.js +0 -626
- package/autopm/.claude/scripts/azure/validate.sh +0 -20
- package/autopm/.claude/scripts/azure/wrapper-template.sh +0 -20
- package/autopm/.claude/scripts/github/dependency-tracker.js +0 -554
- package/autopm/.claude/scripts/github/dependency-validator.js +0 -545
- package/autopm/.claude/scripts/github/dependency-visualizer.js +0 -477
- package/bin/node/azure-feature-show.js +0 -7
- /package/{autopm/.claude/agents/cloud → packages/plugin-ai/agents}/gemini-api-expert.md +0 -0
- /package/{autopm/.claude/agents/data → packages/plugin-ai/agents}/langgraph-workflow-expert.md +0 -0
- /package/{autopm/.claude/agents/cloud → packages/plugin-ai/agents}/openai-python-expert.md +0 -0
- /package/{autopm/.claude/agents/cloud → packages/plugin-cloud/agents}/README.md +0 -0
- /package/{autopm/.claude/agents/cloud → packages/plugin-cloud/agents}/aws-cloud-architect.md +0 -0
- /package/{autopm/.claude/agents/cloud → packages/plugin-cloud/agents}/azure-cloud-architect.md +0 -0
- /package/{autopm/.claude/agents/cloud → packages/plugin-cloud/agents}/gcp-cloud-architect.md +0 -0
- /package/{autopm/.claude/agents/cloud → packages/plugin-cloud/agents}/gcp-cloud-functions-engineer.md +0 -0
- /package/{autopm/.claude/agents/cloud → packages/plugin-cloud/agents}/kubernetes-orchestrator.md +0 -0
- /package/{autopm/.claude/agents/cloud → packages/plugin-cloud/agents}/terraform-infrastructure-expert.md +0 -0
- /package/{autopm/.claude/commands/cloud → packages/plugin-cloud/commands}/infra-deploy.md +0 -0
- /package/{autopm/.claude/commands/kubernetes/deploy.md → packages/plugin-cloud/commands/k8s-deploy.md} +0 -0
- /package/{autopm/.claude/commands/infrastructure → packages/plugin-cloud/commands}/ssh-security.md +0 -0
- /package/{autopm/.claude/commands/infrastructure → packages/plugin-cloud/commands}/traefik-setup.md +0 -0
- /package/{autopm/.claude → packages/plugin-cloud}/rules/infrastructure-pipeline.md +0 -0
- /package/{autopm/.claude → packages/plugin-core}/agents/core/agent-manager.md +0 -0
- /package/{autopm/.claude → packages/plugin-core}/agents/core/code-analyzer.md +0 -0
- /package/{autopm/.claude → packages/plugin-core}/agents/core/file-analyzer.md +0 -0
- /package/{autopm/.claude → packages/plugin-core}/agents/core/test-runner.md +0 -0
- /package/{autopm/.claude → packages/plugin-core}/rules/ai-integration-patterns.md +0 -0
- /package/{autopm/.claude → packages/plugin-core}/rules/performance-guidelines.md +0 -0
- /package/{autopm/.claude/agents/databases → packages/plugin-databases/agents}/README.md +0 -0
- /package/{autopm/.claude/agents/devops → packages/plugin-devops/agents}/README.md +0 -0
- /package/{autopm/.claude/agents/devops → packages/plugin-devops/agents}/azure-devops-specialist.md +0 -0
- /package/{autopm/.claude/agents/devops → packages/plugin-devops/agents}/docker-containerization-expert.md +0 -0
- /package/{autopm/.claude/agents/devops → packages/plugin-devops/agents}/mcp-context-manager.md +0 -0
- /package/{autopm/.claude/agents/devops → packages/plugin-devops/agents}/observability-engineer.md +0 -0
- /package/{autopm/.claude/agents/devops → packages/plugin-devops/agents}/ssh-operations-expert.md +0 -0
- /package/{autopm/.claude/agents/devops → packages/plugin-devops/agents}/traefik-proxy-expert.md +0 -0
- /package/{autopm/.claude/commands/github → packages/plugin-devops/commands}/workflow-create.md +0 -0
- /package/{autopm/.claude → packages/plugin-devops}/rules/ci-cd-kubernetes-strategy.md +0 -0
- /package/{autopm/.claude → packages/plugin-devops}/rules/devops-troubleshooting-playbook.md +0 -0
- /package/{autopm/.claude → packages/plugin-devops}/rules/docker-first-development.md +0 -0
- /package/{autopm/.claude/agents/frameworks → packages/plugin-frameworks/agents}/README.md +0 -0
- /package/{autopm/.claude/agents/frameworks → packages/plugin-frameworks/agents}/nats-messaging-expert.md +0 -0
- /package/{autopm/.claude/agents/frameworks → packages/plugin-frameworks/agents}/react-ui-expert.md +0 -0
- /package/{autopm/.claude/agents/frameworks → packages/plugin-frameworks/agents}/ux-design-expert.md +0 -0
- /package/{autopm/.claude/commands/react → packages/plugin-frameworks/commands}/app-scaffold.md +0 -0
- /package/{autopm/.claude/commands/ui → packages/plugin-frameworks/commands}/tailwind-system.md +0 -0
- /package/{autopm/.claude → packages/plugin-frameworks}/rules/ui-development-standards.md +0 -0
- /package/{autopm/.claude → packages/plugin-frameworks}/rules/ui-framework-rules.md +0 -0
- /package/{autopm/.claude/agents/languages → packages/plugin-languages/agents}/README.md +0 -0
- /package/{autopm/.claude/agents/languages → packages/plugin-languages/agents}/bash-scripting-expert.md +0 -0
- /package/{autopm/.claude/agents/languages → packages/plugin-languages/agents}/javascript-frontend-engineer.md +0 -0
- /package/{autopm/.claude/agents/languages → packages/plugin-languages/agents}/nodejs-backend-engineer.md +0 -0
- /package/{autopm/.claude/agents/languages → packages/plugin-languages/agents}/python-backend-engineer.md +0 -0
- /package/{autopm/.claude/agents/languages → packages/plugin-languages/agents}/python-backend-expert.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/COMMANDS.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/COMMAND_MAPPING.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/INTEGRATION_FIX.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/README.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/active-work.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/aliases.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/blocked-items.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/clean.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/docs-query.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/feature-decompose.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/feature-list.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/feature-new.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/feature-show.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/feature-start.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/fix-integration-example.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/help.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/import-us.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/init.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/next-task.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/search.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/sprint-status.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/standup.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/sync-all.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/task-analyze.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/task-close.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/task-edit.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/task-list.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/task-new.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/task-reopen.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/task-show.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/task-start.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/task-status.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/task-sync.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/us-edit.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/us-list.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/us-new.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/us-parse.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/us-show.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/us-status.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/validate.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/commands/azure/work-item-sync.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/blocked.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/clean.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/context-create.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/context-prime.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/context-update.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/context.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/epic-close.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/epic-decompose.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/epic-edit.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/epic-list.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/epic-merge.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/epic-oneshot.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/epic-refresh.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/epic-show.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/epic-split.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/epic-start.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/epic-status.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/epic-sync-modular.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/epic-sync-original.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/epic-sync.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/help.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/import.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/in-progress.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/init.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/issue-analyze.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/issue-close.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/issue-edit.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/issue-reopen.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/issue-show.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/issue-start.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/issue-status.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/issue-sync.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/next.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/prd-edit.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/prd-list.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/prd-new.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/prd-parse.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/prd-status.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/search.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/standup.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/status.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/sync.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/test-reference-update.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/validate.md +0 -0
- /package/{autopm/.claude/commands/pm → packages/plugin-pm/commands}/what-next.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/analytics.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/blocked.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/blocked.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/clean.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/context-create.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/context-prime.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/context-update.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/context.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/epic-close.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/epic-edit.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/epic-list.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/epic-list.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/epic-show.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/epic-show.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/epic-split.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/epic-start/epic-start.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/epic-start/epic-start.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/epic-status.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/epic-status.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/epic-sync/README.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/epic-sync/create-epic-issue.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/epic-sync/create-task-issues.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/epic-sync/update-epic-file.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/epic-sync/update-references.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/epic-sync.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/help.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/help.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/in-progress.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/in-progress.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/init.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/init.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/issue-close.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/issue-edit.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/issue-show.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/issue-start.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/issue-sync/format-comment.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/issue-sync/gather-updates.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/issue-sync/post-comment.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/issue-sync/preflight-validation.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/issue-sync/update-frontmatter.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/lib/README.md +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/lib/epic-discovery.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/lib/logger.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/next.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/next.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/optimize.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/pr-create.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/pr-list.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/prd-list.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/prd-list.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/prd-new.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/prd-parse.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/prd-status.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/prd-status.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/release.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/search.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/search.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/standup.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/standup.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/status.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/status.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/sync-batch.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/sync.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/template-list.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/template-new.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/validate.js +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/validate.sh +0 -0
- /package/{autopm/.claude → packages/plugin-pm}/scripts/pm/what-next.js +0 -0
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
# Testing Standards Rule
|
|
2
|
+
|
|
3
|
+
**Rule Name**: testing-standards
|
|
4
|
+
**Priority**: High
|
|
5
|
+
**Applies To**: commands, agents
|
|
6
|
+
**Enforces On**: frontend-testing-engineer
|
|
7
|
+
|
|
8
|
+
## Description
|
|
9
|
+
|
|
10
|
+
Comprehensive testing standards with Context7-verified best practices for unit, integration, and E2E tests. This rule ensures all tests follow industry-standard patterns from official testing framework documentation.
|
|
11
|
+
|
|
12
|
+
## Context7 Documentation Sources
|
|
13
|
+
|
|
14
|
+
**MANDATORY:** All testing implementations must reference these Context7 sources:
|
|
15
|
+
|
|
16
|
+
- `/vitest-dev/vitest` - Vitest testing framework patterns
|
|
17
|
+
- `/testing-library/testing-library-docs` - Testing Library query patterns
|
|
18
|
+
- `/testing-library/react-testing-library` - React Testing Library best practices
|
|
19
|
+
- `/jestjs/jest` - Jest testing framework (when applicable)
|
|
20
|
+
|
|
21
|
+
## Core Testing Principles
|
|
22
|
+
|
|
23
|
+
### 1. Test-Driven Development (TDD)
|
|
24
|
+
|
|
25
|
+
**MANDATORY for all new features:**
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
Red-Green-Refactor Cycle:
|
|
29
|
+
┌──────────────────────────────────────┐
|
|
30
|
+
│ 1. RED: Write failing test first │
|
|
31
|
+
│ ↓ │
|
|
32
|
+
│ 2. GREEN: Write minimum code to pass│
|
|
33
|
+
│ ↓ │
|
|
34
|
+
│ 3. REFACTOR: Improve code quality │
|
|
35
|
+
│ ↓ │
|
|
36
|
+
│ 4. REPEAT for next feature │
|
|
37
|
+
└──────────────────────────────────────┘
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Example:**
|
|
41
|
+
```javascript
|
|
42
|
+
// ✅ CORRECT TDD Flow
|
|
43
|
+
// Step 1: Write failing test FIRST
|
|
44
|
+
test('should calculate total price', () => {
|
|
45
|
+
expect(calculateTotal([10, 20, 30])).toBe(60);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Step 2: Implement minimum code
|
|
49
|
+
function calculateTotal(prices) {
|
|
50
|
+
return prices.reduce((sum, price) => sum + price, 0);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Step 3: Refactor if needed
|
|
54
|
+
function calculateTotal(prices) {
|
|
55
|
+
if (!Array.isArray(prices)) throw new Error('Invalid input');
|
|
56
|
+
return prices.reduce((sum, price) => sum + price, 0);
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 2. Query Priority (Testing Library Standard)
|
|
61
|
+
|
|
62
|
+
**MANDATORY:** Follow Testing Library's query priority hierarchy:
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
// Priority 1: Accessible to Everyone (BEST)
|
|
66
|
+
// ✅ Queries accessible to screen readers and users
|
|
67
|
+
screen.getByRole('button', { name: 'Submit' })
|
|
68
|
+
screen.getByLabelText('Email address')
|
|
69
|
+
screen.getByPlaceholderText('Enter your name')
|
|
70
|
+
screen.getByText('Welcome back!')
|
|
71
|
+
screen.getByDisplayValue('current value')
|
|
72
|
+
|
|
73
|
+
// Priority 2: Semantic Queries (GOOD)
|
|
74
|
+
// ✅ Queries that match HTML semantics
|
|
75
|
+
screen.getByAltText('Profile picture')
|
|
76
|
+
screen.getByTitle('Close dialog')
|
|
77
|
+
|
|
78
|
+
// Priority 3: Test IDs (ACCEPTABLE)
|
|
79
|
+
// ⚠️ Only when semantic queries don't work
|
|
80
|
+
screen.getByTestId('custom-element')
|
|
81
|
+
|
|
82
|
+
// Priority 4: CSS Selectors (AVOID)
|
|
83
|
+
// ❌ Tied to implementation, breaks easily
|
|
84
|
+
container.querySelector('.submit-button') // DON'T USE
|
|
85
|
+
container.querySelector('#email-input') // DON'T USE
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 3. Test Independence
|
|
89
|
+
|
|
90
|
+
**MANDATORY:** Each test must be completely independent:
|
|
91
|
+
|
|
92
|
+
```javascript
|
|
93
|
+
// ❌ WRONG: Tests depend on each other
|
|
94
|
+
let user = null;
|
|
95
|
+
|
|
96
|
+
test('creates user', () => {
|
|
97
|
+
user = { id: 1, name: 'John' };
|
|
98
|
+
expect(user).toBeTruthy();
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test('updates user', () => {
|
|
102
|
+
user.name = 'Jane'; // Depends on previous test
|
|
103
|
+
expect(user.name).toBe('Jane');
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// ✅ CORRECT: Independent tests
|
|
107
|
+
describe('User operations', () => {
|
|
108
|
+
beforeEach(() => {
|
|
109
|
+
// Fresh state for each test
|
|
110
|
+
mockDatabase.reset();
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
test('creates user', () => {
|
|
114
|
+
const user = createUser({ name: 'John' });
|
|
115
|
+
expect(user).toEqual({ id: 1, name: 'John' });
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
test('updates user', () => {
|
|
119
|
+
const user = createUser({ name: 'John' });
|
|
120
|
+
const updated = updateUser(user.id, { name: 'Jane' });
|
|
121
|
+
expect(updated.name).toBe('Jane');
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### 4. Async Testing Best Practices
|
|
127
|
+
|
|
128
|
+
**MANDATORY:** Use Testing Library's async utilities:
|
|
129
|
+
|
|
130
|
+
```javascript
|
|
131
|
+
// ❌ WRONG: Manual delays
|
|
132
|
+
test('shows data after loading', async () => {
|
|
133
|
+
render(<DataDisplay />);
|
|
134
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
135
|
+
expect(screen.getByText('Data loaded')).toBeInTheDocument();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// ✅ CORRECT: Async utilities with auto-retry
|
|
139
|
+
test('shows data after loading', async () => {
|
|
140
|
+
render(<DataDisplay />);
|
|
141
|
+
|
|
142
|
+
// Automatically waits and retries
|
|
143
|
+
expect(await screen.findByText('Data loaded')).toBeInTheDocument();
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// ✅ CORRECT: waitFor for complex conditions
|
|
147
|
+
test('shows updated count', async () => {
|
|
148
|
+
render(<Counter />);
|
|
149
|
+
|
|
150
|
+
await userEvent.click(screen.getByRole('button', { name: 'Increment' }));
|
|
151
|
+
|
|
152
|
+
await waitFor(() => {
|
|
153
|
+
expect(screen.getByText('Count: 1')).toBeInTheDocument();
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### 5. User-Centric Testing
|
|
159
|
+
|
|
160
|
+
**MANDATORY:** Test behavior, not implementation:
|
|
161
|
+
|
|
162
|
+
```javascript
|
|
163
|
+
// ❌ WRONG: Testing implementation details
|
|
164
|
+
test('sets loading state to true', () => {
|
|
165
|
+
const { result } = renderHook(() => useData());
|
|
166
|
+
expect(result.current.loading).toBe(true); // Internal state
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
// ✅ CORRECT: Testing user-visible behavior
|
|
170
|
+
test('shows loading indicator while fetching', () => {
|
|
171
|
+
render(<DataComponent />);
|
|
172
|
+
expect(screen.getByText('Loading...')).toBeInTheDocument();
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// ❌ WRONG: Accessing component internals
|
|
176
|
+
test('updates state on click', () => {
|
|
177
|
+
const wrapper = shallow(<Component />);
|
|
178
|
+
wrapper.find('button').simulate('click');
|
|
179
|
+
expect(wrapper.state('clicked')).toBe(true);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
// ✅ CORRECT: Testing user interactions
|
|
183
|
+
test('shows success message after submit', async () => {
|
|
184
|
+
const user = userEvent.setup();
|
|
185
|
+
render(<Form />);
|
|
186
|
+
|
|
187
|
+
await user.click(screen.getByRole('button', { name: 'Submit' }));
|
|
188
|
+
|
|
189
|
+
expect(await screen.findByText('Success!')).toBeInTheDocument();
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Test Structure Standards
|
|
194
|
+
|
|
195
|
+
### AAA Pattern (Arrange-Act-Assert)
|
|
196
|
+
|
|
197
|
+
**MANDATORY for all tests:**
|
|
198
|
+
|
|
199
|
+
```javascript
|
|
200
|
+
test('user can log in with valid credentials', async () => {
|
|
201
|
+
// ARRANGE: Set up test data and environment
|
|
202
|
+
const user = userEvent.setup();
|
|
203
|
+
const credentials = { email: 'user@example.com', password: 'pass123' };
|
|
204
|
+
render(<LoginForm />);
|
|
205
|
+
|
|
206
|
+
// ACT: Perform the action being tested
|
|
207
|
+
await user.type(screen.getByLabelText('Email'), credentials.email);
|
|
208
|
+
await user.type(screen.getByLabelText('Password'), credentials.password);
|
|
209
|
+
await user.click(screen.getByRole('button', { name: 'Log in' }));
|
|
210
|
+
|
|
211
|
+
// ASSERT: Verify expected outcome
|
|
212
|
+
expect(await screen.findByText('Welcome!')).toBeInTheDocument();
|
|
213
|
+
});
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Descriptive Test Names
|
|
217
|
+
|
|
218
|
+
**MANDATORY:** Test names must describe behavior:
|
|
219
|
+
|
|
220
|
+
```javascript
|
|
221
|
+
// ❌ WRONG: Vague test names
|
|
222
|
+
test('it works', () => { });
|
|
223
|
+
test('button', () => { });
|
|
224
|
+
test('user test', () => { });
|
|
225
|
+
|
|
226
|
+
// ✅ CORRECT: Descriptive behavior-focused names
|
|
227
|
+
test('should display error message when email is invalid', () => { });
|
|
228
|
+
test('should navigate to dashboard after successful login', () => { });
|
|
229
|
+
test('should disable submit button while form is submitting', () => { });
|
|
230
|
+
|
|
231
|
+
// ✅ CORRECT: Organized with describe blocks
|
|
232
|
+
describe('LoginForm', () => {
|
|
233
|
+
describe('when user provides valid credentials', () => {
|
|
234
|
+
test('should successfully log in', () => { });
|
|
235
|
+
test('should clear form fields', () => { });
|
|
236
|
+
test('should redirect to dashboard', () => { });
|
|
237
|
+
});
|
|
238
|
+
|
|
239
|
+
describe('when user provides invalid credentials', () => {
|
|
240
|
+
test('should display error message', () => { });
|
|
241
|
+
test('should keep user on login page', () => { });
|
|
242
|
+
test('should clear password field', () => { });
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Coverage Standards
|
|
248
|
+
|
|
249
|
+
### Minimum Coverage Thresholds
|
|
250
|
+
|
|
251
|
+
**MANDATORY:** All new code must meet these thresholds:
|
|
252
|
+
|
|
253
|
+
```javascript
|
|
254
|
+
// vitest.config.js
|
|
255
|
+
export default {
|
|
256
|
+
test: {
|
|
257
|
+
coverage: {
|
|
258
|
+
thresholds: {
|
|
259
|
+
lines: 80, // Minimum 80% line coverage
|
|
260
|
+
functions: 80, // Minimum 80% function coverage
|
|
261
|
+
branches: 75, // Minimum 75% branch coverage
|
|
262
|
+
statements: 80 // Minimum 80% statement coverage
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### What to Exclude from Coverage
|
|
270
|
+
|
|
271
|
+
```javascript
|
|
272
|
+
// ✅ CORRECT: Exclude non-testable code
|
|
273
|
+
coverage: {
|
|
274
|
+
exclude: [
|
|
275
|
+
'node_modules/',
|
|
276
|
+
'test/',
|
|
277
|
+
'**/*.config.js',
|
|
278
|
+
'**/*.spec.js',
|
|
279
|
+
'**/*.test.js',
|
|
280
|
+
'src/main.js', // App entry point
|
|
281
|
+
'src/index.js', // Entry point
|
|
282
|
+
'src/**/*.d.ts', // Type definitions
|
|
283
|
+
'src/constants.js', // Pure constants
|
|
284
|
+
'src/types.js' // Type exports
|
|
285
|
+
]
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### Coverage Quality over Quantity
|
|
290
|
+
|
|
291
|
+
```
|
|
292
|
+
Coverage Checklist:
|
|
293
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
294
|
+
|
|
295
|
+
❌ 100% coverage with poor tests:
|
|
296
|
+
- Tests that only check code executes
|
|
297
|
+
- No assertions about correctness
|
|
298
|
+
- Testing implementation details
|
|
299
|
+
- Brittle tests that break easily
|
|
300
|
+
|
|
301
|
+
✅ 80% coverage with quality tests:
|
|
302
|
+
- Tests verify correct behavior
|
|
303
|
+
- Tests check edge cases
|
|
304
|
+
- Tests use semantic queries
|
|
305
|
+
- Tests are maintainable
|
|
306
|
+
- Tests document expected behavior
|
|
307
|
+
|
|
308
|
+
💡 Focus on test quality, not just coverage numbers!
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## Mocking Standards
|
|
312
|
+
|
|
313
|
+
### API Mocking (Recommended: MSW)
|
|
314
|
+
|
|
315
|
+
```javascript
|
|
316
|
+
// ✅ CORRECT: Mock at network level with MSW
|
|
317
|
+
import { rest } from 'msw';
|
|
318
|
+
import { setupServer } from 'msw/node';
|
|
319
|
+
|
|
320
|
+
const server = setupServer(
|
|
321
|
+
rest.get('/api/user/:id', (req, res, ctx) => {
|
|
322
|
+
return res(ctx.json({ id: req.params.id, name: 'Test User' }));
|
|
323
|
+
})
|
|
324
|
+
);
|
|
325
|
+
|
|
326
|
+
beforeAll(() => server.listen());
|
|
327
|
+
afterEach(() => server.resetHandlers());
|
|
328
|
+
afterAll(() => server.close());
|
|
329
|
+
|
|
330
|
+
test('fetches user data', async () => {
|
|
331
|
+
render(<UserProfile userId={1} />);
|
|
332
|
+
|
|
333
|
+
expect(await screen.findByText('Test User')).toBeInTheDocument();
|
|
334
|
+
});
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Module Mocking (When Necessary)
|
|
338
|
+
|
|
339
|
+
```javascript
|
|
340
|
+
// ✅ CORRECT: Mock external dependencies
|
|
341
|
+
import { vi } from 'vitest';
|
|
342
|
+
|
|
343
|
+
vi.mock('../services/analytics', () => ({
|
|
344
|
+
trackEvent: vi.fn(),
|
|
345
|
+
trackPageView: vi.fn()
|
|
346
|
+
}));
|
|
347
|
+
|
|
348
|
+
test('tracks button click', async () => {
|
|
349
|
+
const { trackEvent } = await import('../services/analytics');
|
|
350
|
+
render(<Button />);
|
|
351
|
+
|
|
352
|
+
await userEvent.click(screen.getByRole('button'));
|
|
353
|
+
|
|
354
|
+
expect(trackEvent).toHaveBeenCalledWith('button_click');
|
|
355
|
+
});
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
## Accessibility Testing
|
|
359
|
+
|
|
360
|
+
**MANDATORY for UI components:**
|
|
361
|
+
|
|
362
|
+
```javascript
|
|
363
|
+
import { axe, toHaveNoViolations } from 'jest-axe';
|
|
364
|
+
expect.extend(toHaveNoViolations);
|
|
365
|
+
|
|
366
|
+
test('should have no accessibility violations', async () => {
|
|
367
|
+
const { container } = render(<MyComponent />);
|
|
368
|
+
const results = await axe(container);
|
|
369
|
+
expect(results).toHaveNoViolations();
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
// ✅ Test keyboard navigation
|
|
373
|
+
test('should be keyboard navigable', async () => {
|
|
374
|
+
const user = userEvent.setup();
|
|
375
|
+
render(<Form />);
|
|
376
|
+
|
|
377
|
+
// Tab through form fields
|
|
378
|
+
await user.tab();
|
|
379
|
+
expect(screen.getByLabelText('Name')).toHaveFocus();
|
|
380
|
+
|
|
381
|
+
await user.tab();
|
|
382
|
+
expect(screen.getByLabelText('Email')).toHaveFocus();
|
|
383
|
+
});
|
|
384
|
+
|
|
385
|
+
// ✅ Test screen reader text
|
|
386
|
+
test('should have descriptive aria-label', () => {
|
|
387
|
+
render(<IconButton icon="close" />);
|
|
388
|
+
|
|
389
|
+
expect(screen.getByRole('button', { name: 'Close dialog' }))
|
|
390
|
+
.toBeInTheDocument();
|
|
391
|
+
});
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
## Performance Testing
|
|
395
|
+
|
|
396
|
+
```javascript
|
|
397
|
+
// ✅ Test component rendering performance
|
|
398
|
+
test('should render large list efficiently', () => {
|
|
399
|
+
const items = Array.from({ length: 10000 }, (_, i) => ({ id: i }));
|
|
400
|
+
|
|
401
|
+
const start = performance.now();
|
|
402
|
+
render(<VirtualizedList items={items} />);
|
|
403
|
+
const duration = performance.now() - start;
|
|
404
|
+
|
|
405
|
+
expect(duration).toBeLessThan(100); // Should render in < 100ms
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
// ✅ Use Vitest's benchmark feature
|
|
409
|
+
import { bench, describe } from 'vitest';
|
|
410
|
+
|
|
411
|
+
describe('Array operations', () => {
|
|
412
|
+
bench('Array.push', () => {
|
|
413
|
+
const arr = [];
|
|
414
|
+
for (let i = 0; i < 1000; i++) {
|
|
415
|
+
arr.push(i);
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
bench('Array spread', () => {
|
|
420
|
+
let arr = [];
|
|
421
|
+
for (let i = 0; i < 1000; i++) {
|
|
422
|
+
arr = [...arr, i];
|
|
423
|
+
}
|
|
424
|
+
});
|
|
425
|
+
});
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
## Anti-Patterns to Avoid
|
|
429
|
+
|
|
430
|
+
### ❌ Don't Test Third-Party Libraries
|
|
431
|
+
|
|
432
|
+
```javascript
|
|
433
|
+
// ❌ WRONG: Testing React itself
|
|
434
|
+
test('useState works', () => {
|
|
435
|
+
const { result } = renderHook(() => useState(0));
|
|
436
|
+
expect(result.current[0]).toBe(0); // Don't test React
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
// ✅ CORRECT: Test your component behavior
|
|
440
|
+
test('counter increments when button clicked', async () => {
|
|
441
|
+
render(<Counter />);
|
|
442
|
+
await userEvent.click(screen.getByRole('button', { name: 'Increment' }));
|
|
443
|
+
expect(screen.getByText('Count: 1')).toBeInTheDocument();
|
|
444
|
+
});
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### ❌ Don't Use Snapshot Testing for Everything
|
|
448
|
+
|
|
449
|
+
```javascript
|
|
450
|
+
// ❌ WRONG: Large snapshots that break often
|
|
451
|
+
test('renders correctly', () => {
|
|
452
|
+
const { container } = render(<ComplexComponent />);
|
|
453
|
+
expect(container).toMatchSnapshot(); // 500 line snapshot
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
// ✅ CORRECT: Targeted snapshots for specific elements
|
|
457
|
+
test('renders error message correctly', () => {
|
|
458
|
+
render(<Form error="Invalid input" />);
|
|
459
|
+
const errorEl = screen.getByRole('alert');
|
|
460
|
+
expect(errorEl).toMatchInlineSnapshot(`
|
|
461
|
+
<div role="alert" class="error">
|
|
462
|
+
Invalid input
|
|
463
|
+
</div>
|
|
464
|
+
`);
|
|
465
|
+
});
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
### ❌ Don't Rely on Test Order
|
|
469
|
+
|
|
470
|
+
```javascript
|
|
471
|
+
// ❌ WRONG: Tests depend on execution order
|
|
472
|
+
test.only('test 1', () => { sharedState = 'value'; });
|
|
473
|
+
test('test 2', () => { expect(sharedState).toBe('value'); });
|
|
474
|
+
|
|
475
|
+
// ✅ CORRECT: Tests are independent
|
|
476
|
+
beforeEach(() => {
|
|
477
|
+
sharedState = getInitialState();
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
test('test 1', () => { /* uses sharedState */ });
|
|
481
|
+
test('test 2', () => { /* uses sharedState */ });
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
## Enforcement Checklist
|
|
485
|
+
|
|
486
|
+
Before committing test code, verify:
|
|
487
|
+
|
|
488
|
+
- [ ] All new code has corresponding tests
|
|
489
|
+
- [ ] Tests follow AAA pattern (Arrange-Act-Assert)
|
|
490
|
+
- [ ] Query priority is respected (getByRole preferred)
|
|
491
|
+
- [ ] No manual delays (use waitFor, findBy)
|
|
492
|
+
- [ ] Tests are independent (beforeEach used properly)
|
|
493
|
+
- [ ] Test names are descriptive
|
|
494
|
+
- [ ] Coverage thresholds are met (80%+)
|
|
495
|
+
- [ ] Accessibility is tested for UI components
|
|
496
|
+
- [ ] No testing of third-party libraries
|
|
497
|
+
- [ ] Mocks are cleaned up properly
|
|
498
|
+
- [ ] CI/CD integration is configured
|
|
499
|
+
|
|
500
|
+
## Validation
|
|
501
|
+
|
|
502
|
+
Run these checks before merge:
|
|
503
|
+
|
|
504
|
+
```bash
|
|
505
|
+
# Run all tests
|
|
506
|
+
npm test
|
|
507
|
+
|
|
508
|
+
# Check coverage
|
|
509
|
+
npm run test:coverage
|
|
510
|
+
|
|
511
|
+
# Run accessibility tests
|
|
512
|
+
npm run test:a11y
|
|
513
|
+
|
|
514
|
+
# Run in CI mode
|
|
515
|
+
npm run test:ci
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
## Related Rules
|
|
519
|
+
|
|
520
|
+
- `test-coverage-requirements` - Coverage threshold enforcement
|
|
521
|
+
- `accessibility-standards` - A11y testing requirements
|
|
522
|
+
- `code-quality-standards` - General code quality rules
|
|
523
|
+
|
|
524
|
+
## Support
|
|
525
|
+
|
|
526
|
+
For questions about testing standards:
|
|
527
|
+
- Review Context7 documentation for testing libraries
|
|
528
|
+
- Consult frontend-testing-engineer agent
|
|
529
|
+
- Review example tests in `test/examples/`
|