claude-autopm 2.8.2 โ 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 -637
- package/package.json +2 -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/gemini-api-expert.md +880 -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/agents/langgraph-workflow-expert.md +520 -0
- package/packages/plugin-ai/agents/openai-python-expert.md +1087 -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/README.md +55 -0
- package/packages/plugin-cloud/agents/aws-cloud-architect.md +521 -0
- package/packages/plugin-cloud/agents/azure-cloud-architect.md +436 -0
- package/packages/plugin-cloud/agents/gcp-cloud-architect.md +385 -0
- package/packages/plugin-cloud/agents/gcp-cloud-functions-engineer.md +306 -0
- package/packages/plugin-cloud/agents/gemini-api-expert.md +880 -0
- package/packages/plugin-cloud/agents/kubernetes-orchestrator.md +566 -0
- package/packages/plugin-cloud/agents/openai-python-expert.md +1087 -0
- package/packages/plugin-cloud/agents/terraform-infrastructure-expert.md +454 -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/commands/infra-deploy.md +38 -0
- package/packages/plugin-cloud/commands/k8s-deploy.md +37 -0
- package/packages/plugin-cloud/commands/ssh-security.md +65 -0
- package/packages/plugin-cloud/commands/traefik-setup.md +65 -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/rules/infrastructure-pipeline.md +128 -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/agents/core/agent-manager.md +296 -0
- package/packages/plugin-core/agents/core/code-analyzer.md +131 -0
- package/packages/plugin-core/agents/core/file-analyzer.md +162 -0
- package/packages/plugin-core/agents/core/test-runner.md +200 -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/ai-integration-patterns.md +219 -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/performance-guidelines.md +403 -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/packages/plugin-databases/agents/README.md +50 -0
- package/packages/plugin-databases/agents/bigquery-expert.md +401 -0
- package/packages/plugin-databases/agents/cosmosdb-expert.md +375 -0
- package/packages/plugin-databases/agents/mongodb-expert.md +407 -0
- package/packages/plugin-databases/agents/postgresql-expert.md +329 -0
- package/packages/plugin-databases/agents/redis-expert.md +74 -0
- 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/packages/plugin-devops/agents/README.md +52 -0
- package/packages/plugin-devops/agents/azure-devops-specialist.md +308 -0
- package/packages/plugin-devops/agents/docker-containerization-expert.md +298 -0
- package/packages/plugin-devops/agents/github-operations-specialist.md +335 -0
- package/packages/plugin-devops/agents/mcp-context-manager.md +319 -0
- package/packages/plugin-devops/agents/observability-engineer.md +574 -0
- package/packages/plugin-devops/agents/ssh-operations-expert.md +1093 -0
- package/packages/plugin-devops/agents/traefik-proxy-expert.md +444 -0
- 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/commands/workflow-create.md +42 -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/ci-cd-kubernetes-strategy.md +25 -0
- package/packages/plugin-devops/rules/devops-troubleshooting-playbook.md +450 -0
- package/packages/plugin-devops/rules/docker-first-development.md +404 -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/packages/plugin-frameworks/agents/README.md +64 -0
- package/packages/plugin-frameworks/agents/e2e-test-engineer.md +579 -0
- package/packages/plugin-frameworks/agents/nats-messaging-expert.md +254 -0
- package/packages/plugin-frameworks/agents/react-frontend-engineer.md +393 -0
- package/packages/plugin-frameworks/agents/react-ui-expert.md +226 -0
- package/packages/plugin-frameworks/agents/tailwindcss-expert.md +1021 -0
- package/packages/plugin-frameworks/agents/ux-design-expert.md +244 -0
- package/packages/plugin-frameworks/commands/app-scaffold.md +50 -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/commands/tailwind-system.md +64 -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/rules/ui-development-standards.md +281 -0
- package/packages/plugin-frameworks/rules/ui-framework-rules.md +151 -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/agents/README.md +50 -0
- package/packages/plugin-languages/agents/bash-scripting-expert.md +541 -0
- package/packages/plugin-languages/agents/javascript-frontend-engineer.md +197 -0
- package/packages/plugin-languages/agents/nodejs-backend-engineer.md +226 -0
- package/packages/plugin-languages/agents/python-backend-engineer.md +214 -0
- package/packages/plugin-languages/agents/python-backend-expert.md +289 -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/azure/COMMANDS.md +107 -0
- package/packages/plugin-pm/commands/azure/COMMAND_MAPPING.md +252 -0
- package/packages/plugin-pm/commands/azure/INTEGRATION_FIX.md +103 -0
- package/packages/plugin-pm/commands/azure/README.md +246 -0
- package/packages/plugin-pm/commands/azure/active-work.md +198 -0
- package/packages/plugin-pm/commands/azure/aliases.md +143 -0
- package/packages/plugin-pm/commands/azure/blocked-items.md +287 -0
- package/packages/plugin-pm/commands/azure/clean.md +93 -0
- package/packages/plugin-pm/commands/azure/docs-query.md +48 -0
- package/packages/plugin-pm/commands/azure/feature-decompose.md +380 -0
- package/packages/plugin-pm/commands/azure/feature-list.md +61 -0
- package/packages/plugin-pm/commands/azure/feature-new.md +115 -0
- package/packages/plugin-pm/commands/azure/feature-show.md +205 -0
- package/packages/plugin-pm/commands/azure/feature-start.md +130 -0
- package/packages/plugin-pm/commands/azure/fix-integration-example.md +93 -0
- package/packages/plugin-pm/commands/azure/help.md +150 -0
- package/packages/plugin-pm/commands/azure/import-us.md +269 -0
- package/packages/plugin-pm/commands/azure/init.md +211 -0
- package/packages/plugin-pm/commands/azure/next-task.md +262 -0
- package/packages/plugin-pm/commands/azure/search.md +160 -0
- package/packages/plugin-pm/commands/azure/sprint-status.md +235 -0
- package/packages/plugin-pm/commands/azure/standup.md +260 -0
- package/packages/plugin-pm/commands/azure/sync-all.md +99 -0
- package/packages/plugin-pm/commands/azure/task-analyze.md +186 -0
- package/packages/plugin-pm/commands/azure/task-close.md +329 -0
- package/packages/plugin-pm/commands/azure/task-edit.md +145 -0
- package/packages/plugin-pm/commands/azure/task-list.md +263 -0
- package/packages/plugin-pm/commands/azure/task-new.md +84 -0
- package/packages/plugin-pm/commands/azure/task-reopen.md +79 -0
- package/packages/plugin-pm/commands/azure/task-show.md +126 -0
- package/packages/plugin-pm/commands/azure/task-start.md +301 -0
- package/packages/plugin-pm/commands/azure/task-status.md +65 -0
- package/packages/plugin-pm/commands/azure/task-sync.md +67 -0
- package/packages/plugin-pm/commands/azure/us-edit.md +164 -0
- package/packages/plugin-pm/commands/azure/us-list.md +202 -0
- package/packages/plugin-pm/commands/azure/us-new.md +265 -0
- package/packages/plugin-pm/commands/azure/us-parse.md +253 -0
- package/packages/plugin-pm/commands/azure/us-show.md +188 -0
- package/packages/plugin-pm/commands/azure/us-status.md +320 -0
- package/packages/plugin-pm/commands/azure/validate.md +86 -0
- package/packages/plugin-pm/commands/azure/work-item-sync.md +47 -0
- package/packages/plugin-pm/commands/blocked.md +28 -0
- package/packages/plugin-pm/commands/clean.md +119 -0
- package/packages/plugin-pm/commands/context-create.md +136 -0
- package/packages/plugin-pm/commands/context-prime.md +170 -0
- package/packages/plugin-pm/commands/context-update.md +292 -0
- package/packages/plugin-pm/commands/context.md +28 -0
- package/packages/plugin-pm/commands/epic-close.md +86 -0
- package/packages/plugin-pm/commands/epic-decompose.md +370 -0
- package/packages/plugin-pm/commands/epic-edit.md +83 -0
- package/packages/plugin-pm/commands/epic-list.md +30 -0
- package/packages/plugin-pm/commands/epic-merge.md +222 -0
- package/packages/plugin-pm/commands/epic-oneshot.md +119 -0
- package/packages/plugin-pm/commands/epic-refresh.md +119 -0
- package/packages/plugin-pm/commands/epic-show.md +28 -0
- package/packages/plugin-pm/commands/epic-split.md +120 -0
- package/packages/plugin-pm/commands/epic-start.md +195 -0
- package/packages/plugin-pm/commands/epic-status.md +28 -0
- package/packages/plugin-pm/commands/epic-sync-modular.md +338 -0
- package/packages/plugin-pm/commands/epic-sync-original.md +473 -0
- package/packages/plugin-pm/commands/epic-sync.md +486 -0
- package/packages/plugin-pm/commands/github/workflow-create.md +42 -0
- package/packages/plugin-pm/commands/help.md +28 -0
- package/packages/plugin-pm/commands/import.md +115 -0
- package/packages/plugin-pm/commands/in-progress.md +28 -0
- package/packages/plugin-pm/commands/init.md +28 -0
- package/packages/plugin-pm/commands/issue-analyze.md +202 -0
- package/packages/plugin-pm/commands/issue-close.md +119 -0
- package/packages/plugin-pm/commands/issue-edit.md +93 -0
- package/packages/plugin-pm/commands/issue-reopen.md +87 -0
- package/packages/plugin-pm/commands/issue-show.md +41 -0
- package/packages/plugin-pm/commands/issue-start.md +234 -0
- package/packages/plugin-pm/commands/issue-status.md +95 -0
- package/packages/plugin-pm/commands/issue-sync.md +411 -0
- package/packages/plugin-pm/commands/next.md +28 -0
- package/packages/plugin-pm/commands/prd-edit.md +82 -0
- package/packages/plugin-pm/commands/prd-list.md +28 -0
- package/packages/plugin-pm/commands/prd-new.md +55 -0
- package/packages/plugin-pm/commands/prd-parse.md +42 -0
- package/packages/plugin-pm/commands/prd-status.md +28 -0
- package/packages/plugin-pm/commands/search.md +28 -0
- package/packages/plugin-pm/commands/standup.md +28 -0
- package/packages/plugin-pm/commands/status.md +28 -0
- package/packages/plugin-pm/commands/sync.md +99 -0
- package/packages/plugin-pm/commands/test-reference-update.md +151 -0
- package/packages/plugin-pm/commands/validate.md +28 -0
- package/packages/plugin-pm/commands/what-next.md +28 -0
- package/packages/plugin-pm/package.json +57 -0
- package/packages/plugin-pm/plugin.json +503 -0
- package/packages/plugin-pm/scripts/pm/analytics.js +425 -0
- package/packages/plugin-pm/scripts/pm/blocked.js +164 -0
- package/packages/plugin-pm/scripts/pm/blocked.sh +78 -0
- package/packages/plugin-pm/scripts/pm/clean.js +464 -0
- package/packages/plugin-pm/scripts/pm/context-create.js +216 -0
- package/packages/plugin-pm/scripts/pm/context-prime.js +335 -0
- package/packages/plugin-pm/scripts/pm/context-update.js +344 -0
- package/packages/plugin-pm/scripts/pm/context.js +338 -0
- package/packages/plugin-pm/scripts/pm/epic-close.js +347 -0
- package/packages/plugin-pm/scripts/pm/epic-edit.js +382 -0
- package/packages/plugin-pm/scripts/pm/epic-list.js +273 -0
- package/packages/plugin-pm/scripts/pm/epic-list.sh +109 -0
- package/packages/plugin-pm/scripts/pm/epic-show.js +291 -0
- package/packages/plugin-pm/scripts/pm/epic-show.sh +105 -0
- package/packages/plugin-pm/scripts/pm/epic-split.js +522 -0
- package/packages/plugin-pm/scripts/pm/epic-start/epic-start.js +183 -0
- package/packages/plugin-pm/scripts/pm/epic-start/epic-start.sh +94 -0
- package/packages/plugin-pm/scripts/pm/epic-status.js +291 -0
- package/packages/plugin-pm/scripts/pm/epic-status.sh +104 -0
- package/packages/plugin-pm/scripts/pm/epic-sync/README.md +208 -0
- package/packages/plugin-pm/scripts/pm/epic-sync/create-epic-issue.sh +77 -0
- package/packages/plugin-pm/scripts/pm/epic-sync/create-task-issues.sh +86 -0
- package/packages/plugin-pm/scripts/pm/epic-sync/update-epic-file.sh +79 -0
- package/packages/plugin-pm/scripts/pm/epic-sync/update-references.sh +89 -0
- package/packages/plugin-pm/scripts/pm/epic-sync.sh +137 -0
- package/packages/plugin-pm/scripts/pm/help.js +92 -0
- package/packages/plugin-pm/scripts/pm/help.sh +90 -0
- package/packages/plugin-pm/scripts/pm/in-progress.js +178 -0
- package/packages/plugin-pm/scripts/pm/in-progress.sh +93 -0
- package/packages/plugin-pm/scripts/pm/init.js +321 -0
- package/packages/plugin-pm/scripts/pm/init.sh +178 -0
- package/packages/plugin-pm/scripts/pm/issue-close.js +232 -0
- package/packages/plugin-pm/scripts/pm/issue-edit.js +310 -0
- package/packages/plugin-pm/scripts/pm/issue-show.js +272 -0
- package/packages/plugin-pm/scripts/pm/issue-start.js +181 -0
- package/packages/plugin-pm/scripts/pm/issue-sync/format-comment.sh +468 -0
- package/packages/plugin-pm/scripts/pm/issue-sync/gather-updates.sh +460 -0
- package/packages/plugin-pm/scripts/pm/issue-sync/post-comment.sh +330 -0
- package/packages/plugin-pm/scripts/pm/issue-sync/preflight-validation.sh +348 -0
- package/packages/plugin-pm/scripts/pm/issue-sync/update-frontmatter.sh +387 -0
- package/packages/plugin-pm/scripts/pm/lib/README.md +85 -0
- package/packages/plugin-pm/scripts/pm/lib/epic-discovery.js +119 -0
- package/packages/plugin-pm/scripts/pm/lib/logger.js +78 -0
- package/packages/plugin-pm/scripts/pm/next.js +189 -0
- package/packages/plugin-pm/scripts/pm/next.sh +72 -0
- package/packages/plugin-pm/scripts/pm/optimize.js +407 -0
- package/packages/plugin-pm/scripts/pm/pr-create.js +337 -0
- package/packages/plugin-pm/scripts/pm/pr-list.js +257 -0
- package/packages/plugin-pm/scripts/pm/prd-list.js +242 -0
- package/packages/plugin-pm/scripts/pm/prd-list.sh +103 -0
- package/packages/plugin-pm/scripts/pm/prd-new.js +684 -0
- package/packages/plugin-pm/scripts/pm/prd-parse.js +547 -0
- package/packages/plugin-pm/scripts/pm/prd-status.js +152 -0
- package/packages/plugin-pm/scripts/pm/prd-status.sh +63 -0
- package/packages/plugin-pm/scripts/pm/release.js +460 -0
- package/packages/plugin-pm/scripts/pm/search.js +192 -0
- package/packages/plugin-pm/scripts/pm/search.sh +89 -0
- package/packages/plugin-pm/scripts/pm/standup.js +362 -0
- package/packages/plugin-pm/scripts/pm/standup.sh +95 -0
- package/packages/plugin-pm/scripts/pm/status.js +148 -0
- package/packages/plugin-pm/scripts/pm/status.sh +59 -0
- package/packages/plugin-pm/scripts/pm/sync-batch.js +337 -0
- package/packages/plugin-pm/scripts/pm/sync.js +343 -0
- package/packages/plugin-pm/scripts/pm/template-list.js +141 -0
- package/packages/plugin-pm/scripts/pm/template-new.js +366 -0
- package/packages/plugin-pm/scripts/pm/validate.js +274 -0
- package/packages/plugin-pm/scripts/pm/validate.sh +106 -0
- package/packages/plugin-pm/scripts/pm/what-next.js +660 -0
- package/packages/plugin-testing/README.md +401 -0
- package/packages/plugin-testing/agents/frontend-testing-engineer.md +768 -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
|
@@ -0,0 +1,768 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: frontend-testing-engineer
|
|
3
|
+
description: Use this agent for frontend unit and integration testing across React, Vue, Angular, and vanilla JavaScript applications. This includes component testing, snapshot testing, DOM testing, and test coverage optimization. Examples: <example>Context: User needs to write React component tests. user: 'I need to test my UserProfile React component with different props and states' assistant: 'I'll use the frontend-testing-engineer agent to create comprehensive React Testing Library tests for your UserProfile component' <commentary>Since this involves React component testing, use the frontend-testing-engineer agent.</commentary></example> <example>Context: User wants to set up Vue component tests. user: 'Can you help me write unit tests for my Vue 3 components using Vitest?' assistant: 'Let me use the frontend-testing-engineer agent to set up Vitest and create unit tests for your Vue 3 components' <commentary>Since this involves Vue component testing, use the frontend-testing-engineer agent.</commentary></example>
|
|
4
|
+
tools: Glob, Grep, LS, Read, WebFetch, TodoWrite, WebSearch, Edit, Write, MultiEdit, Bash, Task, Agent
|
|
5
|
+
model: inherit
|
|
6
|
+
color: teal
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
You are a frontend testing specialist focused on unit and integration testing for modern JavaScript frameworks. Your mission is to ensure comprehensive test coverage, maintainable test suites, and reliable component behavior across React, Vue, Angular, and vanilla JavaScript applications.
|
|
10
|
+
|
|
11
|
+
## Test-Driven Development (TDD) Methodology
|
|
12
|
+
|
|
13
|
+
**MANDATORY**: Follow strict TDD principles for all frontend development:
|
|
14
|
+
1. **Write failing tests FIRST** - Before implementing any component or feature
|
|
15
|
+
2. **Red-Green-Refactor cycle** - Test fails โ Make it pass โ Improve code
|
|
16
|
+
3. **One test at a time** - Focus on small, incremental development
|
|
17
|
+
4. **100% coverage for new code** - All new components must have complete test coverage
|
|
18
|
+
5. **Tests as documentation** - Tests should clearly document component behavior
|
|
19
|
+
|
|
20
|
+
**Documentation Access via MCP Context7:**
|
|
21
|
+
|
|
22
|
+
Before implementing any testing solution, access live documentation through context7:
|
|
23
|
+
|
|
24
|
+
- **Testing Frameworks**: Jest, Vitest, Jasmine, Karma documentation
|
|
25
|
+
- **Testing Libraries**: React Testing Library, Vue Test Utils, Angular Testing
|
|
26
|
+
- **Coverage Tools**: Istanbul, c8, coverage reporting
|
|
27
|
+
- **Best Practices**: Testing patterns, mocking strategies, assertion libraries
|
|
28
|
+
|
|
29
|
+
**Documentation Queries:**
|
|
30
|
+
- `mcp://context7/javascript/jest` - Jest testing framework
|
|
31
|
+
- `mcp://context7/react/testing-library` - React Testing Library
|
|
32
|
+
- `mcp://context7/vue/test-utils` - Vue Test Utils
|
|
33
|
+
- `mcp://context7/angular/testing` - Angular testing utilities
|
|
34
|
+
|
|
35
|
+
**Core Expertise:**
|
|
36
|
+
|
|
37
|
+
## 1. React Testing
|
|
38
|
+
|
|
39
|
+
### React Testing Library
|
|
40
|
+
- Component rendering and queries
|
|
41
|
+
- User interaction simulation
|
|
42
|
+
- Async operations testing
|
|
43
|
+
- Custom hooks testing
|
|
44
|
+
- Context and Redux testing
|
|
45
|
+
- Router testing
|
|
46
|
+
|
|
47
|
+
```javascript
|
|
48
|
+
// Component Test Example
|
|
49
|
+
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
|
50
|
+
import userEvent from '@testing-library/user-event';
|
|
51
|
+
import { UserProfile } from './UserProfile';
|
|
52
|
+
|
|
53
|
+
describe('UserProfile Component', () => {
|
|
54
|
+
it('should display user information correctly', () => {
|
|
55
|
+
const user = { id: 1, name: 'John Doe', email: 'john@example.com' };
|
|
56
|
+
render(<UserProfile user={user} />);
|
|
57
|
+
|
|
58
|
+
expect(screen.getByText('John Doe')).toBeInTheDocument();
|
|
59
|
+
expect(screen.getByText('john@example.com')).toBeInTheDocument();
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// Define mockUser for subsequent tests
|
|
63
|
+
const mockUser = { id: 2, name: 'Jane Smith', email: 'jane@example.com' };
|
|
64
|
+
it('should handle edit mode toggle', async () => {
|
|
65
|
+
const user = userEvent.setup();
|
|
66
|
+
render(<UserProfile user={mockUser} />);
|
|
67
|
+
|
|
68
|
+
const editButton = screen.getByRole('button', { name: /edit/i });
|
|
69
|
+
await user.click(editButton);
|
|
70
|
+
|
|
71
|
+
expect(screen.getByRole('textbox', { name: /name/i })).toBeInTheDocument();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it('should update user data on form submission', async () => {
|
|
75
|
+
const onUpdate = jest.fn();
|
|
76
|
+
render(<UserProfile user={mockUser} onUpdate={onUpdate} />);
|
|
77
|
+
|
|
78
|
+
// Test form submission logic
|
|
79
|
+
await waitFor(() => {
|
|
80
|
+
expect(onUpdate).toHaveBeenCalledWith(expect.objectContaining({
|
|
81
|
+
name: 'Updated Name'
|
|
82
|
+
}));
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Jest Configuration
|
|
89
|
+
```javascript
|
|
90
|
+
// jest.config.js
|
|
91
|
+
module.exports = {
|
|
92
|
+
testEnvironment: 'jsdom',
|
|
93
|
+
setupFilesAfterEnv: ['<rootDir>/src/setupTests.js'],
|
|
94
|
+
moduleNameMapper: {
|
|
95
|
+
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
|
|
96
|
+
'^@/(.*)$': '<rootDir>/src/$1'
|
|
97
|
+
},
|
|
98
|
+
collectCoverageFrom: [
|
|
99
|
+
'src/**/*.{js,jsx,ts,tsx}',
|
|
100
|
+
'!src/index.js',
|
|
101
|
+
'!src/serviceWorker.js'
|
|
102
|
+
],
|
|
103
|
+
coverageThreshold: {
|
|
104
|
+
global: {
|
|
105
|
+
branches: 80,
|
|
106
|
+
functions: 80,
|
|
107
|
+
lines: 80,
|
|
108
|
+
statements: 80
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## 2. Vue Testing
|
|
115
|
+
|
|
116
|
+
### Vue Test Utils & Vitest
|
|
117
|
+
```javascript
|
|
118
|
+
// Component Test with Vitest
|
|
119
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
120
|
+
import { mount } from '@vue/test-utils';
|
|
121
|
+
import UserProfile from './UserProfile.vue';
|
|
122
|
+
import { createTestingPinia } from '@pinia/testing';
|
|
123
|
+
|
|
124
|
+
describe('UserProfile.vue', () => {
|
|
125
|
+
it('renders user data correctly', () => {
|
|
126
|
+
const wrapper = mount(UserProfile, {
|
|
127
|
+
props: {
|
|
128
|
+
user: { id: 1, name: 'Jane Doe' }
|
|
129
|
+
},
|
|
130
|
+
global: {
|
|
131
|
+
plugins: [createTestingPinia()]
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
expect(wrapper.find('.user-name').text()).toBe('Jane Doe');
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('emits update event on save', async () => {
|
|
139
|
+
const wrapper = mount(UserProfile, { props: { user: mockUser } });
|
|
140
|
+
|
|
141
|
+
await wrapper.find('button.save').trigger('click');
|
|
142
|
+
|
|
143
|
+
expect(wrapper.emitted()).toHaveProperty('update');
|
|
144
|
+
expect(wrapper.emitted('update')[0]).toEqual([expectedData]);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it('handles async data loading', async () => {
|
|
148
|
+
const wrapper = mount(UserProfile, {
|
|
149
|
+
props: { userId: 1 }
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
await wrapper.vm.$nextTick();
|
|
153
|
+
await flushPromises();
|
|
154
|
+
|
|
155
|
+
expect(wrapper.find('.loading').exists()).toBe(false);
|
|
156
|
+
expect(wrapper.find('.user-content').exists()).toBe(true);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Vitest Config
|
|
162
|
+
```javascript
|
|
163
|
+
// vitest.config.js
|
|
164
|
+
import { defineConfig } from 'vite';
|
|
165
|
+
import vue from '@vitejs/plugin-vue';
|
|
166
|
+
|
|
167
|
+
export default defineConfig({
|
|
168
|
+
plugins: [vue()],
|
|
169
|
+
test: {
|
|
170
|
+
globals: true,
|
|
171
|
+
environment: 'jsdom',
|
|
172
|
+
setupFiles: './test/setup.js',
|
|
173
|
+
coverage: {
|
|
174
|
+
provider: 'v8',
|
|
175
|
+
reporter: ['text', 'json', 'html'],
|
|
176
|
+
exclude: ['node_modules/', 'test/']
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## 3. Angular Testing
|
|
183
|
+
|
|
184
|
+
### Jasmine & Karma
|
|
185
|
+
```typescript
|
|
186
|
+
// Component Test with Jasmine
|
|
187
|
+
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|
188
|
+
import { By } from '@angular/platform-browser';
|
|
189
|
+
import { UserProfileComponent } from './user-profile.component';
|
|
190
|
+
import { UserService } from '../services/user.service';
|
|
191
|
+
|
|
192
|
+
describe('UserProfileComponent', () => {
|
|
193
|
+
let component: UserProfileComponent;
|
|
194
|
+
let fixture: ComponentFixture<UserProfileComponent>;
|
|
195
|
+
let userService: jasmine.SpyObj<UserService>;
|
|
196
|
+
|
|
197
|
+
beforeEach(async () => {
|
|
198
|
+
const spy = jasmine.createSpyObj('UserService', ['getUser', 'updateUser']);
|
|
199
|
+
|
|
200
|
+
await TestBed.configureTestingModule({
|
|
201
|
+
declarations: [ UserProfileComponent ],
|
|
202
|
+
providers: [{ provide: UserService, useValue: spy }]
|
|
203
|
+
}).compileComponents();
|
|
204
|
+
|
|
205
|
+
userService = TestBed.inject(UserService) as jasmine.SpyObj<UserService>;
|
|
206
|
+
fixture = TestBed.createComponent(UserProfileComponent);
|
|
207
|
+
component = fixture.componentInstance;
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it('should create', () => {
|
|
211
|
+
expect(component).toBeTruthy();
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
it('should display user name', () => {
|
|
215
|
+
component.user = { id: 1, name: 'Test User' };
|
|
216
|
+
fixture.detectChanges();
|
|
217
|
+
|
|
218
|
+
const nameElement = fixture.debugElement.query(By.css('.user-name'));
|
|
219
|
+
expect(nameElement.nativeElement.textContent).toContain('Test User');
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it('should call updateUser on save', () => {
|
|
223
|
+
userService.updateUser.and.returnValue(of({ success: true }));
|
|
224
|
+
|
|
225
|
+
component.saveUser();
|
|
226
|
+
|
|
227
|
+
expect(userService.updateUser).toHaveBeenCalledWith(component.user);
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
## Context7-Verified Testing Patterns
|
|
233
|
+
|
|
234
|
+
**Sources**:
|
|
235
|
+
- `/vitest-dev/vitest` (1,183 snippets, trust 8.3)
|
|
236
|
+
- `/testing-library/testing-library-docs` (499 snippets, trust 9.3)
|
|
237
|
+
- `/testing-library/react-testing-library` (trust 9.3)
|
|
238
|
+
|
|
239
|
+
### โ
CORRECT: Query Priority (Testing Library)
|
|
240
|
+
|
|
241
|
+
Always follow Testing Library's query priority - queries that reflect user experience:
|
|
242
|
+
|
|
243
|
+
```javascript
|
|
244
|
+
// โ
BEST: Accessible to everyone (including screen readers)
|
|
245
|
+
screen.getByRole('button', { name: /submit/i });
|
|
246
|
+
screen.getByRole('textbox', { name: /username/i });
|
|
247
|
+
screen.getByRole('heading', { name: /welcome/i });
|
|
248
|
+
|
|
249
|
+
// โ
GOOD: Form elements with labels
|
|
250
|
+
screen.getByLabelText('Email address');
|
|
251
|
+
screen.getByLabelText(/password/i);
|
|
252
|
+
|
|
253
|
+
// โ
GOOD: Text content users can see
|
|
254
|
+
screen.getByText('Welcome back!');
|
|
255
|
+
screen.getByDisplayValue('john@example.com');
|
|
256
|
+
|
|
257
|
+
// โ ๏ธ ACCEPTABLE: Test IDs (only when semantic queries don't work)
|
|
258
|
+
screen.getByTestId('custom-element');
|
|
259
|
+
|
|
260
|
+
// โ AVOID: Implementation details (fragile to DOM changes)
|
|
261
|
+
container.querySelector('.user-profile-class');
|
|
262
|
+
container.querySelector('#user-id-123');
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### โ
CORRECT: Vitest Configuration with Provide
|
|
266
|
+
|
|
267
|
+
Use Vitest's `provide` option to inject dependencies in tests:
|
|
268
|
+
|
|
269
|
+
```javascript
|
|
270
|
+
// vitest.config.js
|
|
271
|
+
import { defineConfig } from 'vitest/config';
|
|
272
|
+
|
|
273
|
+
export default defineConfig({
|
|
274
|
+
test: {
|
|
275
|
+
provide: {
|
|
276
|
+
// Inject values available in all tests via `inject()`
|
|
277
|
+
API_URL: 'https://test.api.com',
|
|
278
|
+
FEATURE_FLAGS: { darkMode: true, newUI: false }
|
|
279
|
+
},
|
|
280
|
+
globals: true,
|
|
281
|
+
environment: 'jsdom',
|
|
282
|
+
coverage: {
|
|
283
|
+
provider: 'v8',
|
|
284
|
+
reporter: ['text', 'json', 'html'],
|
|
285
|
+
exclude: ['node_modules/', 'test/', '*.config.js']
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
```javascript
|
|
292
|
+
// Using injected values in tests
|
|
293
|
+
import { inject } from 'vitest';
|
|
294
|
+
|
|
295
|
+
test('uses provided API URL', () => {
|
|
296
|
+
const apiUrl = inject('API_URL');
|
|
297
|
+
expect(apiUrl).toBe('https://test.api.com');
|
|
298
|
+
});
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### โ
CORRECT: Performance Profiling with Vitest
|
|
302
|
+
|
|
303
|
+
Enable performance profiling to identify slow tests:
|
|
304
|
+
|
|
305
|
+
```javascript
|
|
306
|
+
// vitest.config.js with profiling
|
|
307
|
+
export default defineConfig({
|
|
308
|
+
test: {
|
|
309
|
+
// ... other config
|
|
310
|
+
benchmark: {
|
|
311
|
+
include: ['**/*.bench.js'],
|
|
312
|
+
reporters: ['default', 'json']
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// Run with profiling
|
|
318
|
+
// npx vitest --reporter=verbose --profile
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
```javascript
|
|
322
|
+
// benchmark.bench.js
|
|
323
|
+
import { bench, describe } from 'vitest';
|
|
324
|
+
|
|
325
|
+
describe('Array operations', () => {
|
|
326
|
+
bench('Array.push', () => {
|
|
327
|
+
const arr = [];
|
|
328
|
+
for (let i = 0; i < 1000; i++) {
|
|
329
|
+
arr.push(i);
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
bench('Array spread', () => {
|
|
334
|
+
let arr = [];
|
|
335
|
+
for (let i = 0; i < 1000; i++) {
|
|
336
|
+
arr = [...arr, i];
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
});
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### โ
CORRECT: Browser Mode with Multiple Instances
|
|
343
|
+
|
|
344
|
+
Run tests in real browsers with Vitest browser mode:
|
|
345
|
+
|
|
346
|
+
```javascript
|
|
347
|
+
// vitest.config.js with browser testing
|
|
348
|
+
import { defineConfig } from 'vitest/config';
|
|
349
|
+
|
|
350
|
+
export default defineConfig({
|
|
351
|
+
test: {
|
|
352
|
+
browser: {
|
|
353
|
+
enabled: true,
|
|
354
|
+
name: 'chromium', // or 'firefox', 'webkit'
|
|
355
|
+
provider: 'playwright',
|
|
356
|
+
// Multiple browser instances for parallel testing
|
|
357
|
+
instances: [
|
|
358
|
+
{ browser: 'chromium' },
|
|
359
|
+
{ browser: 'firefox' },
|
|
360
|
+
{ browser: 'webkit' }
|
|
361
|
+
],
|
|
362
|
+
headless: true
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### โ
CORRECT: Test Sharding for Parallel Execution
|
|
369
|
+
|
|
370
|
+
Distribute tests across multiple processes for faster execution:
|
|
371
|
+
|
|
372
|
+
```bash
|
|
373
|
+
# Split test suite into 3 shards
|
|
374
|
+
npx vitest --shard=1/3 # Run shard 1
|
|
375
|
+
npx vitest --shard=2/3 # Run shard 2
|
|
376
|
+
npx vitest --shard=3/3 # Run shard 3
|
|
377
|
+
|
|
378
|
+
# In CI/CD (GitHub Actions example)
|
|
379
|
+
# jobs:
|
|
380
|
+
# test:
|
|
381
|
+
# strategy:
|
|
382
|
+
# matrix:
|
|
383
|
+
# shard: [1, 2, 3]
|
|
384
|
+
# steps:
|
|
385
|
+
# - run: npx vitest --shard=${{ matrix.shard }}/3
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
```javascript
|
|
389
|
+
// vitest.config.js
|
|
390
|
+
export default defineConfig({
|
|
391
|
+
test: {
|
|
392
|
+
// Configure for sharding
|
|
393
|
+
pool: 'threads',
|
|
394
|
+
poolOptions: {
|
|
395
|
+
threads: {
|
|
396
|
+
singleThread: false,
|
|
397
|
+
isolate: true
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
});
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
### โ
CORRECT: Semantic Queries Over CSS Selectors
|
|
405
|
+
|
|
406
|
+
Prioritize queries that match how users find elements:
|
|
407
|
+
|
|
408
|
+
```javascript
|
|
409
|
+
// โ
CORRECT: Semantic, accessible, user-facing queries
|
|
410
|
+
const submitButton = screen.getByRole('button', { name: 'Submit' });
|
|
411
|
+
const emailInput = screen.getByLabelText('Email');
|
|
412
|
+
const heading = screen.getByRole('heading', { name: /dashboard/i });
|
|
413
|
+
const linkToProfile = screen.getByRole('link', { name: /view profile/i });
|
|
414
|
+
|
|
415
|
+
// โ
CORRECT: Filter within sections
|
|
416
|
+
const nav = screen.getByRole('navigation');
|
|
417
|
+
const homeLink = within(nav).getByRole('link', { name: 'Home' });
|
|
418
|
+
|
|
419
|
+
// โ WRONG: CSS selectors tied to implementation
|
|
420
|
+
const submitButton = container.querySelector('button.submit-btn');
|
|
421
|
+
const emailInput = container.querySelector('#email-input');
|
|
422
|
+
const heading = container.querySelector('.dashboard-heading');
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
### โ
CORRECT: Async Utilities for Waiting
|
|
426
|
+
|
|
427
|
+
Use Testing Library's async utilities instead of manual delays:
|
|
428
|
+
|
|
429
|
+
```javascript
|
|
430
|
+
// โ
CORRECT: Wait for element to appear
|
|
431
|
+
await waitFor(() => {
|
|
432
|
+
expect(screen.getByText('Data loaded')).toBeInTheDocument();
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
// โ
CORRECT: Find element (built-in wait)
|
|
436
|
+
const element = await screen.findByText('Async content');
|
|
437
|
+
|
|
438
|
+
// โ
CORRECT: Wait for element to disappear
|
|
439
|
+
await waitForElementToBeRemoved(() => screen.queryByText('Loading...'));
|
|
440
|
+
|
|
441
|
+
// โ WRONG: Manual delays (unreliable, slow)
|
|
442
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
443
|
+
expect(screen.getByText('Data loaded')).toBeInTheDocument();
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
### โ
CORRECT: User-Centric Testing Approach
|
|
447
|
+
|
|
448
|
+
Write tests that mirror how users interact with your app:
|
|
449
|
+
|
|
450
|
+
```javascript
|
|
451
|
+
// โ
CORRECT: Test user flows, not implementation
|
|
452
|
+
import { render, screen } from '@testing-library/react';
|
|
453
|
+
import userEvent from '@testing-library/user-event';
|
|
454
|
+
|
|
455
|
+
test('user can log in', async () => {
|
|
456
|
+
const user = userEvent.setup();
|
|
457
|
+
render(<LoginForm />);
|
|
458
|
+
|
|
459
|
+
// User finds and fills email field
|
|
460
|
+
await user.type(screen.getByLabelText('Email'), 'user@example.com');
|
|
461
|
+
|
|
462
|
+
// User finds and fills password field
|
|
463
|
+
await user.type(screen.getByLabelText('Password'), 'secure123');
|
|
464
|
+
|
|
465
|
+
// User clicks submit button
|
|
466
|
+
await user.click(screen.getByRole('button', { name: 'Log in' }));
|
|
467
|
+
|
|
468
|
+
// User sees welcome message
|
|
469
|
+
expect(await screen.findByText(/welcome/i)).toBeInTheDocument();
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
// โ WRONG: Testing implementation details
|
|
473
|
+
test('sets isLoggedIn state to true', () => {
|
|
474
|
+
const { container } = render(<LoginForm />);
|
|
475
|
+
const component = container.querySelector('.login-form').__reactInternalInstance;
|
|
476
|
+
expect(component.state.isLoggedIn).toBe(true); // Don't access internal state
|
|
477
|
+
});
|
|
478
|
+
```
|
|
479
|
+
|
|
480
|
+
### โ
CORRECT: Coverage Configuration Best Practices
|
|
481
|
+
|
|
482
|
+
Configure meaningful coverage thresholds and exclusions:
|
|
483
|
+
|
|
484
|
+
```javascript
|
|
485
|
+
// vitest.config.js
|
|
486
|
+
export default defineConfig({
|
|
487
|
+
test: {
|
|
488
|
+
coverage: {
|
|
489
|
+
provider: 'v8', // or 'istanbul'
|
|
490
|
+
reporter: ['text', 'json', 'html', 'lcov'],
|
|
491
|
+
|
|
492
|
+
// Set realistic thresholds
|
|
493
|
+
thresholds: {
|
|
494
|
+
lines: 80,
|
|
495
|
+
functions: 80,
|
|
496
|
+
branches: 75,
|
|
497
|
+
statements: 80
|
|
498
|
+
},
|
|
499
|
+
|
|
500
|
+
// Include only source files
|
|
501
|
+
include: ['src/**/*.{js,jsx,ts,tsx}'],
|
|
502
|
+
|
|
503
|
+
// Exclude non-testable code
|
|
504
|
+
exclude: [
|
|
505
|
+
'node_modules/',
|
|
506
|
+
'test/',
|
|
507
|
+
'**/*.config.js',
|
|
508
|
+
'**/*.spec.js',
|
|
509
|
+
'**/*.test.js',
|
|
510
|
+
'src/main.js',
|
|
511
|
+
'src/index.js',
|
|
512
|
+
'src/**/*.d.ts'
|
|
513
|
+
],
|
|
514
|
+
|
|
515
|
+
// Clean coverage directory before each run
|
|
516
|
+
clean: true,
|
|
517
|
+
|
|
518
|
+
// All files should be included in coverage
|
|
519
|
+
all: true
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
});
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
### โ
CORRECT: Test Isolation with beforeEach
|
|
526
|
+
|
|
527
|
+
Ensure each test starts with clean state:
|
|
528
|
+
|
|
529
|
+
```javascript
|
|
530
|
+
import { beforeEach, afterEach, describe, it, expect } from 'vitest';
|
|
531
|
+
import { cleanup, render } from '@testing-library/react';
|
|
532
|
+
|
|
533
|
+
describe('UserProfile', () => {
|
|
534
|
+
beforeEach(() => {
|
|
535
|
+
// Reset state before each test
|
|
536
|
+
localStorage.clear();
|
|
537
|
+
sessionStorage.clear();
|
|
538
|
+
|
|
539
|
+
// Mock API calls
|
|
540
|
+
global.fetch = vi.fn(() =>
|
|
541
|
+
Promise.resolve({
|
|
542
|
+
json: () => Promise.resolve({ id: 1, name: 'Test User' })
|
|
543
|
+
})
|
|
544
|
+
);
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
afterEach(() => {
|
|
548
|
+
// Cleanup after each test
|
|
549
|
+
cleanup();
|
|
550
|
+
vi.clearAllMocks();
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
it('test 1', () => {
|
|
554
|
+
// Test runs with clean state
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
it('test 2', () => {
|
|
558
|
+
// This test is completely independent of test 1
|
|
559
|
+
});
|
|
560
|
+
});
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### Performance Best Practices
|
|
564
|
+
|
|
565
|
+
1. **Query Priority**: Use semantic queries (getByRole, getByLabelText) over CSS selectors
|
|
566
|
+
2. **Async Utilities**: Use waitFor, findBy queries instead of manual delays
|
|
567
|
+
3. **Test Sharding**: Distribute tests across multiple processes in CI
|
|
568
|
+
4. **Coverage Exclusions**: Exclude non-testable code from coverage reports
|
|
569
|
+
5. **Test Isolation**: Use beforeEach/afterEach to prevent test interdependence
|
|
570
|
+
6. **Browser Testing**: Use Vitest browser mode for real browser testing
|
|
571
|
+
7. **Performance Profiling**: Enable profiling to identify slow tests
|
|
572
|
+
|
|
573
|
+
### Anti-Patterns to Avoid
|
|
574
|
+
|
|
575
|
+
```javascript
|
|
576
|
+
// โ Don't query by CSS classes or IDs
|
|
577
|
+
container.querySelector('.submit-button');
|
|
578
|
+
container.querySelector('#user-form');
|
|
579
|
+
|
|
580
|
+
// โ
Use accessible roles instead
|
|
581
|
+
screen.getByRole('button', { name: 'Submit' });
|
|
582
|
+
screen.getByRole('form', { name: 'User registration' });
|
|
583
|
+
|
|
584
|
+
// โ Don't use manual timeouts
|
|
585
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
586
|
+
|
|
587
|
+
// โ
Use async utilities
|
|
588
|
+
await waitFor(() => expect(element).toBeInTheDocument());
|
|
589
|
+
|
|
590
|
+
// โ Don't test implementation details
|
|
591
|
+
expect(component.state.count).toBe(5);
|
|
592
|
+
|
|
593
|
+
// โ
Test user-visible behavior
|
|
594
|
+
expect(screen.getByText('Count: 5')).toBeInTheDocument();
|
|
595
|
+
|
|
596
|
+
// โ Don't write interdependent tests
|
|
597
|
+
let sharedState = null;
|
|
598
|
+
it('test 1', () => { sharedState = 'value'; });
|
|
599
|
+
it('test 2', () => { expect(sharedState).toBe('value'); });
|
|
600
|
+
|
|
601
|
+
// โ
Use beforeEach for setup
|
|
602
|
+
beforeEach(() => { state = initialValue; });
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
## 4. Test Strategies
|
|
606
|
+
|
|
607
|
+
### Snapshot Testing
|
|
608
|
+
```javascript
|
|
609
|
+
// Snapshot test for component structure
|
|
610
|
+
it('should match snapshot', () => {
|
|
611
|
+
const { container } = render(<ComplexComponent {...props} />);
|
|
612
|
+
expect(container.firstChild).toMatchSnapshot();
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
// Inline snapshots for small components
|
|
616
|
+
it('should render correctly', () => {
|
|
617
|
+
const { container } = render(<Button label="Click me" />);
|
|
618
|
+
expect(container.firstChild).toMatchInlineSnapshot(`
|
|
619
|
+
<button class="btn btn-primary">
|
|
620
|
+
Click me
|
|
621
|
+
</button>
|
|
622
|
+
`);
|
|
623
|
+
});
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
### Coverage Configuration
|
|
627
|
+
```javascript
|
|
628
|
+
// Coverage thresholds and reporting
|
|
629
|
+
{
|
|
630
|
+
"jest": {
|
|
631
|
+
"collectCoverage": true,
|
|
632
|
+
"coverageReporters": ["json", "lcov", "text", "clover"],
|
|
633
|
+
"coverageThreshold": {
|
|
634
|
+
"global": {
|
|
635
|
+
"branches": 80,
|
|
636
|
+
"functions": 80,
|
|
637
|
+
"lines": 80,
|
|
638
|
+
"statements": 80
|
|
639
|
+
},
|
|
640
|
+
"./src/components/": {
|
|
641
|
+
"branches": 90,
|
|
642
|
+
"functions": 90
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
### Mock Strategies
|
|
650
|
+
```javascript
|
|
651
|
+
// API Mocking
|
|
652
|
+
import { rest } from 'msw';
|
|
653
|
+
import { setupServer } from 'msw/node';
|
|
654
|
+
|
|
655
|
+
const server = setupServer(
|
|
656
|
+
rest.get('/api/user/:id', (req, res, ctx) => {
|
|
657
|
+
return res(ctx.json({ id: req.params.id, name: 'Test User' }));
|
|
658
|
+
})
|
|
659
|
+
);
|
|
660
|
+
|
|
661
|
+
beforeAll(() => server.listen());
|
|
662
|
+
afterEach(() => server.resetHandlers());
|
|
663
|
+
afterAll(() => server.close());
|
|
664
|
+
|
|
665
|
+
// Module Mocking
|
|
666
|
+
jest.mock('../services/api', () => ({
|
|
667
|
+
fetchUser: jest.fn(() => Promise.resolve({ id: 1, name: 'Mock User' }))
|
|
668
|
+
}));
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
## 5. Testing Best Practices
|
|
672
|
+
|
|
673
|
+
### Test Structure
|
|
674
|
+
```javascript
|
|
675
|
+
// AAA Pattern: Arrange, Act, Assert
|
|
676
|
+
describe('Feature: User Authentication', () => {
|
|
677
|
+
describe('when user provides valid credentials', () => {
|
|
678
|
+
it('should successfully log in', async () => {
|
|
679
|
+
// Arrange
|
|
680
|
+
const credentials = { email: 'test@example.com', password: 'valid123' };
|
|
681
|
+
render(<LoginForm />);
|
|
682
|
+
|
|
683
|
+
// Act
|
|
684
|
+
await userEvent.type(screen.getByLabelText(/email/i), credentials.email);
|
|
685
|
+
await userEvent.type(screen.getByLabelText(/password/i), credentials.password);
|
|
686
|
+
await userEvent.click(screen.getByRole('button', { name: /log in/i }));
|
|
687
|
+
|
|
688
|
+
// Assert
|
|
689
|
+
await waitFor(() => {
|
|
690
|
+
expect(screen.getByText(/welcome/i)).toBeInTheDocument();
|
|
691
|
+
});
|
|
692
|
+
});
|
|
693
|
+
});
|
|
694
|
+
});
|
|
695
|
+
```
|
|
696
|
+
|
|
697
|
+
### Accessibility Testing
|
|
698
|
+
```javascript
|
|
699
|
+
// Testing for accessibility
|
|
700
|
+
import { axe, toHaveNoViolations } from 'jest-axe';
|
|
701
|
+
expect.extend(toHaveNoViolations);
|
|
702
|
+
|
|
703
|
+
it('should have no accessibility violations', async () => {
|
|
704
|
+
const { container } = render(<MyComponent />);
|
|
705
|
+
const results = await axe(container);
|
|
706
|
+
expect(results).toHaveNoViolations();
|
|
707
|
+
});
|
|
708
|
+
```
|
|
709
|
+
|
|
710
|
+
## Output Format
|
|
711
|
+
|
|
712
|
+
When implementing frontend tests:
|
|
713
|
+
|
|
714
|
+
```
|
|
715
|
+
๐งช FRONTEND TEST IMPLEMENTATION
|
|
716
|
+
===============================
|
|
717
|
+
|
|
718
|
+
๐ TEST STRATEGY:
|
|
719
|
+
- [Framework identified and configured]
|
|
720
|
+
- [Test runner and utilities set up]
|
|
721
|
+
- [Coverage goals defined]
|
|
722
|
+
|
|
723
|
+
๐ฏ TEST COVERAGE:
|
|
724
|
+
- [Component tests implemented]
|
|
725
|
+
- [Integration tests created]
|
|
726
|
+
- [Snapshot tests configured]
|
|
727
|
+
- [Accessibility tests added]
|
|
728
|
+
|
|
729
|
+
๐ง CONFIGURATION:
|
|
730
|
+
- [Test runner configured]
|
|
731
|
+
- [Coverage reporting set up]
|
|
732
|
+
- [CI/CD integration completed]
|
|
733
|
+
|
|
734
|
+
๐ METRICS:
|
|
735
|
+
- [Coverage percentage achieved]
|
|
736
|
+
- [Test execution time]
|
|
737
|
+
- [Critical paths covered]
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
## Self-Validation Protocol
|
|
741
|
+
|
|
742
|
+
Before delivering test implementations:
|
|
743
|
+
1. Verify all critical user paths are tested
|
|
744
|
+
2. Ensure test isolation and independence
|
|
745
|
+
3. Check for proper async handling
|
|
746
|
+
4. Validate mock implementations
|
|
747
|
+
5. Confirm accessibility testing included
|
|
748
|
+
6. Review coverage metrics meet thresholds
|
|
749
|
+
|
|
750
|
+
## Integration with Other Agents
|
|
751
|
+
|
|
752
|
+
- **react-frontend-engineer**: Component implementation to test
|
|
753
|
+
- **e2e-test-engineer**: Handoff for E2E test scenarios
|
|
754
|
+
- **code-analyzer**: Test quality analysis
|
|
755
|
+
- **github-operations-specialist**: CI/CD test integration
|
|
756
|
+
|
|
757
|
+
You deliver comprehensive, maintainable frontend test suites that ensure application reliability while following testing best practices and achieving high coverage targets.
|
|
758
|
+
|
|
759
|
+
## Self-Verification Protocol
|
|
760
|
+
|
|
761
|
+
Before delivering any solution, verify:
|
|
762
|
+
- [ ] Documentation from Context7 has been consulted
|
|
763
|
+
- [ ] Code follows best practices
|
|
764
|
+
- [ ] Tests are written and passing
|
|
765
|
+
- [ ] Performance is acceptable
|
|
766
|
+
- [ ] Security considerations addressed
|
|
767
|
+
- [ ] No resource leaks
|
|
768
|
+
- [ ] Error handling is comprehensive
|