@wazir-dev/cli 1.0.0
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/AGENTS.md +111 -0
- package/CHANGELOG.md +14 -0
- package/CONTRIBUTING.md +101 -0
- package/LICENSE +21 -0
- package/README.md +314 -0
- package/assets/composition-engine.mmd +34 -0
- package/assets/demo-script.sh +17 -0
- package/assets/logo-dark.svg +14 -0
- package/assets/logo.svg +14 -0
- package/assets/pipeline.mmd +39 -0
- package/assets/record-demo.sh +51 -0
- package/docs/README.md +51 -0
- package/docs/adapters/context-mode.md +60 -0
- package/docs/concepts/architecture.md +87 -0
- package/docs/concepts/artifact-model.md +60 -0
- package/docs/concepts/composition-engine.md +36 -0
- package/docs/concepts/indexing-and-recall.md +160 -0
- package/docs/concepts/observability.md +41 -0
- package/docs/concepts/roles-and-workflows.md +59 -0
- package/docs/concepts/terminology-policy.md +27 -0
- package/docs/getting-started/01-installation.md +78 -0
- package/docs/getting-started/02-first-run.md +102 -0
- package/docs/getting-started/03-adding-to-project.md +15 -0
- package/docs/getting-started/04-host-setup.md +15 -0
- package/docs/guides/ci-integration.md +15 -0
- package/docs/guides/creating-skills.md +15 -0
- package/docs/guides/expertise-module-authoring.md +15 -0
- package/docs/guides/hook-development.md +15 -0
- package/docs/guides/memory-and-learnings.md +34 -0
- package/docs/guides/multi-host-export.md +15 -0
- package/docs/guides/troubleshooting.md +101 -0
- package/docs/guides/writing-custom-roles.md +15 -0
- package/docs/plans/2026-03-15-cli-pipeline-integration-design.md +592 -0
- package/docs/plans/2026-03-15-cli-pipeline-integration-plan.md +598 -0
- package/docs/plans/2026-03-15-docs-enforcement-plan.md +238 -0
- package/docs/readmes/INDEX.md +99 -0
- package/docs/readmes/features/expertise/README.md +171 -0
- package/docs/readmes/features/exports/README.md +222 -0
- package/docs/readmes/features/hooks/README.md +103 -0
- package/docs/readmes/features/hooks/loop-cap-guard.md +133 -0
- package/docs/readmes/features/hooks/post-tool-capture.md +121 -0
- package/docs/readmes/features/hooks/post-tool-lint.md +130 -0
- package/docs/readmes/features/hooks/pre-compact-summary.md +122 -0
- package/docs/readmes/features/hooks/pre-tool-capture-route.md +100 -0
- package/docs/readmes/features/hooks/protected-path-write-guard.md +128 -0
- package/docs/readmes/features/hooks/session-start.md +119 -0
- package/docs/readmes/features/hooks/stop-handoff-harvest.md +125 -0
- package/docs/readmes/features/roles/README.md +157 -0
- package/docs/readmes/features/roles/clarifier.md +152 -0
- package/docs/readmes/features/roles/content-author.md +190 -0
- package/docs/readmes/features/roles/designer.md +193 -0
- package/docs/readmes/features/roles/executor.md +184 -0
- package/docs/readmes/features/roles/learner.md +210 -0
- package/docs/readmes/features/roles/planner.md +182 -0
- package/docs/readmes/features/roles/researcher.md +164 -0
- package/docs/readmes/features/roles/reviewer.md +184 -0
- package/docs/readmes/features/roles/specifier.md +162 -0
- package/docs/readmes/features/roles/verifier.md +215 -0
- package/docs/readmes/features/schemas/README.md +178 -0
- package/docs/readmes/features/skills/README.md +63 -0
- package/docs/readmes/features/skills/brainstorming.md +96 -0
- package/docs/readmes/features/skills/debugging.md +148 -0
- package/docs/readmes/features/skills/design.md +120 -0
- package/docs/readmes/features/skills/prepare-next.md +109 -0
- package/docs/readmes/features/skills/run-audit.md +159 -0
- package/docs/readmes/features/skills/scan-project.md +109 -0
- package/docs/readmes/features/skills/self-audit.md +176 -0
- package/docs/readmes/features/skills/tdd.md +137 -0
- package/docs/readmes/features/skills/using-skills.md +92 -0
- package/docs/readmes/features/skills/verification.md +120 -0
- package/docs/readmes/features/skills/writing-plans.md +104 -0
- package/docs/readmes/features/tooling/README.md +320 -0
- package/docs/readmes/features/workflows/README.md +186 -0
- package/docs/readmes/features/workflows/author.md +181 -0
- package/docs/readmes/features/workflows/clarify.md +154 -0
- package/docs/readmes/features/workflows/design-review.md +171 -0
- package/docs/readmes/features/workflows/design.md +169 -0
- package/docs/readmes/features/workflows/discover.md +162 -0
- package/docs/readmes/features/workflows/execute.md +173 -0
- package/docs/readmes/features/workflows/learn.md +167 -0
- package/docs/readmes/features/workflows/plan-review.md +165 -0
- package/docs/readmes/features/workflows/plan.md +170 -0
- package/docs/readmes/features/workflows/prepare-next.md +167 -0
- package/docs/readmes/features/workflows/review.md +169 -0
- package/docs/readmes/features/workflows/run-audit.md +191 -0
- package/docs/readmes/features/workflows/spec-challenge.md +159 -0
- package/docs/readmes/features/workflows/specify.md +160 -0
- package/docs/readmes/features/workflows/verify.md +177 -0
- package/docs/readmes/packages/README.md +50 -0
- package/docs/readmes/packages/ajv.md +117 -0
- package/docs/readmes/packages/context-mode.md +118 -0
- package/docs/readmes/packages/gray-matter.md +116 -0
- package/docs/readmes/packages/node-test.md +137 -0
- package/docs/readmes/packages/yaml.md +112 -0
- package/docs/reference/configuration-reference.md +159 -0
- package/docs/reference/expertise-index.md +52 -0
- package/docs/reference/git-flow.md +43 -0
- package/docs/reference/hooks.md +87 -0
- package/docs/reference/host-exports.md +50 -0
- package/docs/reference/launch-checklist.md +172 -0
- package/docs/reference/marketplace-listings.md +76 -0
- package/docs/reference/release-process.md +34 -0
- package/docs/reference/roles-reference.md +77 -0
- package/docs/reference/skills.md +33 -0
- package/docs/reference/templates.md +29 -0
- package/docs/reference/tooling-cli.md +94 -0
- package/docs/truth-claims.yaml +222 -0
- package/expertise/PROGRESS.md +63 -0
- package/expertise/README.md +18 -0
- package/expertise/antipatterns/PROGRESS.md +56 -0
- package/expertise/antipatterns/backend/api-design-antipatterns.md +1271 -0
- package/expertise/antipatterns/backend/auth-antipatterns.md +1195 -0
- package/expertise/antipatterns/backend/caching-antipatterns.md +622 -0
- package/expertise/antipatterns/backend/database-antipatterns.md +1038 -0
- package/expertise/antipatterns/backend/index.md +24 -0
- package/expertise/antipatterns/backend/microservices-antipatterns.md +850 -0
- package/expertise/antipatterns/code/architecture-antipatterns.md +919 -0
- package/expertise/antipatterns/code/async-antipatterns.md +622 -0
- package/expertise/antipatterns/code/code-smells.md +1186 -0
- package/expertise/antipatterns/code/dependency-antipatterns.md +1209 -0
- package/expertise/antipatterns/code/error-handling-antipatterns.md +1360 -0
- package/expertise/antipatterns/code/index.md +27 -0
- package/expertise/antipatterns/code/naming-and-abstraction.md +1118 -0
- package/expertise/antipatterns/code/state-management-antipatterns.md +1076 -0
- package/expertise/antipatterns/code/testing-antipatterns.md +1053 -0
- package/expertise/antipatterns/design/accessibility-antipatterns.md +1136 -0
- package/expertise/antipatterns/design/dark-patterns.md +1121 -0
- package/expertise/antipatterns/design/index.md +22 -0
- package/expertise/antipatterns/design/ui-antipatterns.md +1202 -0
- package/expertise/antipatterns/design/ux-antipatterns.md +680 -0
- package/expertise/antipatterns/frontend/css-layout-antipatterns.md +691 -0
- package/expertise/antipatterns/frontend/flutter-antipatterns.md +1827 -0
- package/expertise/antipatterns/frontend/index.md +23 -0
- package/expertise/antipatterns/frontend/mobile-antipatterns.md +573 -0
- package/expertise/antipatterns/frontend/react-antipatterns.md +1128 -0
- package/expertise/antipatterns/frontend/spa-antipatterns.md +1235 -0
- package/expertise/antipatterns/index.md +31 -0
- package/expertise/antipatterns/performance/index.md +20 -0
- package/expertise/antipatterns/performance/performance-antipatterns.md +1013 -0
- package/expertise/antipatterns/performance/premature-optimization.md +623 -0
- package/expertise/antipatterns/performance/scaling-antipatterns.md +785 -0
- package/expertise/antipatterns/process/ai-coding-antipatterns.md +853 -0
- package/expertise/antipatterns/process/code-review-antipatterns.md +656 -0
- package/expertise/antipatterns/process/deployment-antipatterns.md +920 -0
- package/expertise/antipatterns/process/index.md +23 -0
- package/expertise/antipatterns/process/technical-debt-antipatterns.md +647 -0
- package/expertise/antipatterns/security/index.md +20 -0
- package/expertise/antipatterns/security/secrets-antipatterns.md +849 -0
- package/expertise/antipatterns/security/security-theater.md +843 -0
- package/expertise/antipatterns/security/vulnerability-patterns.md +801 -0
- package/expertise/architecture/PROGRESS.md +70 -0
- package/expertise/architecture/data/caching-architecture.md +671 -0
- package/expertise/architecture/data/data-consistency.md +574 -0
- package/expertise/architecture/data/data-modeling.md +536 -0
- package/expertise/architecture/data/event-streams-and-queues.md +634 -0
- package/expertise/architecture/data/index.md +25 -0
- package/expertise/architecture/data/search-architecture.md +663 -0
- package/expertise/architecture/data/sql-vs-nosql.md +708 -0
- package/expertise/architecture/decisions/architecture-decision-records.md +640 -0
- package/expertise/architecture/decisions/build-vs-buy.md +616 -0
- package/expertise/architecture/decisions/index.md +23 -0
- package/expertise/architecture/decisions/monolith-to-microservices.md +790 -0
- package/expertise/architecture/decisions/technology-selection.md +616 -0
- package/expertise/architecture/distributed/cap-theorem-and-tradeoffs.md +800 -0
- package/expertise/architecture/distributed/circuit-breaker-bulkhead.md +741 -0
- package/expertise/architecture/distributed/consensus-and-coordination.md +796 -0
- package/expertise/architecture/distributed/distributed-systems-fundamentals.md +564 -0
- package/expertise/architecture/distributed/idempotency-and-retry.md +796 -0
- package/expertise/architecture/distributed/index.md +25 -0
- package/expertise/architecture/distributed/saga-pattern.md +797 -0
- package/expertise/architecture/foundations/architectural-thinking.md +460 -0
- package/expertise/architecture/foundations/coupling-and-cohesion.md +770 -0
- package/expertise/architecture/foundations/design-principles-solid.md +649 -0
- package/expertise/architecture/foundations/domain-driven-design.md +719 -0
- package/expertise/architecture/foundations/index.md +25 -0
- package/expertise/architecture/foundations/separation-of-concerns.md +472 -0
- package/expertise/architecture/foundations/twelve-factor-app.md +797 -0
- package/expertise/architecture/index.md +34 -0
- package/expertise/architecture/integration/api-design-graphql.md +638 -0
- package/expertise/architecture/integration/api-design-grpc.md +804 -0
- package/expertise/architecture/integration/api-design-rest.md +892 -0
- package/expertise/architecture/integration/index.md +25 -0
- package/expertise/architecture/integration/third-party-integration.md +795 -0
- package/expertise/architecture/integration/webhooks-and-callbacks.md +1152 -0
- package/expertise/architecture/integration/websockets-realtime.md +791 -0
- package/expertise/architecture/mobile-architecture/index.md +22 -0
- package/expertise/architecture/mobile-architecture/mobile-app-architecture.md +780 -0
- package/expertise/architecture/mobile-architecture/mobile-backend-for-frontend.md +670 -0
- package/expertise/architecture/mobile-architecture/offline-first.md +719 -0
- package/expertise/architecture/mobile-architecture/push-and-sync.md +782 -0
- package/expertise/architecture/patterns/cqrs-event-sourcing.md +717 -0
- package/expertise/architecture/patterns/event-driven.md +797 -0
- package/expertise/architecture/patterns/hexagonal-clean-architecture.md +870 -0
- package/expertise/architecture/patterns/index.md +27 -0
- package/expertise/architecture/patterns/layered-architecture.md +736 -0
- package/expertise/architecture/patterns/microservices.md +753 -0
- package/expertise/architecture/patterns/modular-monolith.md +692 -0
- package/expertise/architecture/patterns/monolith.md +626 -0
- package/expertise/architecture/patterns/plugin-architecture.md +735 -0
- package/expertise/architecture/patterns/serverless.md +780 -0
- package/expertise/architecture/scaling/database-scaling.md +615 -0
- package/expertise/architecture/scaling/feature-flags-and-rollouts.md +757 -0
- package/expertise/architecture/scaling/horizontal-vs-vertical.md +606 -0
- package/expertise/architecture/scaling/index.md +24 -0
- package/expertise/architecture/scaling/multi-tenancy.md +800 -0
- package/expertise/architecture/scaling/stateless-design.md +787 -0
- package/expertise/backend/embedded-firmware.md +625 -0
- package/expertise/backend/go.md +853 -0
- package/expertise/backend/index.md +24 -0
- package/expertise/backend/java-spring.md +448 -0
- package/expertise/backend/node-typescript.md +625 -0
- package/expertise/backend/python-fastapi.md +724 -0
- package/expertise/backend/rust.md +458 -0
- package/expertise/backend/solidity.md +711 -0
- package/expertise/composition-map.yaml +443 -0
- package/expertise/content/foundations/content-modeling.md +395 -0
- package/expertise/content/foundations/editorial-standards.md +449 -0
- package/expertise/content/foundations/index.md +24 -0
- package/expertise/content/foundations/microcopy.md +455 -0
- package/expertise/content/foundations/terminology-governance.md +509 -0
- package/expertise/content/index.md +34 -0
- package/expertise/content/patterns/accessibility-copy.md +518 -0
- package/expertise/content/patterns/index.md +24 -0
- package/expertise/content/patterns/notification-content.md +433 -0
- package/expertise/content/patterns/sample-content.md +486 -0
- package/expertise/content/patterns/state-copy.md +439 -0
- package/expertise/design/PROGRESS.md +58 -0
- package/expertise/design/disciplines/dark-mode-theming.md +577 -0
- package/expertise/design/disciplines/design-systems.md +595 -0
- package/expertise/design/disciplines/index.md +25 -0
- package/expertise/design/disciplines/information-architecture.md +800 -0
- package/expertise/design/disciplines/interaction-design.md +788 -0
- package/expertise/design/disciplines/responsive-design.md +552 -0
- package/expertise/design/disciplines/usability-testing.md +516 -0
- package/expertise/design/disciplines/user-research.md +792 -0
- package/expertise/design/foundations/accessibility-design.md +796 -0
- package/expertise/design/foundations/color-theory.md +797 -0
- package/expertise/design/foundations/iconography.md +795 -0
- package/expertise/design/foundations/index.md +26 -0
- package/expertise/design/foundations/motion-and-animation.md +653 -0
- package/expertise/design/foundations/rtl-design.md +585 -0
- package/expertise/design/foundations/spacing-and-layout.md +607 -0
- package/expertise/design/foundations/typography.md +800 -0
- package/expertise/design/foundations/visual-hierarchy.md +761 -0
- package/expertise/design/index.md +32 -0
- package/expertise/design/patterns/authentication-flows.md +474 -0
- package/expertise/design/patterns/content-consumption.md +789 -0
- package/expertise/design/patterns/data-display.md +618 -0
- package/expertise/design/patterns/e-commerce.md +1494 -0
- package/expertise/design/patterns/feedback-and-states.md +642 -0
- package/expertise/design/patterns/forms-and-input.md +819 -0
- package/expertise/design/patterns/gamification.md +801 -0
- package/expertise/design/patterns/index.md +31 -0
- package/expertise/design/patterns/microinteractions.md +449 -0
- package/expertise/design/patterns/navigation.md +800 -0
- package/expertise/design/patterns/notifications.md +705 -0
- package/expertise/design/patterns/onboarding.md +700 -0
- package/expertise/design/patterns/search-and-filter.md +601 -0
- package/expertise/design/patterns/settings-and-preferences.md +768 -0
- package/expertise/design/patterns/social-and-community.md +748 -0
- package/expertise/design/platforms/desktop-native.md +612 -0
- package/expertise/design/platforms/index.md +25 -0
- package/expertise/design/platforms/mobile-android.md +825 -0
- package/expertise/design/platforms/mobile-cross-platform.md +983 -0
- package/expertise/design/platforms/mobile-ios.md +699 -0
- package/expertise/design/platforms/tablet.md +794 -0
- package/expertise/design/platforms/web-dashboard.md +790 -0
- package/expertise/design/platforms/web-responsive.md +550 -0
- package/expertise/design/psychology/behavioral-nudges.md +449 -0
- package/expertise/design/psychology/cognitive-load.md +1191 -0
- package/expertise/design/psychology/error-psychology.md +778 -0
- package/expertise/design/psychology/index.md +22 -0
- package/expertise/design/psychology/persuasive-design.md +736 -0
- package/expertise/design/psychology/user-mental-models.md +623 -0
- package/expertise/design/tooling/open-pencil.md +266 -0
- package/expertise/frontend/angular.md +1073 -0
- package/expertise/frontend/desktop-electron.md +546 -0
- package/expertise/frontend/flutter.md +782 -0
- package/expertise/frontend/index.md +27 -0
- package/expertise/frontend/native-android.md +409 -0
- package/expertise/frontend/native-ios.md +490 -0
- package/expertise/frontend/react-native.md +1160 -0
- package/expertise/frontend/react.md +808 -0
- package/expertise/frontend/vue.md +1089 -0
- package/expertise/humanize/domain-rules-code.md +79 -0
- package/expertise/humanize/domain-rules-content.md +67 -0
- package/expertise/humanize/domain-rules-technical-docs.md +56 -0
- package/expertise/humanize/index.md +35 -0
- package/expertise/humanize/self-audit-checklist.md +87 -0
- package/expertise/humanize/sentence-patterns.md +218 -0
- package/expertise/humanize/vocabulary-blacklist.md +105 -0
- package/expertise/i18n/PROGRESS.md +65 -0
- package/expertise/i18n/advanced/accessibility-and-i18n.md +28 -0
- package/expertise/i18n/advanced/bidirectional-text-algorithm.md +38 -0
- package/expertise/i18n/advanced/complex-scripts.md +30 -0
- package/expertise/i18n/advanced/performance-and-i18n.md +27 -0
- package/expertise/i18n/advanced/testing-i18n.md +28 -0
- package/expertise/i18n/content/content-adaptation.md +23 -0
- package/expertise/i18n/content/locale-specific-formatting.md +23 -0
- package/expertise/i18n/content/machine-translation-integration.md +28 -0
- package/expertise/i18n/content/translation-management.md +29 -0
- package/expertise/i18n/foundations/date-time-calendars.md +67 -0
- package/expertise/i18n/foundations/i18n-architecture.md +272 -0
- package/expertise/i18n/foundations/locale-and-language-tags.md +79 -0
- package/expertise/i18n/foundations/numbers-currency-units.md +61 -0
- package/expertise/i18n/foundations/pluralization-and-gender.md +109 -0
- package/expertise/i18n/foundations/string-externalization.md +236 -0
- package/expertise/i18n/foundations/text-direction-bidi.md +241 -0
- package/expertise/i18n/foundations/unicode-and-encoding.md +86 -0
- package/expertise/i18n/index.md +38 -0
- package/expertise/i18n/platform/backend-i18n.md +31 -0
- package/expertise/i18n/platform/flutter-i18n.md +148 -0
- package/expertise/i18n/platform/native-android-i18n.md +36 -0
- package/expertise/i18n/platform/native-ios-i18n.md +36 -0
- package/expertise/i18n/platform/react-i18n.md +103 -0
- package/expertise/i18n/platform/web-css-i18n.md +81 -0
- package/expertise/i18n/rtl/arabic-specific.md +175 -0
- package/expertise/i18n/rtl/hebrew-specific.md +149 -0
- package/expertise/i18n/rtl/rtl-animations-and-transitions.md +111 -0
- package/expertise/i18n/rtl/rtl-forms-and-input.md +161 -0
- package/expertise/i18n/rtl/rtl-fundamentals.md +211 -0
- package/expertise/i18n/rtl/rtl-icons-and-images.md +181 -0
- package/expertise/i18n/rtl/rtl-layout-mirroring.md +252 -0
- package/expertise/i18n/rtl/rtl-navigation-and-gestures.md +107 -0
- package/expertise/i18n/rtl/rtl-testing-and-qa.md +147 -0
- package/expertise/i18n/rtl/rtl-typography.md +160 -0
- package/expertise/index.md +113 -0
- package/expertise/index.yaml +216 -0
- package/expertise/infrastructure/cloud-aws.md +597 -0
- package/expertise/infrastructure/cloud-gcp.md +599 -0
- package/expertise/infrastructure/cybersecurity.md +816 -0
- package/expertise/infrastructure/database-mongodb.md +447 -0
- package/expertise/infrastructure/database-postgres.md +400 -0
- package/expertise/infrastructure/devops-cicd.md +787 -0
- package/expertise/infrastructure/index.md +27 -0
- package/expertise/performance/PROGRESS.md +50 -0
- package/expertise/performance/backend/api-latency.md +1204 -0
- package/expertise/performance/backend/background-jobs.md +506 -0
- package/expertise/performance/backend/connection-pooling.md +1209 -0
- package/expertise/performance/backend/database-query-optimization.md +515 -0
- package/expertise/performance/backend/index.md +23 -0
- package/expertise/performance/backend/rate-limiting-and-throttling.md +971 -0
- package/expertise/performance/foundations/algorithmic-complexity.md +954 -0
- package/expertise/performance/foundations/caching-strategies.md +489 -0
- package/expertise/performance/foundations/concurrency-and-parallelism.md +847 -0
- package/expertise/performance/foundations/index.md +24 -0
- package/expertise/performance/foundations/measuring-and-profiling.md +440 -0
- package/expertise/performance/foundations/memory-management.md +964 -0
- package/expertise/performance/foundations/performance-budgets.md +1314 -0
- package/expertise/performance/index.md +31 -0
- package/expertise/performance/infrastructure/auto-scaling.md +1059 -0
- package/expertise/performance/infrastructure/cdn-and-edge.md +1081 -0
- package/expertise/performance/infrastructure/index.md +22 -0
- package/expertise/performance/infrastructure/load-balancing.md +1081 -0
- package/expertise/performance/infrastructure/observability.md +1079 -0
- package/expertise/performance/mobile/index.md +23 -0
- package/expertise/performance/mobile/mobile-animations.md +544 -0
- package/expertise/performance/mobile/mobile-memory-battery.md +416 -0
- package/expertise/performance/mobile/mobile-network.md +452 -0
- package/expertise/performance/mobile/mobile-rendering.md +599 -0
- package/expertise/performance/mobile/mobile-startup-time.md +505 -0
- package/expertise/performance/platform-specific/flutter-performance.md +647 -0
- package/expertise/performance/platform-specific/index.md +22 -0
- package/expertise/performance/platform-specific/node-performance.md +1307 -0
- package/expertise/performance/platform-specific/postgres-performance.md +1366 -0
- package/expertise/performance/platform-specific/react-performance.md +1403 -0
- package/expertise/performance/web/bundle-optimization.md +1239 -0
- package/expertise/performance/web/image-and-media.md +636 -0
- package/expertise/performance/web/index.md +24 -0
- package/expertise/performance/web/network-optimization.md +1133 -0
- package/expertise/performance/web/rendering-performance.md +1098 -0
- package/expertise/performance/web/ssr-and-hydration.md +918 -0
- package/expertise/performance/web/web-vitals.md +1374 -0
- package/expertise/quality/accessibility.md +985 -0
- package/expertise/quality/evidence-based-verification.md +499 -0
- package/expertise/quality/index.md +24 -0
- package/expertise/quality/ml-model-audit.md +614 -0
- package/expertise/quality/performance.md +600 -0
- package/expertise/quality/testing-api.md +891 -0
- package/expertise/quality/testing-mobile.md +496 -0
- package/expertise/quality/testing-web.md +849 -0
- package/expertise/security/PROGRESS.md +54 -0
- package/expertise/security/agentic-identity.md +540 -0
- package/expertise/security/compliance-frameworks.md +601 -0
- package/expertise/security/data/data-encryption.md +364 -0
- package/expertise/security/data/data-privacy-gdpr.md +692 -0
- package/expertise/security/data/database-security.md +1171 -0
- package/expertise/security/data/index.md +22 -0
- package/expertise/security/data/pii-handling.md +531 -0
- package/expertise/security/foundations/authentication.md +1041 -0
- package/expertise/security/foundations/authorization.md +603 -0
- package/expertise/security/foundations/cryptography.md +1001 -0
- package/expertise/security/foundations/index.md +25 -0
- package/expertise/security/foundations/owasp-top-10.md +1354 -0
- package/expertise/security/foundations/secrets-management.md +1217 -0
- package/expertise/security/foundations/secure-sdlc.md +700 -0
- package/expertise/security/foundations/supply-chain-security.md +698 -0
- package/expertise/security/index.md +31 -0
- package/expertise/security/infrastructure/cloud-security-aws.md +1296 -0
- package/expertise/security/infrastructure/cloud-security-gcp.md +1376 -0
- package/expertise/security/infrastructure/container-security.md +721 -0
- package/expertise/security/infrastructure/incident-response.md +1295 -0
- package/expertise/security/infrastructure/index.md +24 -0
- package/expertise/security/infrastructure/logging-and-monitoring.md +1618 -0
- package/expertise/security/infrastructure/network-security.md +1337 -0
- package/expertise/security/mobile/index.md +23 -0
- package/expertise/security/mobile/mobile-android-security.md +1218 -0
- package/expertise/security/mobile/mobile-binary-protection.md +1229 -0
- package/expertise/security/mobile/mobile-data-storage.md +1265 -0
- package/expertise/security/mobile/mobile-ios-security.md +1401 -0
- package/expertise/security/mobile/mobile-network-security.md +1520 -0
- package/expertise/security/smart-contract-security.md +594 -0
- package/expertise/security/testing/index.md +22 -0
- package/expertise/security/testing/penetration-testing.md +1258 -0
- package/expertise/security/testing/security-code-review.md +1765 -0
- package/expertise/security/testing/threat-modeling.md +1074 -0
- package/expertise/security/testing/vulnerability-scanning.md +1062 -0
- package/expertise/security/web/api-security.md +586 -0
- package/expertise/security/web/cors-and-headers.md +433 -0
- package/expertise/security/web/csrf.md +562 -0
- package/expertise/security/web/file-upload.md +1477 -0
- package/expertise/security/web/index.md +25 -0
- package/expertise/security/web/injection.md +1375 -0
- package/expertise/security/web/session-management.md +1101 -0
- package/expertise/security/web/xss.md +1158 -0
- package/exports/README.md +17 -0
- package/exports/hosts/claude/.claude/agents/clarifier.md +42 -0
- package/exports/hosts/claude/.claude/agents/content-author.md +63 -0
- package/exports/hosts/claude/.claude/agents/designer.md +55 -0
- package/exports/hosts/claude/.claude/agents/executor.md +55 -0
- package/exports/hosts/claude/.claude/agents/learner.md +51 -0
- package/exports/hosts/claude/.claude/agents/planner.md +53 -0
- package/exports/hosts/claude/.claude/agents/researcher.md +43 -0
- package/exports/hosts/claude/.claude/agents/reviewer.md +54 -0
- package/exports/hosts/claude/.claude/agents/specifier.md +47 -0
- package/exports/hosts/claude/.claude/agents/verifier.md +71 -0
- package/exports/hosts/claude/.claude/commands/author.md +42 -0
- package/exports/hosts/claude/.claude/commands/clarify.md +38 -0
- package/exports/hosts/claude/.claude/commands/design-review.md +46 -0
- package/exports/hosts/claude/.claude/commands/design.md +44 -0
- package/exports/hosts/claude/.claude/commands/discover.md +37 -0
- package/exports/hosts/claude/.claude/commands/execute.md +48 -0
- package/exports/hosts/claude/.claude/commands/learn.md +38 -0
- package/exports/hosts/claude/.claude/commands/plan-review.md +42 -0
- package/exports/hosts/claude/.claude/commands/plan.md +39 -0
- package/exports/hosts/claude/.claude/commands/prepare-next.md +37 -0
- package/exports/hosts/claude/.claude/commands/review.md +40 -0
- package/exports/hosts/claude/.claude/commands/run-audit.md +41 -0
- package/exports/hosts/claude/.claude/commands/spec-challenge.md +41 -0
- package/exports/hosts/claude/.claude/commands/specify.md +38 -0
- package/exports/hosts/claude/.claude/commands/verify.md +37 -0
- package/exports/hosts/claude/.claude/settings.json +34 -0
- package/exports/hosts/claude/CLAUDE.md +19 -0
- package/exports/hosts/claude/export.manifest.json +38 -0
- package/exports/hosts/claude/host-package.json +67 -0
- package/exports/hosts/codex/AGENTS.md +19 -0
- package/exports/hosts/codex/export.manifest.json +38 -0
- package/exports/hosts/codex/host-package.json +41 -0
- package/exports/hosts/cursor/.cursor/hooks.json +16 -0
- package/exports/hosts/cursor/.cursor/rules/wazir-core.mdc +19 -0
- package/exports/hosts/cursor/export.manifest.json +38 -0
- package/exports/hosts/cursor/host-package.json +42 -0
- package/exports/hosts/gemini/GEMINI.md +19 -0
- package/exports/hosts/gemini/export.manifest.json +38 -0
- package/exports/hosts/gemini/host-package.json +41 -0
- package/hooks/README.md +18 -0
- package/hooks/definitions/loop_cap_guard.yaml +21 -0
- package/hooks/definitions/post_tool_capture.yaml +24 -0
- package/hooks/definitions/pre_compact_summary.yaml +19 -0
- package/hooks/definitions/pre_tool_capture_route.yaml +19 -0
- package/hooks/definitions/protected_path_write_guard.yaml +19 -0
- package/hooks/definitions/session_start.yaml +19 -0
- package/hooks/definitions/stop_handoff_harvest.yaml +20 -0
- package/hooks/loop-cap-guard +17 -0
- package/hooks/post-tool-lint +36 -0
- package/hooks/protected-path-write-guard +17 -0
- package/hooks/session-start +41 -0
- package/llms-full.txt +2355 -0
- package/llms.txt +43 -0
- package/package.json +79 -0
- package/roles/README.md +20 -0
- package/roles/clarifier.md +42 -0
- package/roles/content-author.md +63 -0
- package/roles/designer.md +55 -0
- package/roles/executor.md +55 -0
- package/roles/learner.md +51 -0
- package/roles/planner.md +53 -0
- package/roles/researcher.md +43 -0
- package/roles/reviewer.md +54 -0
- package/roles/specifier.md +47 -0
- package/roles/verifier.md +71 -0
- package/schemas/README.md +24 -0
- package/schemas/accepted-learning.schema.json +20 -0
- package/schemas/author-artifact.schema.json +156 -0
- package/schemas/clarification.schema.json +19 -0
- package/schemas/design-artifact.schema.json +80 -0
- package/schemas/docs-claim.schema.json +18 -0
- package/schemas/export-manifest.schema.json +20 -0
- package/schemas/hook.schema.json +67 -0
- package/schemas/host-export-package.schema.json +18 -0
- package/schemas/implementation-plan.schema.json +19 -0
- package/schemas/proposed-learning.schema.json +19 -0
- package/schemas/research.schema.json +18 -0
- package/schemas/review.schema.json +29 -0
- package/schemas/run-manifest.schema.json +18 -0
- package/schemas/spec-challenge.schema.json +18 -0
- package/schemas/spec.schema.json +20 -0
- package/schemas/usage.schema.json +102 -0
- package/schemas/verification-proof.schema.json +29 -0
- package/schemas/wazir-manifest.schema.json +173 -0
- package/skills/README.md +40 -0
- package/skills/brainstorming/SKILL.md +77 -0
- package/skills/debugging/SKILL.md +50 -0
- package/skills/design/SKILL.md +61 -0
- package/skills/dispatching-parallel-agents/SKILL.md +128 -0
- package/skills/executing-plans/SKILL.md +70 -0
- package/skills/finishing-a-development-branch/SKILL.md +169 -0
- package/skills/humanize/SKILL.md +123 -0
- package/skills/init-pipeline/SKILL.md +124 -0
- package/skills/prepare-next/SKILL.md +20 -0
- package/skills/receiving-code-review/SKILL.md +123 -0
- package/skills/requesting-code-review/SKILL.md +105 -0
- package/skills/requesting-code-review/code-reviewer.md +108 -0
- package/skills/run-audit/SKILL.md +197 -0
- package/skills/scan-project/SKILL.md +41 -0
- package/skills/self-audit/SKILL.md +153 -0
- package/skills/subagent-driven-development/SKILL.md +154 -0
- package/skills/subagent-driven-development/code-quality-reviewer-prompt.md +26 -0
- package/skills/subagent-driven-development/implementer-prompt.md +102 -0
- package/skills/subagent-driven-development/spec-reviewer-prompt.md +61 -0
- package/skills/tdd/SKILL.md +23 -0
- package/skills/using-git-worktrees/SKILL.md +163 -0
- package/skills/using-skills/SKILL.md +95 -0
- package/skills/verification/SKILL.md +22 -0
- package/skills/wazir/SKILL.md +463 -0
- package/skills/writing-plans/SKILL.md +30 -0
- package/skills/writing-skills/SKILL.md +157 -0
- package/skills/writing-skills/anthropic-best-practices.md +122 -0
- package/skills/writing-skills/persuasion-principles.md +50 -0
- package/templates/README.md +20 -0
- package/templates/artifacts/README.md +10 -0
- package/templates/artifacts/accepted-learning.md +19 -0
- package/templates/artifacts/accepted-learning.template.json +12 -0
- package/templates/artifacts/author.md +74 -0
- package/templates/artifacts/author.template.json +19 -0
- package/templates/artifacts/clarification.md +21 -0
- package/templates/artifacts/clarification.template.json +12 -0
- package/templates/artifacts/execute-notes.md +19 -0
- package/templates/artifacts/implementation-plan.md +21 -0
- package/templates/artifacts/implementation-plan.template.json +11 -0
- package/templates/artifacts/learning-proposal.md +19 -0
- package/templates/artifacts/next-run-handoff.md +21 -0
- package/templates/artifacts/plan-review.md +19 -0
- package/templates/artifacts/proposed-learning.template.json +12 -0
- package/templates/artifacts/research.md +21 -0
- package/templates/artifacts/research.template.json +12 -0
- package/templates/artifacts/review-findings.md +19 -0
- package/templates/artifacts/review.template.json +11 -0
- package/templates/artifacts/run-manifest.template.json +8 -0
- package/templates/artifacts/spec-challenge.md +19 -0
- package/templates/artifacts/spec-challenge.template.json +11 -0
- package/templates/artifacts/spec.md +21 -0
- package/templates/artifacts/spec.template.json +12 -0
- package/templates/artifacts/verification-proof.md +19 -0
- package/templates/artifacts/verification-proof.template.json +11 -0
- package/templates/examples/accepted-learning.example.json +14 -0
- package/templates/examples/author.example.json +152 -0
- package/templates/examples/clarification.example.json +15 -0
- package/templates/examples/docs-claim.example.json +8 -0
- package/templates/examples/export-manifest.example.json +7 -0
- package/templates/examples/host-export-package.example.json +11 -0
- package/templates/examples/implementation-plan.example.json +17 -0
- package/templates/examples/proposed-learning.example.json +13 -0
- package/templates/examples/research.example.json +15 -0
- package/templates/examples/research.example.md +6 -0
- package/templates/examples/review.example.json +17 -0
- package/templates/examples/run-manifest.example.json +9 -0
- package/templates/examples/spec-challenge.example.json +14 -0
- package/templates/examples/spec.example.json +21 -0
- package/templates/examples/verification-proof.example.json +21 -0
- package/templates/examples/wazir-manifest.example.yaml +65 -0
- package/templates/task-definition-schema.md +99 -0
- package/tooling/README.md +20 -0
- package/tooling/src/adapters/context-mode.js +50 -0
- package/tooling/src/capture/command.js +376 -0
- package/tooling/src/capture/store.js +99 -0
- package/tooling/src/capture/usage.js +270 -0
- package/tooling/src/checks/branches.js +50 -0
- package/tooling/src/checks/brand-truth.js +110 -0
- package/tooling/src/checks/changelog.js +231 -0
- package/tooling/src/checks/command-registry.js +36 -0
- package/tooling/src/checks/commits.js +102 -0
- package/tooling/src/checks/docs-drift.js +103 -0
- package/tooling/src/checks/docs-truth.js +201 -0
- package/tooling/src/checks/runtime-surface.js +156 -0
- package/tooling/src/cli.js +116 -0
- package/tooling/src/command-options.js +56 -0
- package/tooling/src/commands/validate.js +320 -0
- package/tooling/src/doctor/command.js +91 -0
- package/tooling/src/export/command.js +77 -0
- package/tooling/src/export/compiler.js +498 -0
- package/tooling/src/guards/loop-cap-guard.js +52 -0
- package/tooling/src/guards/protected-path-write-guard.js +67 -0
- package/tooling/src/index/command.js +152 -0
- package/tooling/src/index/storage.js +1061 -0
- package/tooling/src/index/summarizers.js +261 -0
- package/tooling/src/loaders.js +18 -0
- package/tooling/src/project-root.js +22 -0
- package/tooling/src/recall/command.js +225 -0
- package/tooling/src/schema-validator.js +30 -0
- package/tooling/src/state-root.js +40 -0
- package/tooling/src/status/command.js +71 -0
- package/wazir.manifest.yaml +135 -0
- package/workflows/README.md +19 -0
- package/workflows/author.md +42 -0
- package/workflows/clarify.md +38 -0
- package/workflows/design-review.md +46 -0
- package/workflows/design.md +44 -0
- package/workflows/discover.md +37 -0
- package/workflows/execute.md +48 -0
- package/workflows/learn.md +38 -0
- package/workflows/plan-review.md +42 -0
- package/workflows/plan.md +39 -0
- package/workflows/prepare-next.md +37 -0
- package/workflows/review.md +40 -0
- package/workflows/run-audit.md +41 -0
- package/workflows/spec-challenge.md +41 -0
- package/workflows/specify.md +38 -0
- package/workflows/verify.md +37 -0
|
@@ -0,0 +1,849 @@
|
|
|
1
|
+
# Web Testing — Expertise Module
|
|
2
|
+
|
|
3
|
+
> A web testing specialist designs, implements, and maintains automated test suites that verify web application correctness, accessibility, performance, and security across browsers and devices. The scope spans unit/component tests through end-to-end flows, visual regression, accessibility audits, and security scanning — ensuring every code change ships with confidence while keeping feedback loops fast.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Core Patterns & Conventions
|
|
8
|
+
|
|
9
|
+
### Testing Trophy (Not Pyramid) for Web Applications
|
|
10
|
+
|
|
11
|
+
The traditional testing pyramid (many unit tests, fewer integration, fewest E2E) has been replaced in modern web development by Kent C. Dodds' **Testing Trophy**, which reorders priorities:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
E2E (~10%) — Playwright / Cypress
|
|
15
|
+
Integration (~50%) — RTL + Vitest / Jest
|
|
16
|
+
Unit (~20%) — Vitest / Jest (pure logic)
|
|
17
|
+
Static (~20%) — TypeScript + ESLint
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**Key principle**: "The more your tests resemble the way your software is used, the more confidence they can give you." Integration tests are king because modern UIs rely on composed components and backend services — testing them in isolation misses the real failure modes.
|
|
21
|
+
|
|
22
|
+
**Practical allocation** (Vitest 3.x+ with browser mode):
|
|
23
|
+
- ~70% integration tests (fast and reliable in browser mode)
|
|
24
|
+
- ~20% composable unit tests for pure logic
|
|
25
|
+
- ~10% accessibility + visual regression + E2E
|
|
26
|
+
|
|
27
|
+
### Component Testing Patterns
|
|
28
|
+
|
|
29
|
+
**React Testing Library (RTL) 16.x+ with Vitest 3.x+:**
|
|
30
|
+
- Query by role first (`getByRole`), then by label, then by text — never by test ID unless no accessible alternative exists
|
|
31
|
+
- Test user behavior, not implementation details — never assert on internal state or prop values
|
|
32
|
+
- Use `userEvent` (not `fireEvent`) for realistic interaction simulation
|
|
33
|
+
- Use `waitFor` for async state changes; avoid arbitrary `setTimeout`
|
|
34
|
+
- Mock child components for unit-level isolation; render full trees for integration
|
|
35
|
+
- Do not test single-use custom hooks in isolation — test the component that uses them
|
|
36
|
+
|
|
37
|
+
**Vue Test Utils 2.x with Vitest:**
|
|
38
|
+
- Mount with `mount()` for integration tests, `shallowMount()` for unit isolation
|
|
39
|
+
- Use `wrapper.find('[data-testid="..."]')` only as a last resort; prefer accessible selectors
|
|
40
|
+
- Await `nextTick()` after state mutations before asserting
|
|
41
|
+
|
|
42
|
+
### E2E Testing Patterns (Playwright 1.x)
|
|
43
|
+
|
|
44
|
+
**Locator strategy priority** (per Playwright team recommendation):
|
|
45
|
+
1. `getByRole()` — mirrors assistive technology perception
|
|
46
|
+
2. `getByLabel()` — form elements
|
|
47
|
+
3. `getByText()` — visible text content
|
|
48
|
+
4. `getByTestId()` — last resort for elements without accessible names
|
|
49
|
+
|
|
50
|
+
**Web-first assertions**: Always use `await expect(locator).toBeVisible()` instead of manual waits. Playwright auto-waits and retries until the condition is met or timeout expires.
|
|
51
|
+
|
|
52
|
+
**Test isolation**: Each test gets its own browser context with isolated storage, cookies, and session. Never share state between tests. Use `test.describe.configure({ mode: 'serial' })` only when absolutely necessary (e.g., multi-step purchase flow).
|
|
53
|
+
|
|
54
|
+
**Trace-based debugging**: In CI, enable traces on first retry (`trace: 'on-first-retry'`). The Playwright Trace Viewer provides timeline, DOM snapshots, network requests, and console logs — far superior to screenshots or video for debugging failures.
|
|
55
|
+
|
|
56
|
+
### Visual Regression Testing
|
|
57
|
+
|
|
58
|
+
**Three tiers of visual testing:**
|
|
59
|
+
|
|
60
|
+
| Tier | Tool | Best For |
|
|
61
|
+
|------|------|----------|
|
|
62
|
+
| Free / small teams | Playwright `toHaveScreenshot()` | Pixel-level diffing via pixelmatch, baselines in Git |
|
|
63
|
+
| Component-focused | Chromatic 3.x | Storybook-based, catches component-level regressions |
|
|
64
|
+
| Full-page / cross-browser | Percy (BrowserStack) | AI-powered diffing, filters rendering noise, cross-browser |
|
|
65
|
+
|
|
66
|
+
**Best practice**: Start with Playwright's built-in `toHaveScreenshot()` — it covers 80% of use cases at zero cost. When you outgrow it (cross-browser rendering, team review workflows, smart diffing), add Percy or Chromatic.
|
|
67
|
+
|
|
68
|
+
**Handling dynamic content**: Mask timestamps, avatars, and ads with CSS or `mask` option. Pin viewport sizes. Wait for fonts and images to load before capture. Percy's AI Review Agent (launched late 2025) draws bounding boxes around meaningful changes and filters ~40% of rendering noise.
|
|
69
|
+
|
|
70
|
+
### Accessibility Testing
|
|
71
|
+
|
|
72
|
+
**Automated accessibility testing catches only 30-40% of issues** — it is necessary but not sufficient.
|
|
73
|
+
|
|
74
|
+
**Integration with Playwright (axe-core 4.x):**
|
|
75
|
+
```typescript
|
|
76
|
+
import AxeBuilder from '@axe-core/playwright';
|
|
77
|
+
|
|
78
|
+
test('page meets WCAG 2.2 AA', async ({ page }) => {
|
|
79
|
+
await page.goto('/dashboard');
|
|
80
|
+
const results = await new AxeBuilder({ page })
|
|
81
|
+
.withTags(['wcag2a', 'wcag2aa', 'wcag22aa'])
|
|
82
|
+
.analyze();
|
|
83
|
+
expect(results.violations).toEqual([]);
|
|
84
|
+
});
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Tool roles:**
|
|
88
|
+
- **axe-core**: Gold standard rule engine. 70+ rules, covers WCAG 2.0/2.1/2.2 at A/AA/AAA levels. Minimal false positives.
|
|
89
|
+
- **Lighthouse**: Quick overview during development (uses axe-core under the hood but runs fewer rules). Best for CI score gates.
|
|
90
|
+
- **Manual testing**: Screen reader walkthroughs (VoiceOver, NVDA), keyboard-only navigation, color contrast checks with real users.
|
|
91
|
+
|
|
92
|
+
**Legal context (2026)**: ADA Title II deadline hit April 2026. EU European Accessibility Act enforcement began June 2025. WCAG 2.1 AA compliance is now a legal requirement for most public-facing web applications.
|
|
93
|
+
|
|
94
|
+
### Cross-Browser Testing Strategies
|
|
95
|
+
|
|
96
|
+
**Playwright's advantage**: Single API covers Chromium, Firefox, and WebKit (Safari engine). No extra tooling needed.
|
|
97
|
+
|
|
98
|
+
**Strategy**:
|
|
99
|
+
1. Run full suite against Chromium on every PR (fast feedback)
|
|
100
|
+
2. Run full suite against Firefox + WebKit on nightly builds or pre-release
|
|
101
|
+
3. Run critical user journeys across all three browsers on every deploy
|
|
102
|
+
4. Use `browserName` fixture to conditionally skip browser-specific tests
|
|
103
|
+
|
|
104
|
+
### Test Data Management
|
|
105
|
+
|
|
106
|
+
**Factories vs. Fixtures:**
|
|
107
|
+
- **Factories**: Functions that generate data on demand — flexible, unique, self-contained. Use for test-specific records.
|
|
108
|
+
- **Fixtures**: Predefined data loaded before tests. Use for shared reference data (countries, roles, feature flags).
|
|
109
|
+
|
|
110
|
+
**Best practices:**
|
|
111
|
+
- Keep factory files in the test directory, not in application source
|
|
112
|
+
- Clean up between tests: truncate tables or roll back transactions in `beforeEach`
|
|
113
|
+
- Combine both: fixtures for reference data stability, factories for test-specific flexibility
|
|
114
|
+
- Never share mutable test data between tests — leaked data is the most common source of flakiness
|
|
115
|
+
|
|
116
|
+
### Page Object Model vs. Component Object Pattern
|
|
117
|
+
|
|
118
|
+
**Page Object Model (POM):**
|
|
119
|
+
- Encapsulates locators and actions for a full page in a class
|
|
120
|
+
- When a locator changes, update in one place; test scripts read like user workflows
|
|
121
|
+
- Best for E2E tests with Playwright/Cypress
|
|
122
|
+
|
|
123
|
+
**Component Object Pattern:**
|
|
124
|
+
- Models reusable UI components (e.g., `DatePicker`, `DataTable`) as objects
|
|
125
|
+
- Nest component objects inside page objects for complex pages
|
|
126
|
+
- Better fit for component-heavy SPAs built with React/Vue/Angular
|
|
127
|
+
|
|
128
|
+
**Emerging alternative — Screenplay Pattern:**
|
|
129
|
+
- Models tests as "actors performing tasks" rather than "pages containing elements"
|
|
130
|
+
- Reduces coupling between tests and UI structure
|
|
131
|
+
- Overkill for most teams; consider when POM maintenance becomes burdensome
|
|
132
|
+
|
|
133
|
+
### Test Naming Conventions
|
|
134
|
+
|
|
135
|
+
Use the **Arrange-Act-Assert** structure reflected in the test name:
|
|
136
|
+
|
|
137
|
+
```
|
|
138
|
+
// Pattern: [unit] [action/scenario] [expected result]
|
|
139
|
+
test('LoginForm displays error when credentials are invalid')
|
|
140
|
+
test('CartTotal recalculates when item quantity changes')
|
|
141
|
+
test('SearchResults shows empty state when no matches found')
|
|
142
|
+
|
|
143
|
+
// For Playwright E2E:
|
|
144
|
+
test('user can complete checkout with saved payment method')
|
|
145
|
+
test('admin can bulk-delete users from management page')
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Avoid generic names like `test('it works')` or `test('should render')`. The name should tell you what broke without reading the test body.
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Anti-Patterns & Pitfalls
|
|
153
|
+
|
|
154
|
+
### 1. Testing Implementation Instead of Behavior
|
|
155
|
+
**Problem**: Tests coupled to internal state, CSS classes, or component structure break on every refactor even when user-facing behavior is unchanged. Maintenance cost skyrockets.
|
|
156
|
+
**Fix**: Query by role/label/text. Assert on what the user sees, not how the code works.
|
|
157
|
+
|
|
158
|
+
### 2. Over-Reliance on E2E Tests (Ice Cream Cone)
|
|
159
|
+
**Problem**: UI tests are 10-100x slower than unit tests, fragile against layout changes, and expensive to maintain. A suite of 500 E2E tests creates a 2-hour feedback loop.
|
|
160
|
+
**Fix**: Follow the Testing Trophy. Push validation down to integration and unit levels. Reserve E2E for critical user journeys only.
|
|
161
|
+
|
|
162
|
+
### 3. Using `sleep()` / `waitForTimeout()` Instead of Explicit Waits
|
|
163
|
+
**Problem**: Hard-coded delays are either too short (flaky) or too long (slow). They compound across hundreds of tests.
|
|
164
|
+
**Fix**: Use web-first assertions (`expect(locator).toBeVisible()`) and auto-waiting locators. Never use `page.waitForTimeout()` in production test code.
|
|
165
|
+
|
|
166
|
+
### 4. Shared Mutable State Between Tests
|
|
167
|
+
**Problem**: Test A creates data that Test B depends on. When Test A changes or runs out of order, Test B fails mysteriously. Parallelization becomes impossible.
|
|
168
|
+
**Fix**: Each test sets up its own data and tears it down. Use `beforeEach` for setup, never rely on test execution order.
|
|
169
|
+
|
|
170
|
+
### 5. Testing Third-Party Libraries
|
|
171
|
+
**Problem**: Writing tests that verify React Router navigates correctly or that axios sends HTTP requests wastes time and creates false confidence.
|
|
172
|
+
**Fix**: Test YOUR code's behavior, not the library's. Mock external boundaries; trust well-tested dependencies.
|
|
173
|
+
|
|
174
|
+
### 6. Snapshot Testing as a Primary Strategy
|
|
175
|
+
**Problem**: Large snapshots are never actually reviewed during code review. Developers reflexively run `--updateSnapshot` when they fail. They catch nothing and waste CI time.
|
|
176
|
+
**Fix**: Use snapshots sparingly for small, stable outputs (serialized config, error messages). For UI, use visual regression testing instead.
|
|
177
|
+
|
|
178
|
+
### 7. Ignoring Flaky Tests
|
|
179
|
+
**Problem**: Each flaky test erodes team trust in the suite. Engineers start ignoring failures, re-running CI "until it passes." Studies show 58% of CI failures come from flakiness, not real defects. Teams lose 6-8 hours/week to flaky test investigation.
|
|
180
|
+
**Fix**: Quarantine flaky tests immediately. Track flakiness rate. Fix root causes (timing, shared state, network dependencies). Never accept retries as a permanent solution.
|
|
181
|
+
|
|
182
|
+
### 8. Testing Too Late in Development
|
|
183
|
+
**Problem**: Defects found in a staging E2E run are 10-100x more expensive to fix than defects caught by a unit test during development.
|
|
184
|
+
**Fix**: Shift left. Write tests alongside feature code. Run fast tests locally before pushing. Gate PRs on test passage.
|
|
185
|
+
|
|
186
|
+
### 9. DRY Obsession in Test Code (Over-Abstraction)
|
|
187
|
+
**Problem**: Extracting every repeated value into shared helpers makes tests unreadable. A failing test requires navigating 5 files of helpers to understand what it does.
|
|
188
|
+
**Fix**: Tests should be DAMP (Descriptive And Meaningful Phrases), not DRY. Inline setup values. Repeat yourself if it makes the test self-documenting.
|
|
189
|
+
|
|
190
|
+
### 10. No Test Isolation in E2E (Reusing Browser Sessions)
|
|
191
|
+
**Problem**: Login once, run 50 tests in the same session. Cookie expiry, accumulated local storage, and DOM leaks cause random failures that are impossible to reproduce locally.
|
|
192
|
+
**Fix**: Use Playwright's `storageState` to save auth state, then load it in a fresh context per test. Each test gets a clean browser context.
|
|
193
|
+
|
|
194
|
+
### 11. Asserting on Element Counts or Exact Text
|
|
195
|
+
**Problem**: `expect(items).toHaveLength(5)` breaks whenever seed data changes. `expect(heading).toHaveText('Welcome, John!')` breaks for every locale.
|
|
196
|
+
**Fix**: Assert on presence/absence and patterns: `expect(items.first()).toBeVisible()`, `expect(heading).toContainText('Welcome')`.
|
|
197
|
+
|
|
198
|
+
### 12. No Accessibility Testing
|
|
199
|
+
**Problem**: Accessibility lawsuits are increasing. Automated tests can catch 30-40% of issues for near-zero effort, yet most teams skip them entirely.
|
|
200
|
+
**Fix**: Add `@axe-core/playwright` to your E2E suite. Run on every page navigation. Gate PRs on zero critical violations.
|
|
201
|
+
|
|
202
|
+
### 13. Mocking Too Much (or Too Little)
|
|
203
|
+
**Problem**: Over-mocking creates tests that pass even when the real integration is broken. Under-mocking creates tests that fail because an external API is down.
|
|
204
|
+
**Fix**: Mock at network boundaries (MSW for HTTP, Playwright route interception for E2E). Never mock the module under test. Never mock two layers deep.
|
|
205
|
+
|
|
206
|
+
### 14. Ignoring Test Performance
|
|
207
|
+
**Problem**: A 45-minute test suite means developers stop running tests. PRs queue up. Merge conflicts multiply.
|
|
208
|
+
**Fix**: Track suite execution time as a metric. Shard when serial time exceeds 10 minutes. Profile slow tests. Parallelize aggressively.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Testing Strategy
|
|
213
|
+
|
|
214
|
+
### Unit vs. Integration vs. E2E Balance
|
|
215
|
+
|
|
216
|
+
| Level | What to Test | Tools | Speed | Confidence |
|
|
217
|
+
|-------|-------------|-------|-------|------------|
|
|
218
|
+
| Static | Type errors, lint rules | TypeScript 5.x, ESLint 9.x | Instant | Low |
|
|
219
|
+
| Unit | Pure functions, utils, reducers, hooks with no side effects | Vitest 3.x+ | <1ms/test | Medium |
|
|
220
|
+
| Integration | Component trees, form flows, data fetching, state management | RTL + Vitest (or Vitest Browser Mode) | 5-50ms/test | High |
|
|
221
|
+
| E2E | Critical user journeys, cross-page flows, auth, payments | Playwright 1.x | 1-10s/test | Very High |
|
|
222
|
+
|
|
223
|
+
### What to Automate vs. What to Test Manually
|
|
224
|
+
|
|
225
|
+
**Automate:**
|
|
226
|
+
- Regression tests for existing functionality
|
|
227
|
+
- Smoke tests for critical user journeys
|
|
228
|
+
- Accessibility rule checks (axe-core)
|
|
229
|
+
- Visual regression baselines
|
|
230
|
+
- API contract validation
|
|
231
|
+
- Cross-browser critical paths
|
|
232
|
+
|
|
233
|
+
**Keep manual:**
|
|
234
|
+
- Exploratory testing for new features
|
|
235
|
+
- Usability evaluation
|
|
236
|
+
- Screen reader walkthroughs
|
|
237
|
+
- Complex multi-device workflows
|
|
238
|
+
- Edge cases discovered during exploratory sessions (automate after discovery)
|
|
239
|
+
|
|
240
|
+
### Flaky Test Prevention and Management
|
|
241
|
+
|
|
242
|
+
**Prevention:**
|
|
243
|
+
1. Use web-first assertions with auto-waiting (never `sleep`)
|
|
244
|
+
2. Isolate test data (no shared mutable state)
|
|
245
|
+
3. Mock external services at the network level (MSW / route interception)
|
|
246
|
+
4. Pin browser versions in CI (never use `latest` Docker tag)
|
|
247
|
+
5. Use deterministic clocks (`page.clock`) for time-dependent tests
|
|
248
|
+
6. Avoid CSS-selector-based locators (use role/label/text)
|
|
249
|
+
|
|
250
|
+
**Management:**
|
|
251
|
+
1. Track flakiness rate per test (most CI platforms report this)
|
|
252
|
+
2. Quarantine tests exceeding 5% flake rate
|
|
253
|
+
3. Set a team SLA: flaky tests must be fixed or deleted within 1 sprint
|
|
254
|
+
4. Run quarantined tests in a separate non-blocking pipeline
|
|
255
|
+
5. Review flakiness trends weekly in engineering standup
|
|
256
|
+
|
|
257
|
+
### Test Parallelization Strategies
|
|
258
|
+
|
|
259
|
+
**Playwright parallelization has two dimensions:**
|
|
260
|
+
|
|
261
|
+
1. **Workers** (single machine): Multiple OS processes, each with its own browser instance. Default: half of CPU cores. Increase to match available cores.
|
|
262
|
+
2. **Sharding** (multiple machines): Split suite across CI agents with `--shard=x/y`. Each shard gets an even distribution of tests when `fullyParallel: true`.
|
|
263
|
+
|
|
264
|
+
**Rule of thumb**: Use workers until a single machine is saturated (~6-8 workers). When suite still takes >10-15 minutes, add sharding across 2-4 CI agents. A suite that takes 20 minutes with 8 workers on one machine can drop to ~5 minutes with 4 shards.
|
|
265
|
+
|
|
266
|
+
**Advanced**: Orchestration services (Currents, Sorry Cypress) replace static sharding with a dynamic task queue — CI runners pull tests in real time, optimally balancing load across machines.
|
|
267
|
+
|
|
268
|
+
### CI/CD Integration Patterns
|
|
269
|
+
|
|
270
|
+
```yaml
|
|
271
|
+
# GitHub Actions — Playwright sharded across 4 machines
|
|
272
|
+
jobs:
|
|
273
|
+
test:
|
|
274
|
+
strategy:
|
|
275
|
+
matrix:
|
|
276
|
+
shard: [1/4, 2/4, 3/4, 4/4]
|
|
277
|
+
steps:
|
|
278
|
+
- uses: actions/checkout@v4
|
|
279
|
+
- uses: actions/setup-node@v4
|
|
280
|
+
- run: npm ci
|
|
281
|
+
- run: npx playwright install --with-deps
|
|
282
|
+
- run: npx playwright test --shard=${{ matrix.shard }}
|
|
283
|
+
- uses: actions/upload-artifact@v4
|
|
284
|
+
if: ${{ !cancelled() }}
|
|
285
|
+
with:
|
|
286
|
+
name: test-results-${{ matrix.shard }}
|
|
287
|
+
path: test-results/
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
**Pipeline stages:**
|
|
291
|
+
1. **Lint + Type Check** (30s) — gate on zero errors
|
|
292
|
+
2. **Unit + Integration** (1-3min) — Vitest with coverage
|
|
293
|
+
3. **E2E Smoke** (2-5min) — critical journeys only, on every PR
|
|
294
|
+
4. **E2E Full Suite** (sharded, 5-10min) — on merge to main
|
|
295
|
+
5. **Visual Regression** (2-5min) — Chromatic/Percy on every PR
|
|
296
|
+
6. **Accessibility Audit** (1-2min) — axe-core on key pages
|
|
297
|
+
|
|
298
|
+
### Coverage Metrics and What They Actually Mean
|
|
299
|
+
|
|
300
|
+
**Types of coverage:**
|
|
301
|
+
- **Statement (C1)**: Which lines executed. Easy to game — a function can run without meaningful assertions.
|
|
302
|
+
- **Branch (C2)**: Which decision paths executed. More meaningful — exposes untested `if/else`, `switch`, and ternary branches.
|
|
303
|
+
- **Function**: Which functions were called. Coarsest metric.
|
|
304
|
+
|
|
305
|
+
**What coverage does NOT tell you:**
|
|
306
|
+
- Whether assertions are meaningful (a test with no `expect()` still generates coverage)
|
|
307
|
+
- Whether edge cases are handled
|
|
308
|
+
- Whether the UI looks correct
|
|
309
|
+
|
|
310
|
+
**Recommended targets** (Google's internal guidance):
|
|
311
|
+
- 60% = acceptable minimum
|
|
312
|
+
- 75% = commendable
|
|
313
|
+
- 90% = exemplary (diminishing returns beyond this)
|
|
314
|
+
|
|
315
|
+
**Practical approach**: Enforce 80% branch coverage as a PR gate. Focus coverage efforts on business logic, not UI glue code. Use coverage reports to find *untested areas*, not as a quality score.
|
|
316
|
+
|
|
317
|
+
---
|
|
318
|
+
|
|
319
|
+
## Performance Considerations
|
|
320
|
+
|
|
321
|
+
### Test Suite Execution Speed Optimization
|
|
322
|
+
|
|
323
|
+
1. **Use Vitest over Jest** for unit/integration tests — 2-10x faster due to native ESM, Vite's transform pipeline, and instant watch mode
|
|
324
|
+
2. **Enable `fullyParallel: true`** in Playwright config — distributes individual tests across workers, not just files
|
|
325
|
+
3. **Reuse authentication state** via `storageState` instead of logging in per test (saves 2-5s per test)
|
|
326
|
+
4. **Minimize `beforeEach` overhead** — setup only what the current test needs
|
|
327
|
+
5. **Use `test.describe.configure({ mode: 'parallel' })** for independent test groups within a file
|
|
328
|
+
6. **Profile slow tests**: Playwright's `--reporter=json` output includes duration per test; sort and optimize the top 10%
|
|
329
|
+
|
|
330
|
+
### Parallel Test Execution
|
|
331
|
+
|
|
332
|
+
| Approach | When to Use | Speedup |
|
|
333
|
+
|----------|-------------|---------|
|
|
334
|
+
| Vitest thread pool | Unit/integration tests | 3-8x vs. serial |
|
|
335
|
+
| Playwright workers (single machine) | E2E on dev/CI machine | 2-6x (depends on cores) |
|
|
336
|
+
| Playwright sharding (multi-machine) | Large E2E suites in CI | Linear with shard count |
|
|
337
|
+
| Orchestrated sharding (Currents) | Very large suites (500+) | Optimal load distribution |
|
|
338
|
+
|
|
339
|
+
### Test Environment Management
|
|
340
|
+
|
|
341
|
+
- **Local dev**: Use Vitest in watch mode for unit/integration. Run targeted Playwright tests with `--grep`.
|
|
342
|
+
- **CI**: Use Playwright Docker image (`mcr.microsoft.com/playwright:v1.49.0-noble`) — all browsers + deps pre-installed. Pin to specific version tag.
|
|
343
|
+
- **Preview deployments**: Run E2E against Vercel/Netlify preview URLs. Pass URL as environment variable.
|
|
344
|
+
- **Staging**: Run full suite + security scans before production deploy.
|
|
345
|
+
|
|
346
|
+
### Browser Resource Consumption
|
|
347
|
+
|
|
348
|
+
- Each Playwright worker spawns a browser process (~150-300MB RAM per Chromium instance)
|
|
349
|
+
- Limit workers to available RAM: `workers: Math.min(os.cpus().length, Math.floor(totalRAM / 400))`
|
|
350
|
+
- In CI with 8GB RAM, cap at 4-6 workers for Chromium
|
|
351
|
+
- WebKit and Firefox are generally lighter than Chromium
|
|
352
|
+
|
|
353
|
+
### CI Pipeline Optimization
|
|
354
|
+
|
|
355
|
+
1. **Cache `node_modules` and Playwright browsers** — browser downloads are 200-400MB
|
|
356
|
+
2. **Use the Docker image** to skip `playwright install` entirely
|
|
357
|
+
3. **Run unit tests and E2E in parallel jobs** (not sequentially)
|
|
358
|
+
4. **Upload artifacts only on failure** (`if: failure()`) to save storage
|
|
359
|
+
5. **Use `--retries=1`** in CI to tolerate transient infrastructure issues, but track retry rate
|
|
360
|
+
6. **Merge shard results** with `npx playwright merge-reports` for a unified HTML report
|
|
361
|
+
|
|
362
|
+
---
|
|
363
|
+
|
|
364
|
+
## Security Considerations
|
|
365
|
+
|
|
366
|
+
### Security Testing in Web Applications
|
|
367
|
+
|
|
368
|
+
**OWASP ZAP integration approach:**
|
|
369
|
+
|
|
370
|
+
| Scan Type | Trigger | Duration | Scope |
|
|
371
|
+
|-----------|---------|----------|-------|
|
|
372
|
+
| Baseline scan | Every PR | 2-5 min | Common vulnerabilities (XSS, headers, cookies) |
|
|
373
|
+
| Full active scan | Nightly / pre-release | 30-60 min | Full OWASP Top 10 probing |
|
|
374
|
+
| API scan | On API changes | 5-15 min | REST/GraphQL endpoint security |
|
|
375
|
+
|
|
376
|
+
**CI integration**: Use the official Docker image (`ghcr.io/zaproxy/zaproxy:stable`). Run baseline scan in PR pipeline; reserve active scan for nightly builds. Teams using ZAP baseline scans on every PR reduced penetration test findings by ~35% per quarter.
|
|
377
|
+
|
|
378
|
+
**Playwright-native security checks:**
|
|
379
|
+
- Verify Content-Security-Policy headers on every page load
|
|
380
|
+
- Test that authentication-required pages redirect when unauthenticated
|
|
381
|
+
- Verify CORS headers on API responses
|
|
382
|
+
- Test rate limiting on login/signup endpoints
|
|
383
|
+
|
|
384
|
+
### Authentication in Test Environments
|
|
385
|
+
|
|
386
|
+
- Use `storageState` files to persist authenticated sessions — never hard-code credentials in test files
|
|
387
|
+
- Create dedicated test user accounts with known credentials
|
|
388
|
+
- Rotate test credentials on a schedule (treat them like any other secret)
|
|
389
|
+
- For OAuth/SSO: mock the identity provider in test environments or use a test-only bypass endpoint (never in production)
|
|
390
|
+
|
|
391
|
+
### Test Data Privacy
|
|
392
|
+
|
|
393
|
+
- Never use real production data in tests — synthesize realistic data with factories (Faker.js, @faker-js/faker 9.x)
|
|
394
|
+
- Mask PII in test reports and CI logs
|
|
395
|
+
- Ensure test databases are ephemeral — create and destroy per CI run
|
|
396
|
+
- GDPR/CCPA apply to test data if it contains real user information
|
|
397
|
+
|
|
398
|
+
### Secrets in Test Configurations
|
|
399
|
+
|
|
400
|
+
- Store test credentials in CI secrets (GitHub Actions secrets, GitLab CI variables), never in `.env` files committed to Git
|
|
401
|
+
- Use `.env.test.local` (gitignored) for local development
|
|
402
|
+
- Audit `playwright.config.ts` and test fixtures for accidentally committed tokens
|
|
403
|
+
- Rotate secrets after any suspected exposure
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
## Integration Patterns
|
|
408
|
+
|
|
409
|
+
### API Mocking
|
|
410
|
+
|
|
411
|
+
**MSW (Mock Service Worker) 2.x** — industry standard for unit/integration tests:
|
|
412
|
+
|
|
413
|
+
```typescript
|
|
414
|
+
// handlers.ts — shared across unit, integration, and E2E
|
|
415
|
+
import { http, HttpResponse } from 'msw';
|
|
416
|
+
|
|
417
|
+
export const handlers = [
|
|
418
|
+
http.get('/api/users/:id', ({ params }) => {
|
|
419
|
+
return HttpResponse.json({
|
|
420
|
+
id: params.id,
|
|
421
|
+
name: 'Test User',
|
|
422
|
+
email: 'test@example.com',
|
|
423
|
+
});
|
|
424
|
+
}),
|
|
425
|
+
http.post('/api/orders', async ({ request }) => {
|
|
426
|
+
const body = await request.json();
|
|
427
|
+
return HttpResponse.json({ id: 'order-123', ...body }, { status: 201 });
|
|
428
|
+
}),
|
|
429
|
+
];
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**Key MSW patterns:**
|
|
433
|
+
- Share handlers across unit, integration, and E2E tests — single source of truth for API behavior
|
|
434
|
+
- Split handlers into feature-specific files for large applications (avoid a single 1000-line handlers file)
|
|
435
|
+
- Use `server.use()` in individual tests to override handlers for error/edge cases
|
|
436
|
+
- Three-step lifecycle: `server.listen()` before all, `server.resetHandlers()` between tests, `server.close()` after all
|
|
437
|
+
|
|
438
|
+
**Playwright route interception** — for E2E tests:
|
|
439
|
+
|
|
440
|
+
```typescript
|
|
441
|
+
await page.route('**/api/users/*', (route) =>
|
|
442
|
+
route.fulfill({
|
|
443
|
+
status: 200,
|
|
444
|
+
contentType: 'application/json',
|
|
445
|
+
body: JSON.stringify({ id: '1', name: 'Mocked User' }),
|
|
446
|
+
})
|
|
447
|
+
);
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
Best for: intercepting slow/flaky external APIs in E2E without modifying application code.
|
|
451
|
+
|
|
452
|
+
### Database Seeding for Tests
|
|
453
|
+
|
|
454
|
+
- Use transaction rollback between tests (wrap each test in a transaction, roll back in `afterEach`)
|
|
455
|
+
- Seed reference data once before suite; create test-specific records with factories
|
|
456
|
+
- For Playwright E2E: expose a `/test/seed` endpoint (test environments only, guarded by env variable) or use API calls in `beforeEach`
|
|
457
|
+
- Never rely on database auto-increment IDs in assertions — use unique identifiers from factories
|
|
458
|
+
|
|
459
|
+
### Test Reporting
|
|
460
|
+
|
|
461
|
+
**Playwright built-in reporters:**
|
|
462
|
+
- `html` — default, self-contained HTML report with filter/search
|
|
463
|
+
- `json` — machine-readable, good for custom dashboards
|
|
464
|
+
- `blob` — for merging sharded results: generate blobs per shard, merge with `npx playwright merge-reports`
|
|
465
|
+
|
|
466
|
+
**Allure Report** — richest open-source option:
|
|
467
|
+
- Interactive dashboards, test timelines, trend analysis, categorization by severity
|
|
468
|
+
- Integrates with GitHub Actions (publish to GitHub Pages) and Azure DevOps
|
|
469
|
+
- Install: `npm i -D allure-playwright`; configure: `reporter: [['allure-playwright']]`
|
|
470
|
+
|
|
471
|
+
**Monitoring test health metrics:**
|
|
472
|
+
- Track: total test count, pass rate, flake rate, suite duration, coverage delta per PR
|
|
473
|
+
- Alert on: flake rate >5%, suite duration increase >20%, coverage drop >2%
|
|
474
|
+
- Dashboard: Grafana + Prometheus, Datadog CI Visibility, or Currents dashboard
|
|
475
|
+
|
|
476
|
+
---
|
|
477
|
+
|
|
478
|
+
## DevOps & Deployment
|
|
479
|
+
|
|
480
|
+
### Test Infrastructure
|
|
481
|
+
|
|
482
|
+
**Playwright in Docker:**
|
|
483
|
+
```dockerfile
|
|
484
|
+
FROM mcr.microsoft.com/playwright:v1.49.0-noble
|
|
485
|
+
WORKDIR /app
|
|
486
|
+
COPY package*.json ./
|
|
487
|
+
RUN npm ci
|
|
488
|
+
COPY . .
|
|
489
|
+
CMD ["npx", "playwright", "test"]
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
Pin to a specific version tag — never use `latest`. The official image ships with all browsers and system dependencies.
|
|
493
|
+
|
|
494
|
+
**Selenium Grid** (legacy/cross-org):
|
|
495
|
+
- Use only when you need to test on real browser versions not supported by Playwright (e.g., IE11 legacy support, specific mobile browsers)
|
|
496
|
+
- For modern web apps, Playwright has replaced Selenium Grid for most teams
|
|
497
|
+
|
|
498
|
+
### CI Configuration Examples
|
|
499
|
+
|
|
500
|
+
**GitHub Actions (recommended for most teams):**
|
|
501
|
+
```yaml
|
|
502
|
+
name: Tests
|
|
503
|
+
on: [push, pull_request]
|
|
504
|
+
|
|
505
|
+
jobs:
|
|
506
|
+
unit-integration:
|
|
507
|
+
runs-on: ubuntu-latest
|
|
508
|
+
steps:
|
|
509
|
+
- uses: actions/checkout@v4
|
|
510
|
+
- uses: actions/setup-node@v4
|
|
511
|
+
with: { node-version: 22, cache: npm }
|
|
512
|
+
- run: npm ci
|
|
513
|
+
- run: npx vitest run --coverage
|
|
514
|
+
- uses: actions/upload-artifact@v4
|
|
515
|
+
with:
|
|
516
|
+
name: coverage
|
|
517
|
+
path: coverage/
|
|
518
|
+
|
|
519
|
+
e2e:
|
|
520
|
+
runs-on: ubuntu-latest
|
|
521
|
+
container:
|
|
522
|
+
image: mcr.microsoft.com/playwright:v1.49.0-noble
|
|
523
|
+
strategy:
|
|
524
|
+
matrix:
|
|
525
|
+
shard: [1/3, 2/3, 3/3]
|
|
526
|
+
steps:
|
|
527
|
+
- uses: actions/checkout@v4
|
|
528
|
+
- uses: actions/setup-node@v4
|
|
529
|
+
with: { node-version: 22, cache: npm }
|
|
530
|
+
- run: npm ci
|
|
531
|
+
- run: npx playwright test --shard=${{ matrix.shard }}
|
|
532
|
+
- uses: actions/upload-artifact@v4
|
|
533
|
+
if: ${{ !cancelled() }}
|
|
534
|
+
with:
|
|
535
|
+
name: results-${{ strategy.job-index }}
|
|
536
|
+
path: |
|
|
537
|
+
test-results/
|
|
538
|
+
playwright-report/
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
**GitLab CI:**
|
|
542
|
+
```yaml
|
|
543
|
+
e2e:
|
|
544
|
+
image: mcr.microsoft.com/playwright:v1.49.0-noble
|
|
545
|
+
parallel: 3
|
|
546
|
+
script:
|
|
547
|
+
- npm ci
|
|
548
|
+
- npx playwright test --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL
|
|
549
|
+
artifacts:
|
|
550
|
+
when: always
|
|
551
|
+
paths: [test-results/, playwright-report/]
|
|
552
|
+
expire_in: 7 days
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
### Test Artifact Management
|
|
556
|
+
|
|
557
|
+
| Artifact | When to Capture | Retention |
|
|
558
|
+
|----------|----------------|-----------|
|
|
559
|
+
| Screenshots | On failure | 7-30 days |
|
|
560
|
+
| Videos | On failure (or first retry) | 7 days |
|
|
561
|
+
| Traces | On first retry | 7 days |
|
|
562
|
+
| HTML report | Always | 30 days |
|
|
563
|
+
| Coverage report | Always | 90 days |
|
|
564
|
+
| Allure results | Always | 30 days |
|
|
565
|
+
|
|
566
|
+
**Best practice**: Capture traces on first retry (`trace: 'on-first-retry'`) — they contain DOM snapshots, network logs, and console output. Far more useful than screenshots alone.
|
|
567
|
+
|
|
568
|
+
### Pre-Deployment Test Gates
|
|
569
|
+
|
|
570
|
+
```
|
|
571
|
+
PR Merge Gate:
|
|
572
|
+
- Lint + Type Check → must pass
|
|
573
|
+
- Unit + Integration → must pass, coverage >= 80%
|
|
574
|
+
- E2E Smoke (5 tests) → must pass
|
|
575
|
+
- Accessibility (axe) → zero critical violations
|
|
576
|
+
- Visual Regression → approved or no changes
|
|
577
|
+
|
|
578
|
+
Pre-Production Gate:
|
|
579
|
+
- Full E2E suite → must pass
|
|
580
|
+
- Security baseline scan → zero high-severity findings
|
|
581
|
+
- Performance budget → LCP < 2.5s, CLS < 0.1
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
### Production Monitoring vs. Testing
|
|
585
|
+
|
|
586
|
+
Testing verifies behavior *before* deployment. Production monitoring catches issues *after* deployment.
|
|
587
|
+
|
|
588
|
+
**Complement tests with:**
|
|
589
|
+
- Synthetic monitoring (Datadog Synthetic, Checkly) — run critical E2E flows against production on a schedule
|
|
590
|
+
- Real User Monitoring (RUM) — track Core Web Vitals, JS errors, API failures from real users
|
|
591
|
+
- Error tracking (Sentry, Datadog) — capture and triage runtime exceptions
|
|
592
|
+
|
|
593
|
+
**Key difference**: A passing test suite guarantees the *tested code paths* work in *test conditions*. Production monitoring catches environment-specific failures, third-party outages, and untested edge cases.
|
|
594
|
+
|
|
595
|
+
---
|
|
596
|
+
|
|
597
|
+
## Decision Trees
|
|
598
|
+
|
|
599
|
+
### Decision Tree 1: Playwright vs. Cypress vs. WebdriverIO
|
|
600
|
+
|
|
601
|
+
```
|
|
602
|
+
Need to test in WebKit (Safari engine)?
|
|
603
|
+
├── Yes → Playwright (only framework with native WebKit support)
|
|
604
|
+
└── No
|
|
605
|
+
├── Need multi-tab or multi-origin testing?
|
|
606
|
+
│ ├── Yes → Playwright (Cypress cannot handle multi-tab)
|
|
607
|
+
│ └── No
|
|
608
|
+
│ ├── Need native mobile testing (Appium)?
|
|
609
|
+
│ │ ├── Yes → WebdriverIO (best Appium integration)
|
|
610
|
+
│ │ └── No
|
|
611
|
+
│ │ ├── Team prefers simplest DX, small-medium project?
|
|
612
|
+
│ │ │ ├── Yes → Cypress (best time-travel debugger, easiest setup)
|
|
613
|
+
│ │ │ └── No
|
|
614
|
+
│ │ │ ├── Need maximum CI speed + parallelization?
|
|
615
|
+
│ │ │ │ ├── Yes → Playwright (native sharding, ~23% faster than Cypress)
|
|
616
|
+
│ │ │ │ └── No → Either Playwright or Cypress; choose by team familiarity
|
|
617
|
+
│ │ └──
|
|
618
|
+
│ └──
|
|
619
|
+
└──
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
**2026 consensus**: Playwright is the default choice for new projects. Cypress remains excellent for teams already invested in it. WebdriverIO fills the mobile testing niche.
|
|
623
|
+
|
|
624
|
+
### Decision Tree 2: Unit vs. Integration vs. E2E
|
|
625
|
+
|
|
626
|
+
```
|
|
627
|
+
Is it pure logic with no UI or I/O?
|
|
628
|
+
├── Yes → Unit test (Vitest)
|
|
629
|
+
│ Examples: utility functions, reducers, validators, formatters
|
|
630
|
+
└── No
|
|
631
|
+
├── Does it involve a single component or small component tree?
|
|
632
|
+
│ ├── Yes → Integration test (RTL + Vitest)
|
|
633
|
+
│ │ Examples: form validation, component interaction, data display
|
|
634
|
+
│ └── No
|
|
635
|
+
│ ├── Does it cross page boundaries or involve navigation?
|
|
636
|
+
│ │ ├── Yes → E2E test (Playwright)
|
|
637
|
+
│ │ │ Examples: checkout flow, auth flow, multi-page wizard
|
|
638
|
+
│ │ └── No
|
|
639
|
+
│ │ ├── Does it involve multiple services or real network?
|
|
640
|
+
│ │ │ ├── Yes → E2E test (Playwright)
|
|
641
|
+
│ │ │ └── No → Integration test (RTL + Vitest with MSW)
|
|
642
|
+
│ │ └──
|
|
643
|
+
│ └──
|
|
644
|
+
└──
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
### Decision Tree 3: Visual Regression — Screenshot-Based vs. DOM-Based
|
|
648
|
+
|
|
649
|
+
```
|
|
650
|
+
Using Storybook for component development?
|
|
651
|
+
├── Yes → Chromatic (DOM-aware, Storybook-native, component-level diffs)
|
|
652
|
+
└── No
|
|
653
|
+
├── Need cross-browser visual comparison?
|
|
654
|
+
│ ├── Yes → Percy (renders in multiple browsers, AI-powered diff)
|
|
655
|
+
│ └── No
|
|
656
|
+
│ ├── Team size < 10 and budget-constrained?
|
|
657
|
+
│ │ ├── Yes → Playwright toHaveScreenshot() (free, pixel-level, baselines in Git)
|
|
658
|
+
│ │ └── No
|
|
659
|
+
│ │ ├── High volume of visual changes needing review?
|
|
660
|
+
│ │ │ ├── Yes → Percy (AI filters noise, team review workflow)
|
|
661
|
+
│ │ │ └── No → Playwright toHaveScreenshot() (sufficient for most teams)
|
|
662
|
+
│ │ └──
|
|
663
|
+
│ └──
|
|
664
|
+
└──
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
---
|
|
668
|
+
|
|
669
|
+
## Code Examples
|
|
670
|
+
|
|
671
|
+
### Example 1: Playwright E2E Test with Auth State Reuse
|
|
672
|
+
|
|
673
|
+
```typescript
|
|
674
|
+
// auth.setup.ts — runs once, saves state for all tests
|
|
675
|
+
import { test as setup, expect } from '@playwright/test';
|
|
676
|
+
|
|
677
|
+
setup('authenticate', async ({ page }) => {
|
|
678
|
+
await page.goto('/login');
|
|
679
|
+
await page.getByLabel('Email').fill('test@example.com');
|
|
680
|
+
await page.getByLabel('Password').fill(process.env.TEST_PASSWORD!);
|
|
681
|
+
await page.getByRole('button', { name: 'Sign in' }).click();
|
|
682
|
+
await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible();
|
|
683
|
+
await page.context().storageState({ path: '.auth/user.json' });
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
// dashboard.spec.ts — uses saved auth state
|
|
687
|
+
import { test, expect } from '@playwright/test';
|
|
688
|
+
|
|
689
|
+
test.use({ storageState: '.auth/user.json' });
|
|
690
|
+
|
|
691
|
+
test('user sees recent activity on dashboard', async ({ page }) => {
|
|
692
|
+
await page.goto('/dashboard');
|
|
693
|
+
const activity = page.getByRole('list', { name: 'Recent activity' });
|
|
694
|
+
await expect(activity.getByRole('listitem')).toHaveCount({ minimum: 1 });
|
|
695
|
+
await expect(activity.getByRole('listitem').first()).toContainText(/ago$/);
|
|
696
|
+
});
|
|
697
|
+
```
|
|
698
|
+
|
|
699
|
+
### Example 2: React Testing Library Integration Test with MSW
|
|
700
|
+
|
|
701
|
+
```typescript
|
|
702
|
+
// OrderForm.test.tsx
|
|
703
|
+
import { render, screen, waitFor } from '@testing-library/react';
|
|
704
|
+
import userEvent from '@testing-library/user-event';
|
|
705
|
+
import { http, HttpResponse } from 'msw';
|
|
706
|
+
import { setupServer } from 'msw/node';
|
|
707
|
+
import { OrderForm } from './OrderForm';
|
|
708
|
+
|
|
709
|
+
const server = setupServer(
|
|
710
|
+
http.post('/api/orders', () =>
|
|
711
|
+
HttpResponse.json({ id: 'order-456', status: 'confirmed' }, { status: 201 })
|
|
712
|
+
)
|
|
713
|
+
);
|
|
714
|
+
|
|
715
|
+
beforeAll(() => server.listen());
|
|
716
|
+
afterEach(() => server.resetHandlers());
|
|
717
|
+
afterAll(() => server.close());
|
|
718
|
+
|
|
719
|
+
test('OrderForm submits and displays confirmation', async () => {
|
|
720
|
+
const user = userEvent.setup();
|
|
721
|
+
render(<OrderForm />);
|
|
722
|
+
|
|
723
|
+
await user.type(screen.getByLabelText('Item name'), 'Widget Pro');
|
|
724
|
+
await user.type(screen.getByLabelText('Quantity'), '3');
|
|
725
|
+
await user.click(screen.getByRole('button', { name: 'Place Order' }));
|
|
726
|
+
|
|
727
|
+
await waitFor(() => {
|
|
728
|
+
expect(screen.getByRole('alert')).toHaveTextContent('Order confirmed');
|
|
729
|
+
});
|
|
730
|
+
expect(screen.getByText('order-456')).toBeInTheDocument();
|
|
731
|
+
});
|
|
732
|
+
|
|
733
|
+
test('OrderForm displays error on server failure', async () => {
|
|
734
|
+
server.use(
|
|
735
|
+
http.post('/api/orders', () => HttpResponse.json({ error: 'Out of stock' }, { status: 422 }))
|
|
736
|
+
);
|
|
737
|
+
|
|
738
|
+
const user = userEvent.setup();
|
|
739
|
+
render(<OrderForm />);
|
|
740
|
+
|
|
741
|
+
await user.type(screen.getByLabelText('Item name'), 'Widget Pro');
|
|
742
|
+
await user.click(screen.getByRole('button', { name: 'Place Order' }));
|
|
743
|
+
|
|
744
|
+
await waitFor(() => {
|
|
745
|
+
expect(screen.getByRole('alert')).toHaveTextContent('Out of stock');
|
|
746
|
+
});
|
|
747
|
+
});
|
|
748
|
+
```
|
|
749
|
+
|
|
750
|
+
### Example 3: Visual Regression Test with Playwright
|
|
751
|
+
|
|
752
|
+
```typescript
|
|
753
|
+
// visual.spec.ts
|
|
754
|
+
import { test, expect } from '@playwright/test';
|
|
755
|
+
|
|
756
|
+
test('homepage matches visual baseline', async ({ page }) => {
|
|
757
|
+
await page.goto('/');
|
|
758
|
+
// Wait for dynamic content to stabilize
|
|
759
|
+
await expect(page.getByRole('heading', { name: 'Welcome' })).toBeVisible();
|
|
760
|
+
|
|
761
|
+
await expect(page).toHaveScreenshot('homepage.png', {
|
|
762
|
+
maxDiffPixelRatio: 0.01, // Allow 1% pixel diff (anti-aliasing tolerance)
|
|
763
|
+
mask: [page.locator('.timestamp'), page.locator('.avatar')], // Mask dynamic elements
|
|
764
|
+
fullPage: true,
|
|
765
|
+
});
|
|
766
|
+
});
|
|
767
|
+
|
|
768
|
+
test('dark mode matches visual baseline', async ({ page }) => {
|
|
769
|
+
await page.emulateMedia({ colorScheme: 'dark' });
|
|
770
|
+
await page.goto('/');
|
|
771
|
+
await expect(page).toHaveScreenshot('homepage-dark.png', {
|
|
772
|
+
maxDiffPixelRatio: 0.01,
|
|
773
|
+
});
|
|
774
|
+
});
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
### Example 4: Accessibility Test with axe-core + Playwright
|
|
778
|
+
|
|
779
|
+
```typescript
|
|
780
|
+
// accessibility.spec.ts
|
|
781
|
+
import { test, expect } from '@playwright/test';
|
|
782
|
+
import AxeBuilder from '@axe-core/playwright';
|
|
783
|
+
|
|
784
|
+
const criticalPages = ['/', '/login', '/dashboard', '/settings', '/checkout'];
|
|
785
|
+
|
|
786
|
+
for (const path of criticalPages) {
|
|
787
|
+
test(`${path} has no accessibility violations`, async ({ page }) => {
|
|
788
|
+
await page.goto(path);
|
|
789
|
+
|
|
790
|
+
const results = await new AxeBuilder({ page })
|
|
791
|
+
.withTags(['wcag2a', 'wcag2aa', 'wcag22aa'])
|
|
792
|
+
.exclude('.third-party-widget') // Exclude elements you don't control
|
|
793
|
+
.analyze();
|
|
794
|
+
|
|
795
|
+
// Detailed failure output
|
|
796
|
+
const violations = results.violations.map((v) => ({
|
|
797
|
+
rule: v.id,
|
|
798
|
+
impact: v.impact,
|
|
799
|
+
description: v.description,
|
|
800
|
+
nodes: v.nodes.length,
|
|
801
|
+
}));
|
|
802
|
+
|
|
803
|
+
expect(violations, `Accessibility violations on ${path}`).toEqual([]);
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
```
|
|
807
|
+
|
|
808
|
+
### Example 5: Vitest Component Test with Browser Mode
|
|
809
|
+
|
|
810
|
+
```typescript
|
|
811
|
+
// SearchBar.test.tsx — Vitest 3.x+ Browser Mode
|
|
812
|
+
import { render, screen } from '@testing-library/react';
|
|
813
|
+
import userEvent from '@testing-library/user-event';
|
|
814
|
+
import { describe, it, expect, vi } from 'vitest';
|
|
815
|
+
import { SearchBar } from './SearchBar';
|
|
816
|
+
|
|
817
|
+
describe('SearchBar', () => {
|
|
818
|
+
it('calls onSearch with debounced input value', async () => {
|
|
819
|
+
const onSearch = vi.fn();
|
|
820
|
+
const user = userEvent.setup();
|
|
821
|
+
render(<SearchBar onSearch={onSearch} debounceMs={100} />);
|
|
822
|
+
|
|
823
|
+
const input = screen.getByRole('searchbox', { name: 'Search' });
|
|
824
|
+
await user.type(input, 'playwright');
|
|
825
|
+
|
|
826
|
+
// Wait for debounce
|
|
827
|
+
await vi.waitFor(() => {
|
|
828
|
+
expect(onSearch).toHaveBeenCalledWith('playwright');
|
|
829
|
+
});
|
|
830
|
+
// Should not fire for every keystroke
|
|
831
|
+
expect(onSearch).toHaveBeenCalledTimes(1);
|
|
832
|
+
});
|
|
833
|
+
|
|
834
|
+
it('clears input when clear button is clicked', async () => {
|
|
835
|
+
const user = userEvent.setup();
|
|
836
|
+
render(<SearchBar onSearch={vi.fn()} />);
|
|
837
|
+
|
|
838
|
+
const input = screen.getByRole('searchbox');
|
|
839
|
+
await user.type(input, 'test query');
|
|
840
|
+
await user.click(screen.getByRole('button', { name: 'Clear search' }));
|
|
841
|
+
|
|
842
|
+
expect(input).toHaveValue('');
|
|
843
|
+
});
|
|
844
|
+
});
|
|
845
|
+
```
|
|
846
|
+
|
|
847
|
+
---
|
|
848
|
+
|
|
849
|
+
*Researched: 2026-03-07 | Sources: [Playwright Best Practices](https://playwright.dev/docs/best-practices), [BrowserStack Playwright Guide](https://www.browserstack.com/guide/playwright-best-practices), [Kent C. Dodds — Testing Trophy](https://kentcdodds.com/blog/the-testing-trophy-and-testing-classifications), [Kent C. Dodds — Write Tests](https://kentcdodds.com/blog/write-tests), [Testing Library Docs](https://testing-library.com/docs/react-testing-library/intro/), [Vitest 4.0 Browser Mode (InfoQ)](https://www.infoq.com/news/2025/12/vitest-4-browser-mode/), [Codepipes — Software Testing Anti-patterns](https://blog.codepipes.com/testing/software-testing-antipatterns.html), [TestDevLab — Anti-patterns](https://www.testdevlab.com/blog/5-test-automation-anti-patterns-and-how-to-avoid-them), [Playwright vs Cypress vs Selenium (TestDino)](https://testdino.com/blog/selenium-vs-cypress-vs-playwright/), [Percy AI Review Agent (Bug0)](https://bug0.com/knowledge-base/percy-visual-regression-testing), [Chromatic Visual Testing](https://www.chromatic.com/blog/how-to-visual-test-ui-using-playwright/), [Playwright Accessibility Testing](https://playwright.dev/docs/accessibility-testing), [Deque axe-core](https://www.deque.com/axe/axe-core/), [MSW Docs](https://mswjs.io/docs/), [Playwright CI Setup](https://playwright.dev/docs/ci), [Allure Playwright](https://allurereport.org/docs/playwright/), [OWASP ZAP Integration (MoldStud)](https://moldstud.com/articles/p-enhance-automated-qa-testing-for-web-applications-with-owasp-zap), [Playwright Sharding](https://playwright.dev/docs/test-sharding), [Currents — Sharding vs Workers](https://currents.dev/posts/optimizing-test-runtime-playwright-sharding-vs-workers), [Google Coverage Guidelines (Qt)](https://www.qt.io/quality-assurance/blog/is-70-80-90-or-100-code-coverage-good-enough), [ACCELQ — Flaky Tests 2026](https://www.accelq.com/blog/flaky-tests/), [web.dev — Testing Strategies](https://web.dev/articles/ta-strategies), [Gorilla Logic — POM vs Component Object](https://gorillalogic.com/test-automation-frameworks-page-object-model-vs-page-component-object-model/), [Code With Seb — Accessibility 2026](https://www.codewithseb.com/blog/web-accessibility-2026-eaa-ada-wcag-guide)*
|