@salesforce/b2c-dx-mcp 3.2.1 → 3.3.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/bin/run.js +5 -9
- package/content/guidance/b2c/b2c-hooks/references/ORDER-HOOK-LIFECYCLE.md +1 -1
- package/content/guidance/b2c/b2c-onboarding/SKILL.md +4 -4
- package/content/guidance/b2c/b2c-ordering/SKILL.md +2 -2
- package/content/guidance/b2c/b2c-querying-data/SKILL.md +2 -2
- package/content/guidance/b2c/b2c-scapi-admin/SKILL.md +3 -3
- package/content/guidance/b2c/b2c-scapi-admin/references/CLIENT-EXAMPLES.md +4 -4
- package/content/guidance/b2c/b2c-scapi-shopper/SKILL.md +6 -6
- package/content/guidance/b2c/b2c-scapi-shopper/references/CLIENT-EXAMPLES.md +8 -9
- package/content/guidance/b2c-cli/b2c-cip/SKILL.md +3 -3
- package/content/guidance/b2c-cli/b2c-cip/references/SALES_ANALYSIS.md +1 -1
- package/content/guidance/b2c-cli/b2c-config/SKILL.md +31 -21
- package/content/guidance/b2c-cli/b2c-content/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-debug/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-docs/SKILL.md +23 -2
- package/content/guidance/b2c-cli/b2c-ecdn/references/ADVANCED.md +1 -1
- package/content/guidance/b2c-cli/b2c-job/references/IMPORT.md +1 -1
- package/content/guidance/b2c-cli/b2c-metrics/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-mrt/SKILL.md +3 -3
- package/content/guidance/b2c-cli/b2c-scapi-custom/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-scapi-schemas/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-site-import-export/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-sites/SKILL.md +1 -1
- package/content/guidance/b2c-cli/b2c-slas/SKILL.md +1 -1
- package/content/guidance/b2c-ops/b2c-checkout-triage/SKILL.md +2 -2
- package/content/guidance/b2c-ops/b2c-job-health/SKILL.md +2 -2
- package/content/guidance/b2c-ops/b2c-order-failure-triage/SKILL.md +1 -1
- package/content/guidance/b2c-ops/b2c-order-failure-triage/references/order-evidence.md +2 -2
- package/content/guidance/b2c-ops/b2c-production-triage/SKILL.md +4 -4
- package/content/guidance/index.json +935 -258
- package/content/guidance/mcp/{cip → b2c-mcp-cip}/SKILL.md +10 -8
- package/content/guidance/mcp/{b2c-config → b2c-mcp-config}/SKILL.md +10 -9
- package/content/guidance/mcp/{debugger → b2c-mcp-debugger}/SKILL.md +9 -8
- package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/SKILL.md +81 -10
- package/content/guidance/mcp/{server → b2c-mcp-server}/SKILL.md +49 -25
- package/content/guidance/storefront-next/sfnext-accessibility/SKILL.md +103 -0
- package/content/guidance/storefront-next/sfnext-accessibility/references/checklist.md +64 -0
- package/content/guidance/storefront-next/sfnext-analytics-consent/SKILL.md +91 -0
- package/content/guidance/storefront-next/sfnext-analytics-consent/references/CUSTOM-ADAPTER.md +49 -0
- package/content/guidance/storefront-next/sfnext-authentication/SKILL.md +86 -79
- package/content/guidance/storefront-next/sfnext-authentication/references/COOKIES.md +39 -0
- package/content/guidance/storefront-next/sfnext-authentication/references/LOGIN-FLOWS.md +59 -0
- package/content/guidance/storefront-next/sfnext-commerce-features/SKILL.md +67 -0
- package/content/guidance/storefront-next/sfnext-commerce-features/references/FEATURE-PREREQUISITES.md +37 -0
- package/content/guidance/storefront-next/sfnext-components/SKILL.md +98 -136
- package/content/guidance/storefront-next/sfnext-components/references/COMPONENT-AUTHORING.md +118 -0
- package/content/guidance/storefront-next/sfnext-components/references/SHAPE-TOKENS.md +51 -0
- package/content/guidance/storefront-next/sfnext-components/references/STORYBOOK.md +54 -0
- package/content/guidance/storefront-next/sfnext-components/references/TOKEN-SYSTEM.md +53 -0
- package/content/guidance/storefront-next/sfnext-components/references/TROUBLESHOOTING.md +19 -0
- package/content/guidance/storefront-next/sfnext-configuration/SKILL.md +116 -113
- package/content/guidance/storefront-next/sfnext-configuration/references/ENV-VARIABLES.md +55 -0
- package/content/guidance/storefront-next/sfnext-configuration/references/MULTI-SITE-URLS.md +137 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/SKILL.md +100 -150
- package/content/guidance/storefront-next/sfnext-data-fetching/references/ACTIONS.md +53 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/references/API-CLIENTS.md +34 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/references/LOADERS.md +73 -0
- package/content/guidance/storefront-next/sfnext-data-fetching/references/SCAPI-FETCHER.md +23 -77
- package/content/guidance/storefront-next/sfnext-deployment/SKILL.md +83 -97
- package/content/guidance/storefront-next/sfnext-deployment/references/MRT-DEPLOYMENT.md +37 -68
- package/content/guidance/storefront-next/sfnext-extensions/SKILL.md +73 -97
- package/content/guidance/storefront-next/sfnext-extensions/references/ACTION-HOOKS.md +57 -0
- package/content/guidance/storefront-next/sfnext-extensions/references/BASE-AUDIT.md +47 -44
- package/content/guidance/storefront-next/sfnext-extensions/references/CLI-AND-INSTALL.md +58 -0
- package/content/guidance/storefront-next/sfnext-extensions/references/EXTENSION-EXAMPLES.md +49 -86
- package/content/guidance/storefront-next/sfnext-hybrid-storefronts/SKILL.md +59 -114
- package/content/guidance/storefront-next/sfnext-hybrid-storefronts/references/HYBRID-PROXY-CONFIG.md +53 -90
- package/content/guidance/storefront-next/sfnext-i18n/SKILL.md +96 -131
- package/content/guidance/storefront-next/sfnext-i18n/references/locale-config.md +35 -0
- package/content/guidance/storefront-next/sfnext-overview/SKILL.md +101 -0
- package/content/guidance/storefront-next/sfnext-page-designer/SKILL.md +152 -131
- package/content/guidance/storefront-next/sfnext-page-designer/references/BUSINESS-MANAGER.md +46 -0
- package/content/guidance/storefront-next/sfnext-page-designer/references/COMPONENT-REGISTRY.md +86 -53
- package/content/guidance/storefront-next/sfnext-page-designer/references/DECORATOR-PATTERNS.md +119 -131
- package/content/guidance/storefront-next/sfnext-page-designer/references/REVIEW-CHECKLIST.md +83 -0
- package/content/guidance/storefront-next/sfnext-page-designer/references/TROUBLESHOOTING.md +35 -0
- package/content/guidance/storefront-next/sfnext-performance/SKILL.md +75 -105
- package/content/guidance/storefront-next/sfnext-performance/references/PERFORMANCE-REVIEW-CHECKLIST.md +85 -0
- package/content/guidance/storefront-next/sfnext-performance/references/SUSPENSE-AND-STREAMING.md +58 -0
- package/content/guidance/storefront-next/sfnext-project-setup/SKILL.md +103 -116
- package/content/guidance/storefront-next/sfnext-project-setup/references/PROJECT-STRUCTURE.md +61 -99
- package/content/guidance/storefront-next/sfnext-project-setup/references/SCRIPTS.md +47 -0
- package/content/guidance/storefront-next/sfnext-project-setup/references/SFNEXT-CLI.md +63 -0
- package/content/guidance/storefront-next/sfnext-quality-gates/SKILL.md +70 -0
- package/content/guidance/storefront-next/sfnext-quality-gates/references/lint-and-budgets.md +39 -0
- package/content/guidance/storefront-next/sfnext-revalidation/SKILL.md +121 -0
- package/content/guidance/storefront-next/sfnext-revalidation/references/POLICIES-AND-TAGS.md +55 -0
- package/content/guidance/storefront-next/sfnext-routing/SKILL.md +86 -143
- package/content/guidance/storefront-next/sfnext-routing/references/ROUTE-CONVENTIONS.md +51 -51
- package/content/guidance/storefront-next/sfnext-routing/references/URLS-AND-SEO-ROUTES.md +22 -0
- package/content/guidance/storefront-next/sfnext-scapi/SKILL.md +126 -0
- package/content/guidance/storefront-next/sfnext-scapi/references/WORKED-EXAMPLE.md +39 -0
- package/content/guidance/storefront-next/sfnext-security/SKILL.md +129 -0
- package/content/guidance/storefront-next/sfnext-security/references/COOKIE-DOMAIN.md +39 -0
- package/content/guidance/storefront-next/sfnext-security/references/TURNSTILE.md +43 -0
- package/content/guidance/storefront-next/sfnext-seo/SKILL.md +95 -0
- package/content/guidance/storefront-next/sfnext-seo/references/MULTI-DOMAIN-BASE-PATH.md +17 -0
- package/content/guidance/storefront-next/sfnext-seo/references/SEO-ROUTES.md +31 -0
- package/content/guidance/storefront-next/sfnext-state-management/SKILL.md +80 -89
- package/content/guidance/storefront-next/sfnext-state-management/references/PATTERNS.md +45 -0
- package/content/guidance/storefront-next/sfnext-testing/SKILL.md +105 -138
- package/content/guidance/storefront-next/sfnext-testing/references/E2E.md +38 -0
- package/content/guidance/storefront-next/sfnext-testing/references/STORYBOOK-PATTERNS.md +73 -94
- package/content/guidance/storefront-next/sfnext-testing/references/UNIT-AND-ROUTE-TESTS.md +60 -0
- package/content/guidance/storefront-next/sfnext-theming/SKILL.md +104 -0
- package/content/guidance/storefront-next/sfnext-theming/references/REBRAND-CHECKLIST.md +29 -0
- package/dist/commands/mcp.d.ts +8 -2
- package/dist/commands/mcp.js +54 -20
- package/dist/guidance.d.ts +4 -1
- package/dist/guidance.js +23 -5
- package/dist/registry.d.ts +2 -1
- package/dist/registry.js +3 -3
- package/dist/server.d.ts +10 -0
- package/dist/server.js +21 -0
- package/dist/skill-references.js +5 -5
- package/dist/tools/cartridges/index.js +1 -0
- package/dist/tools/cip/index.js +6 -3
- package/dist/tools/diagnostics/debug-capture-at-breakpoint.js +1 -1
- package/dist/tools/diagnostics/debug-set-breakpoints.js +1 -1
- package/dist/tools/diagnostics/debug-start-session.js +1 -1
- package/dist/tools/scapi/index.d.ts +4 -1
- package/dist/tools/scapi/index.js +4 -2
- package/dist/tools/scapi/scapi-code.d.ts +2 -2
- package/dist/tools/scapi/scapi-code.js +17 -61
- package/dist/utils/types.d.ts +6 -0
- package/node_modules/@salesforce/b2c-agent-plugins/CHANGELOG.md +20 -0
- package/node_modules/@salesforce/b2c-agent-plugins/README.md +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/.codex-plugin/plugin.json +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/plugin.json +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-hooks/references/ORDER-HOOK-LIFECYCLE.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-onboarding/SKILL.md +4 -4
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-ordering/SKILL.md +2 -2
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-querying-data/SKILL.md +2 -2
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-scapi-admin/SKILL.md +3 -3
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-scapi-admin/references/CLIENT-EXAMPLES.md +4 -4
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-scapi-shopper/SKILL.md +6 -6
- package/node_modules/@salesforce/b2c-agent-plugins/b2c/skills/b2c-scapi-shopper/references/CLIENT-EXAMPLES.md +8 -9
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/.codex-plugin/plugin.json +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/plugin.json +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-cip/SKILL.md +3 -3
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-cip/references/SALES_ANALYSIS.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-config/SKILL.md +31 -21
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-content/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-debug/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-docs/SKILL.md +23 -2
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-ecdn/references/ADVANCED.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-job/references/IMPORT.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-metrics/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-mrt/SKILL.md +3 -3
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-scapi-custom/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-scapi-schemas/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-site-import-export/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-sites/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-cli/skills/b2c-slas/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/.codex-plugin/plugin.json +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/plugin.json +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-checkout-triage/SKILL.md +2 -2
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-job-health/SKILL.md +2 -2
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-order-failure-triage/SKILL.md +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-order-failure-triage/references/order-evidence.md +2 -2
- package/node_modules/@salesforce/b2c-agent-plugins/b2c-ops/skills/b2c-production-triage/SKILL.md +4 -4
- package/node_modules/@salesforce/b2c-agent-plugins/figma-to-sfnext-pagedesigner/README.md +4 -4
- package/node_modules/@salesforce/b2c-agent-plugins/figma-to-sfnext-pagedesigner/skills/figma-to-sfnext-pagedesigner/SKILL.md +76 -73
- package/node_modules/@salesforce/b2c-agent-plugins/figma-to-sfnext-pagedesigner/skills/figma-to-sfnext-pagedesigner/evals/trigger-evals.json +12 -10
- package/node_modules/@salesforce/b2c-agent-plugins/figma-to-sfnext-pagedesigner/skills/figma-to-sfnext-pagedesigner/references/PAGE-DESIGNER-SFN.md +49 -74
- package/node_modules/@salesforce/b2c-agent-plugins/package.json +1 -1
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/.codex-plugin/plugin.json +9 -6
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/README.md +43 -22
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/plugin.json +9 -6
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-accessibility/SKILL.md +103 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-accessibility/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-accessibility/references/checklist.md +64 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-analytics-consent/SKILL.md +91 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-analytics-consent/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-analytics-consent/references/CUSTOM-ADAPTER.md +49 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-authentication/SKILL.md +86 -79
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-authentication/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-authentication/references/COOKIES.md +39 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-authentication/references/LOGIN-FLOWS.md +59 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-commerce-features/SKILL.md +67 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-commerce-features/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-commerce-features/references/FEATURE-PREREQUISITES.md +37 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/SKILL.md +98 -136
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/COMPONENT-AUTHORING.md +118 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/SHAPE-TOKENS.md +51 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/STORYBOOK.md +54 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/TOKEN-SYSTEM.md +53 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-components/references/TROUBLESHOOTING.md +19 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-configuration/SKILL.md +116 -113
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-configuration/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-configuration/references/ENV-VARIABLES.md +55 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-configuration/references/MULTI-SITE-URLS.md +137 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/SKILL.md +100 -150
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/ACTIONS.md +53 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/API-CLIENTS.md +34 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/LOADERS.md +73 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/SCAPI-FETCHER.md +23 -77
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-deployment/SKILL.md +83 -97
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-deployment/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-deployment/references/MRT-DEPLOYMENT.md +37 -68
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/SKILL.md +73 -97
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/references/ACTION-HOOKS.md +57 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/references/BASE-AUDIT.md +47 -44
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/references/CLI-AND-INSTALL.md +58 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-extensions/references/EXTENSION-EXAMPLES.md +49 -86
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-hybrid-storefronts/SKILL.md +59 -114
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-hybrid-storefronts/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-hybrid-storefronts/references/HYBRID-PROXY-CONFIG.md +53 -90
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-i18n/SKILL.md +96 -131
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-i18n/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-i18n/references/locale-config.md +35 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-overview/SKILL.md +101 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-overview/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/SKILL.md +152 -131
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/BUSINESS-MANAGER.md +46 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/COMPONENT-REGISTRY.md +86 -53
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/DECORATOR-PATTERNS.md +119 -131
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/REVIEW-CHECKLIST.md +83 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-page-designer/references/TROUBLESHOOTING.md +35 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-performance/SKILL.md +75 -105
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-performance/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-performance/references/PERFORMANCE-REVIEW-CHECKLIST.md +85 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-performance/references/SUSPENSE-AND-STREAMING.md +58 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/SKILL.md +103 -116
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/references/PROJECT-STRUCTURE.md +61 -99
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/references/SCRIPTS.md +47 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/references/SFNEXT-CLI.md +63 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-quality-gates/SKILL.md +70 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-quality-gates/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-quality-gates/references/lint-and-budgets.md +39 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-revalidation/SKILL.md +121 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-revalidation/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-revalidation/references/POLICIES-AND-TAGS.md +55 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-routing/SKILL.md +86 -143
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-routing/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-routing/references/ROUTE-CONVENTIONS.md +51 -51
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-routing/references/URLS-AND-SEO-ROUTES.md +22 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi/SKILL.md +126 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi/references/WORKED-EXAMPLE.md +39 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-security/SKILL.md +129 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-security/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-security/references/COOKIE-DOMAIN.md +39 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-security/references/TURNSTILE.md +43 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-seo/SKILL.md +95 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-seo/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-seo/references/MULTI-DOMAIN-BASE-PATH.md +17 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-seo/references/SEO-ROUTES.md +31 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-state-management/SKILL.md +80 -89
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-state-management/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-state-management/references/PATTERNS.md +45 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/SKILL.md +105 -138
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/references/E2E.md +38 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/references/STORYBOOK-PATTERNS.md +73 -94
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-testing/references/UNIT-AND-ROUTE-TESTS.md +60 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-theming/SKILL.md +104 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-theming/evals/trigger-evals.json +5 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-theming/references/REBRAND-CHECKLIST.md +29 -0
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next-figma/skills/sfnext-create-figma-kit/SKILL.md +3 -3
- package/oclif.manifest.json +21 -4
- package/package.json +3 -3
- package/content/guidance/storefront-next/sfnext-create-component/SKILL.md +0 -195
- package/content/guidance/storefront-next/sfnext-create-component/references/COMPONENT-AUTHORING.md +0 -206
- package/content/guidance/storefront-next/sfnext-create-component/references/PROJECT-STRUCTURE.md +0 -43
- package/content/guidance/storefront-next/sfnext-create-component/references/TOKEN-SYSTEM.md +0 -130
- package/content/guidance/storefront-next/sfnext-create-component/references/TROUBLESHOOTING.md +0 -34
- package/content/guidance/storefront-next/sfnext-create-vertical/SKILL.md +0 -135
- package/content/guidance/storefront-next/sfnext-create-vertical/references/COMPONENT-AUTHORING.md +0 -206
- package/content/guidance/storefront-next/sfnext-create-vertical/references/PROJECT-STRUCTURE.md +0 -43
- package/content/guidance/storefront-next/sfnext-create-vertical/references/TOKEN-SYSTEM.md +0 -130
- package/content/guidance/storefront-next/sfnext-create-vertical/references/TROUBLESHOOTING.md +0 -34
- package/content/guidance/storefront-next/sfnext-custom-apis/SKILL.md +0 -221
- package/content/guidance/storefront-next/sfnext-custom-apis/references/WORKFLOW-EXAMPLES.md +0 -294
- package/content/guidance/storefront-next/sfnext-data-fetching/references/LOADER-PATTERNS.md +0 -102
- package/content/guidance/storefront-next/sfnext-project-setup/references/ENV-VARIABLES.md +0 -82
- package/content/guidance/storefront-next/sfnext-scapi-management/SKILL.md +0 -203
- package/content/guidance/storefront-next/sfnext-scapi-management/references/CLI-COMMANDS.md +0 -122
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/SKILL.md +0 -195
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/evals/trigger-evals.json +0 -12
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/references/COMPONENT-AUTHORING.md +0 -206
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/references/PROJECT-STRUCTURE.md +0 -43
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/references/TOKEN-SYSTEM.md +0 -130
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-component/references/TROUBLESHOOTING.md +0 -34
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/SKILL.md +0 -135
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/evals/trigger-evals.json +0 -12
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/references/COMPONENT-AUTHORING.md +0 -206
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/references/PROJECT-STRUCTURE.md +0 -43
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/references/TOKEN-SYSTEM.md +0 -130
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-create-vertical/references/TROUBLESHOOTING.md +0 -34
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-custom-apis/SKILL.md +0 -221
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-custom-apis/evals/trigger-evals.json +0 -12
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-custom-apis/references/WORKFLOW-EXAMPLES.md +0 -294
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-data-fetching/references/LOADER-PATTERNS.md +0 -102
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-project-setup/references/ENV-VARIABLES.md +0 -82
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi-management/SKILL.md +0 -203
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi-management/evals/trigger-evals.json +0 -12
- package/node_modules/@salesforce/b2c-agent-plugins/storefront-next/skills/sfnext-scapi-management/references/CLI-COMMANDS.md +0 -122
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/custom-apis.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/custom-properties.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/jobs.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/products.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/promotions.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/saving.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/snippets.md +0 -0
- /package/content/guidance/mcp/{scapi → b2c-mcp-scapi}/references/tokens.md +0 -0
- /package/content/guidance/mcp/{server → b2c-mcp-server}/references/files.md +0 -0
|
@@ -1,184 +1,151 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sfnext-testing
|
|
3
|
-
description:
|
|
3
|
+
description: >-
|
|
4
|
+
Write and run tests for a Storefront Next project: Vitest + React Testing Library unit tests, route loader/action tests (createLoaderArgs, createTestContext), Storybook stories with snapshot, interaction (play) and a11y runs, and a pointer to the CodeceptJS/Playwright e2e suite. Use for "write a test for this component/loader", "add a story", pnpm test, pnpm storybook:test --type=snapshot|interaction|a11y, coverage thresholds, routeLoaderData / scapiMock / mockRoutes story parameters, MSW mocking, fixtures in @/components/__mocks__, failing snapshot updates, or pnpm e2e. Do not use for lint, typecheck, format, bundle-size or Lighthouse gates (use `storefront-next:sfnext-quality-gates`), accessibility rules and fixes (use `storefront-next:sfnext-accessibility`), or translations (use `storefront-next:sfnext-i18n`).
|
|
4
5
|
---
|
|
5
6
|
|
|
6
|
-
# Testing
|
|
7
|
+
# Testing Storefront Next
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
Three layers, all shipped in your project (see `docs/README-TESTS.md`, `docs/README-STORYBOOK.md`, `AGENTS.md`):
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
| Layer | Tool | Files | Command |
|
|
12
|
+
|-------|------|-------|---------|
|
|
13
|
+
| Unit and route tests | Vitest, jsdom, Testing Library, MSW | `*.test.ts(x)` next to source | `pnpm test` |
|
|
14
|
+
| Component stories | Storybook: snapshot (Vitest), interaction and a11y (Playwright/Chromium) | `<component>/stories/*.stories.tsx` | `pnpm storybook:test --type=...` |
|
|
15
|
+
| End to end | CodeceptJS + Playwright | `e2e/` | `pnpm e2e` |
|
|
11
16
|
|
|
12
|
-
|
|
17
|
+
Prefer the cheapest layer that proves the behavior: pure logic and loaders in Vitest, rendered states and interactions in stories, cross-page shopper flows in e2e.
|
|
13
18
|
|
|
14
|
-
|
|
15
|
-
// src/components/product-card/product-card.test.tsx
|
|
16
|
-
import { describe, it, expect, vi } from 'vitest';
|
|
17
|
-
import { render, screen } from '@testing-library/react';
|
|
18
|
-
import { ProductCard } from './product-card';
|
|
19
|
-
import { mockProduct } from '@/test-utils/mocks';
|
|
19
|
+
## Commands
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
21
|
+
```bash
|
|
22
|
+
pnpm test # all unit tests (vitest run); does NOT collect coverage
|
|
23
|
+
pnpm test src/components/footer # one file or directory
|
|
24
|
+
pnpm test:watch # watch mode
|
|
25
|
+
pnpm test --coverage # coverage report (thresholds enforced)
|
|
26
|
+
pnpm test --ui # Vitest UI
|
|
27
|
+
|
|
28
|
+
pnpm storybook # dev server on :6006
|
|
29
|
+
pnpm exec playwright install chromium # once, for interaction/a11y runs
|
|
30
|
+
pnpm storybook:test --type=snapshot # add --update to rewrite snapshots
|
|
31
|
+
pnpm storybook:test --type=interaction # play() functions in real Chromium
|
|
32
|
+
pnpm storybook:test --type=a11y # axe checks
|
|
33
|
+
pnpm storybook:test --type=snapshot --stories=footer # narrow to matching story paths
|
|
27
34
|
```
|
|
28
35
|
|
|
29
|
-
|
|
36
|
+
Add `--static` (optionally `--reuse-build` after `pnpm storybook:build`) to run interaction or a11y against a static build. `--coverage` with snapshot generates story tests and reports story coverage.
|
|
30
37
|
|
|
31
|
-
|
|
38
|
+
Coverage thresholds live inline in `vitest.config.ts` (`thresholds`), and `src/components/ui/**`, stories, snapshot fixtures and `__mocks__` are excluded from coverage. Do not chase 100%.
|
|
32
39
|
|
|
33
|
-
|
|
34
|
-
- `context-provider-utils.ts` — Context provider helpers for testing
|
|
35
|
-
- `context-provider.tsx` — Test context providers
|
|
40
|
+
## Unit test
|
|
36
41
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
```tsx
|
|
43
|
+
import { render, screen } from '@testing-library/react';
|
|
44
|
+
import { describe, expect, it } from 'vitest';
|
|
45
|
+
import { AllProvidersWrapper } from '@/test-utils/context-provider';
|
|
46
|
+
import MyThing from './index';
|
|
47
|
+
|
|
48
|
+
describe('MyThing', () => {
|
|
49
|
+
it('renders the label', () => {
|
|
50
|
+
render(<MyThing label="Hello" />, { wrapper: AllProvidersWrapper });
|
|
51
|
+
expect(screen.getByText('Hello')).toBeInTheDocument();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
43
54
|
```
|
|
44
55
|
|
|
45
|
-
|
|
56
|
+
`vitest.setup.ts` already provides jest-dom matchers, i18next (`en-GB`), `window.__APP_CONFIG__`, a global mock of `@/hooks/use-analytics`, and a 10s async-util timeout; do not re-add them. Helpers, wrappers and the analytics caveat: [references/UNIT-AND-ROUTE-TESTS.md](references/UNIT-AND-ROUTE-TESTS.md).
|
|
57
|
+
|
|
58
|
+
## Route loader / action test
|
|
46
59
|
|
|
47
|
-
|
|
60
|
+
```ts
|
|
61
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
62
|
+
import { createLoaderArgs, createTestContext } from '@/lib/test-utils';
|
|
63
|
+
import { loader } from './resource.basket-products';
|
|
48
64
|
|
|
49
|
-
|
|
50
|
-
|--------|---------|
|
|
51
|
-
| Lines | 73% |
|
|
52
|
-
| Statements | 73% |
|
|
53
|
-
| Functions | 72% |
|
|
54
|
-
| Branches | 67% |
|
|
65
|
+
vi.mock('@/lib/api-clients.server', () => ({ createApiClients: vi.fn() }));
|
|
55
66
|
|
|
56
|
-
|
|
67
|
+
it('returns data', async () => {
|
|
68
|
+
const context = createTestContext({ authSession: { userType: 'guest' } });
|
|
69
|
+
const args = createLoaderArgs(new Request('http://localhost/x'), context, {
|
|
70
|
+
params: {},
|
|
71
|
+
pattern: '/' as never,
|
|
72
|
+
});
|
|
73
|
+
const result = await loader(args);
|
|
74
|
+
expect(result).toBeDefined();
|
|
75
|
+
});
|
|
76
|
+
```
|
|
57
77
|
|
|
58
|
-
-
|
|
59
|
-
- `@testing-library/jest-dom` — Custom DOM matchers (`toBeInTheDocument`, etc.)
|
|
60
|
-
- `@testing-library/user-event` — User interaction simulation
|
|
61
|
-
- `@vitest/coverage-v8` — Code coverage
|
|
62
|
-
- `@vitest/ui` — Interactive test UI
|
|
78
|
+
`createActionArgs` is the action twin and `expectStatus(result, 400)` asserts `data()` statuses. Mock `@/lib/api-clients.server` (SCAPI) at the module boundary, or use MSW for HTTP-level tests. See `storefront-next:sfnext-data-fetching` for the loader patterns under test.
|
|
63
79
|
|
|
64
|
-
##
|
|
80
|
+
## Stories
|
|
65
81
|
|
|
66
|
-
|
|
82
|
+
Stories live in a `stories/` subfolder next to the component (required; coverage tooling only matches there):
|
|
67
83
|
|
|
68
|
-
|
|
84
|
+
```
|
|
85
|
+
src/components/footer/
|
|
86
|
+
├── index.tsx
|
|
87
|
+
├── index.test.tsx
|
|
88
|
+
└── stories/
|
|
89
|
+
├── index.stories.tsx
|
|
90
|
+
├── footer-snapshot.tsx # snapshot fixture, only where a snapshot test exists
|
|
91
|
+
└── __snapshots__/
|
|
92
|
+
```
|
|
69
93
|
|
|
70
|
-
```
|
|
71
|
-
// src/components/product-card/product-card.stories.tsx
|
|
94
|
+
```tsx
|
|
72
95
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
73
|
-
import {
|
|
96
|
+
import { expect, within } from 'storybook/test';
|
|
74
97
|
import { waitForStorybookReady } from '@storybook/test-utils';
|
|
75
|
-
import {
|
|
76
|
-
import
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
title: 'Components/ProductCard',
|
|
82
|
-
component: ProductCard,
|
|
98
|
+
import { mockProductSearchItem } from '@/components/__mocks__/product-search-hit-data';
|
|
99
|
+
import ProductTile from '../index';
|
|
100
|
+
|
|
101
|
+
const meta: Meta<typeof ProductTile> = {
|
|
102
|
+
title: 'Products/Product Tile', // Domain/Component from the fixed sidebar groups
|
|
103
|
+
component: ProductTile,
|
|
83
104
|
tags: ['autodocs', 'interaction'],
|
|
84
|
-
decorators: [
|
|
85
|
-
(Story) => (
|
|
86
|
-
<ConfigProvider config={mockConfig}>
|
|
87
|
-
<Story />
|
|
88
|
-
</ConfigProvider>
|
|
89
|
-
),
|
|
90
|
-
],
|
|
91
105
|
};
|
|
92
|
-
|
|
93
106
|
export default meta;
|
|
94
|
-
type Story = StoryObj<typeof
|
|
107
|
+
type Story = StoryObj<typeof meta>;
|
|
95
108
|
|
|
96
109
|
export const Default: Story = {
|
|
97
|
-
args: {
|
|
98
|
-
product: mockProduct,
|
|
99
|
-
},
|
|
110
|
+
args: { product: mockProductSearchItem },
|
|
100
111
|
play: async ({ canvasElement }) => {
|
|
101
112
|
await waitForStorybookReady(canvasElement);
|
|
102
|
-
|
|
103
|
-
await expect(canvas.getByText(mockProduct.productName)).toBeInTheDocument();
|
|
113
|
+
await expect(within(canvasElement).getAllByRole('link')[0]).toBeInTheDocument();
|
|
104
114
|
},
|
|
105
115
|
};
|
|
106
116
|
```
|
|
107
117
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
### Storybook Commands
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
pnpm storybook # Dev server (port 6006)
|
|
114
|
-
pnpm build-storybook # Build static Storybook
|
|
115
|
-
pnpm test-storybook:snapshot # Snapshot tests
|
|
116
|
-
pnpm test-storybook:snapshot:update # Update snapshots
|
|
117
|
-
pnpm test-storybook:interaction # Interaction tests
|
|
118
|
-
pnpm test-storybook:a11y # Accessibility tests
|
|
119
|
-
pnpm generate:story-tests:coverage # Story coverage report
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
### Story Tags
|
|
118
|
+
Rules of thumb:
|
|
123
119
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
120
|
+
- Every story is already wrapped by a global decorator (memory router + config, site, i18n, auth, basket providers). Do not add your own `ConfigProvider`. If you truly need one, import it from `@salesforce/storefront-next-runtime/config`.
|
|
121
|
+
- Import test helpers from `storybook/test` (not `@storybook/test`).
|
|
122
|
+
- Props first; mock at the route boundary with `parameters` (`routeLoaderData`, `scapiMock`, `miniCartData`, `mockRoutes`), never `vi.mock` of hooks inside a story. Args must be JSON-serializable.
|
|
123
|
+
- Tags: `autodocs` (docs page), `interaction` (included in interaction runs), `skip-a11y` (excluded from a11y runs; use sparingly and comment why).
|
|
124
|
+
- Use Storybook's viewport toolbar instead of separate mobile/desktop stories.
|
|
125
|
+
- Fixtures: `@/components/__mocks__` (barrel of curated fixtures) or `@/components/__mocks__/<file>` for ones not re-exported; shared with unit tests.
|
|
129
126
|
|
|
130
|
-
|
|
127
|
+
Full reference, including parameters, mock routes, taxonomy and argTypes: [references/STORYBOOK-PATTERNS.md](references/STORYBOOK-PATTERNS.md).
|
|
131
128
|
|
|
132
|
-
|
|
129
|
+
## End to end
|
|
133
130
|
|
|
134
|
-
|
|
135
|
-
// src/routes/_app.product.$productId.test.tsx
|
|
136
|
-
import { describe, test, expect, vi } from 'vitest';
|
|
137
|
-
import { render } from '@testing-library/react';
|
|
131
|
+
`e2e/` is a separate CodeceptJS + Playwright project with its own `AGENTS.md`. Run `pnpm e2e` (add `--mode=local` to start the dev server, `--grep "@checkout"`, `--headed`). To author tests, use the skills shipped in your project at `e2e/.claude/skills/generate-storefront-e2e-test` and `e2e/.claude/skills/checkout-test-development`. Setup, env vars and the `pnpm a11y` scan: [references/E2E.md](references/E2E.md).
|
|
138
132
|
|
|
139
|
-
|
|
140
|
-
default: ({ product }: any) => (
|
|
141
|
-
<div data-testid="product-view">
|
|
142
|
-
<div data-testid="product-name">{product?.name}</div>
|
|
143
|
-
</div>
|
|
144
|
-
),
|
|
145
|
-
}));
|
|
146
|
-
```
|
|
133
|
+
## Pitfalls
|
|
147
134
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
│ │ └── stories/
|
|
157
|
-
│ │ └── index.stories.tsx # Stories
|
|
158
|
-
├── routes/
|
|
159
|
-
│ ├── _app.product.$productId.tsx
|
|
160
|
-
│ └── _app.product.$productId.test.tsx
|
|
161
|
-
└── test-utils/ # Shared utilities
|
|
162
|
-
├── config.ts
|
|
163
|
-
└── context-provider-utils.ts
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
## Best Practices
|
|
167
|
-
|
|
168
|
-
1. **Colocate tests** — Keep test files next to source files
|
|
169
|
-
2. **Use test utilities** — Leverage `@/test-utils` for mocks and providers
|
|
170
|
-
3. **Mock external dependencies** — Use `vi.mock()` for API clients and context
|
|
171
|
-
4. **Test interactions** — Use `@testing-library/user-event` and Storybook play functions
|
|
172
|
-
5. **Test accessibility** — Use Storybook a11y addon
|
|
173
|
-
6. **Multiple story variants** — Create stories for Default, Loading, Error states
|
|
174
|
-
7. **Use viewport toolbar** — Test responsive layouts via Storybook's built-in viewport toolbar
|
|
135
|
+
| Pitfall | Fix |
|
|
136
|
+
|---------|-----|
|
|
137
|
+
| Story outside `stories/` | Move it; coverage and generated snapshot tests only find `stories/*.stories.tsx`. |
|
|
138
|
+
| Interaction/a11y run fails to launch a browser | `pnpm exec playwright install chromium`. |
|
|
139
|
+
| Snapshot diff after an intentional DOM change | Review it, then `pnpm storybook:test --type=snapshot --update`. |
|
|
140
|
+
| Test passes but analytics never fires | `@/hooks/use-analytics` is mocked globally; `vi.unmock` it in the test to assert on track calls. |
|
|
141
|
+
| Portalled dialog/toast not found in a play function | Query `within(canvasElement.ownerDocument.body)`. |
|
|
142
|
+
| Mocking too deep | If an internal refactor forces story edits, push the mock to the route/fixture layer. |
|
|
175
143
|
|
|
176
144
|
## Related Skills
|
|
177
145
|
|
|
178
|
-
- `storefront-next:sfnext-
|
|
179
|
-
- `storefront-next:sfnext-
|
|
180
|
-
- `storefront-next:sfnext-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
- [Storybook Patterns Reference](references/STORYBOOK-PATTERNS.md) - Advanced story patterns and testing
|
|
146
|
+
- `storefront-next:sfnext-quality-gates` - lint, typecheck, format and the pre-PR checklist
|
|
147
|
+
- `storefront-next:sfnext-accessibility` - a11y assertions in stories and the e2e axe scan
|
|
148
|
+
- `storefront-next:sfnext-components` - component conventions under test
|
|
149
|
+
- `storefront-next:sfnext-data-fetching` - loaders and actions
|
|
150
|
+
- `storefront-next:sfnext-page-designer` - testing Page Designer components
|
|
151
|
+
- `storefront-next:sfnext-i18n` - translations in tests
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# End-to-end tests
|
|
2
|
+
|
|
3
|
+
`e2e/` is a standalone CodeceptJS + Playwright project shipped with your storefront, with its own `e2e/AGENTS.md`, `e2e/README.md`, `e2e/docs/`, and in-project skills:
|
|
4
|
+
|
|
5
|
+
- `e2e/.claude/skills/generate-storefront-e2e-test/SKILL.md`: structured workflow for new specs, page objects, flows and self-healing recipes.
|
|
6
|
+
- `e2e/.claude/skills/checkout-test-development/`: checkout-specific E2E, debugging and performance guidance.
|
|
7
|
+
|
|
8
|
+
Use those skills when authoring or debugging e2e tests; this page only orients you.
|
|
9
|
+
|
|
10
|
+
## Setup
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
cp e2e/.env.sample e2e/.env # BASE_URL, SITE_ID, SITE_ALIAS, LOCALE, HEADLESS, ...
|
|
14
|
+
pnpm install # per e2e/README.md this also installs Playwright browsers; if not, pnpm exec playwright install chromium
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The storefront itself needs its own `.env` (see `storefront-next:sfnext-configuration`).
|
|
18
|
+
|
|
19
|
+
## Run
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pnpm e2e # against a running storefront (BASE_URL, default http://localhost:5173)
|
|
23
|
+
pnpm e2e --mode=local # start the dev server automatically
|
|
24
|
+
pnpm e2e --mode=remote # BASE_URL must point at the deployed storefront
|
|
25
|
+
pnpm e2e --grep "@checkout" # filter by tag or name
|
|
26
|
+
pnpm e2e --headed # show the browser
|
|
27
|
+
pnpm e2e --debug # Playwright Inspector
|
|
28
|
+
pnpm e2e:turnstile # Turnstile-specific suite
|
|
29
|
+
pnpm a11y # axe scans of key pages, desktop + mobile (see sfnext-accessibility)
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The root scripts above delegate to `e2e/`; you do not need to run them from inside it.
|
|
33
|
+
|
|
34
|
+
## Keep in mind
|
|
35
|
+
|
|
36
|
+
- E2E runs against real backend data; prefer unit tests and stories for logic and visual states, and keep e2e for shopper journeys (search, PDP to cart, checkout, login).
|
|
37
|
+
- Optional AI healing is off unless you pass `--ai` and set `ANTHROPIC_API_KEY` in `e2e/.env`.
|
|
38
|
+
- `e2e/` is excluded from the root OxLint/Vitest runs and has its own `lint`, `format:check`, `typecheck` and `test` scripts (run from `e2e/`).
|
|
@@ -1,118 +1,97 @@
|
|
|
1
|
-
# Storybook
|
|
1
|
+
# Storybook patterns
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Source of truth in your project: `docs/README-STORYBOOK.md`, `.storybook/`, and the existing `stories/` folders. Copy a neighbor story before inventing structure.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
</ConfigProvider>
|
|
23
|
-
),
|
|
24
|
-
],
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
export default meta;
|
|
28
|
-
type Story = StoryObj<typeof MyComponent>;
|
|
5
|
+
## Principles
|
|
6
|
+
|
|
7
|
+
1. Props first. Reach for the global provider/router stack only when the component reads global context (auth, basket, site, locale).
|
|
8
|
+
2. Mock at the boundary. Prefer `parameters.routeLoaderData`, `parameters.scapiMock`, `parameters.mockRoutes` over `vi.mock` of hooks.
|
|
9
|
+
3. Args are JSON-serializable. Promises, class instances and functions returning promises break the Controls panel and snapshot serialization; put them in `parameters`.
|
|
10
|
+
4. One reason to update a mock. If an internal refactor forces story edits, the mock is too deep.
|
|
11
|
+
|
|
12
|
+
## Decorator stack
|
|
13
|
+
|
|
14
|
+
`.storybook/preview.tsx` applies `decorators: [withRouter(StoryShell)]` to every story:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
withRouter(StoryShell) in-memory React Router with default mock routes
|
|
18
|
+
StoryShell
|
|
19
|
+
StorybookWrapper config + site + i18n + auth + basket + storeLocator + checkoutOneClick
|
|
20
|
+
UITargetProviders
|
|
21
|
+
<Story />
|
|
29
22
|
```
|
|
30
23
|
|
|
31
|
-
|
|
24
|
+
Files: `.storybook/decorators/{with-router,with-providers,with-ui-targets,mock-routes}.tsx|ts`. Because of this, a story usually needs no per-story `ConfigProvider` or `SiteProvider`. If you do need to override config for one story, wrap with `ConfigProvider` from `@salesforce/storefront-next-runtime/config` and `SiteProvider` from `@salesforce/storefront-next-runtime/site-context`, using `mockConfig`, `mockLocale`, `mockSiteObject` from `@/test-utils/config` (see `src/components/footer/stories/index.stories.tsx`).
|
|
32
25
|
|
|
33
|
-
|
|
26
|
+
## Story parameters
|
|
34
27
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
28
|
+
| Parameter | Use |
|
|
29
|
+
|-----------|-----|
|
|
30
|
+
| `routeLoaderData: Record<string, unknown>` | Wrap the story in ancestor routes so `useRouteLoaderData(routeId)` resolves. Required for components that read a parent route's loader data. |
|
|
31
|
+
| `scapiMock: { data?: unknown }` | Override the default `/resource/api/client/:resource` response, for stories whose `play()` asserts specific product data. |
|
|
32
|
+
| `miniCartData: { basket, productsById }` | Override what `/resource/basket-products` returns (for example an empty cart). |
|
|
33
|
+
| `mockRoutes: RouteObject[]` | Add story-specific `/resource/*` or `/action/*` routes. Must not shadow `/`, `*` or a default mock path; `withRouter` throws on conflicts. |
|
|
39
34
|
|
|
40
|
-
|
|
41
|
-
args: { isLoading: true },
|
|
42
|
-
};
|
|
35
|
+
`buildDefaultMockRoutes` (in `.storybook/decorators/mock-routes.ts`) lists the default routes: basket enrichment, cart mutations, wishlist, OTP, product/bundle/set adds, site-context updates, tracking consent, place-order.
|
|
43
36
|
|
|
44
|
-
|
|
45
|
-
args: { error: 'Something went wrong' },
|
|
46
|
-
};
|
|
37
|
+
## Titles and sidebar
|
|
47
38
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
```
|
|
39
|
+
`meta.title` is `Domain/Component` or `Domain/Subgroup/Component`, Title Case With Spaces. Top-level groups: Account, Authentication, Cart, Category, Checkout, Content, Core, Design System, Extensions, Home, Layout, Products, Search. Pick the closest existing group by purpose, not by folder. This is a convention, not lint-enforced, and you may restructure it for your brand.
|
|
40
|
+
|
|
41
|
+
## Naming and layout
|
|
52
42
|
|
|
53
|
-
|
|
43
|
+
| Thing | Convention |
|
|
44
|
+
|-------|-----------|
|
|
45
|
+
| Story file | `*.stories.tsx` in `stories/` next to the component (required) |
|
|
46
|
+
| Story export | PascalCase state name: `Default`, `Loading`, `InvalidEmailError` |
|
|
47
|
+
| Snapshot fixture | `<name>-snapshot.tsx` next to the story, with `__snapshots__/` beside it |
|
|
48
|
+
| shadcn primitives in `src/components/ui/` | No stories or coverage requirement |
|
|
54
49
|
|
|
55
|
-
|
|
56
|
-
export const WithInteraction: Story = {
|
|
57
|
-
args: { title: 'Interactive' },
|
|
58
|
-
play: async ({ canvasElement }) => {
|
|
59
|
-
await waitForStorybookReady(canvasElement);
|
|
60
|
-
const canvas = within(canvasElement);
|
|
50
|
+
Default to one component per folder. Snapshot fixtures use `StoryTestWrapper` from `@storybook/test-utils`; copy an existing `*-snapshot.tsx` pair (for example under `src/components/footer/stories/`).
|
|
61
51
|
|
|
62
|
-
|
|
63
|
-
await expect(canvas.getByText('Interactive')).toBeInTheDocument();
|
|
52
|
+
## argTypes
|
|
64
53
|
|
|
65
|
-
|
|
66
|
-
const button = canvas.getByRole('button');
|
|
67
|
-
await userEvent.click(button);
|
|
54
|
+
Expose only what visibly drives the canvas:
|
|
68
55
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
},
|
|
72
|
-
}
|
|
56
|
+
```tsx
|
|
57
|
+
argTypes: {
|
|
58
|
+
label: { control: 'text', description: 'Label in the summary row' },
|
|
59
|
+
className: { control: false, table: { disable: true } },
|
|
60
|
+
onCancel: { action: 'cancel' },
|
|
61
|
+
}
|
|
73
62
|
```
|
|
74
63
|
|
|
75
|
-
##
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
(
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
],
|
|
88
|
-
|
|
89
|
-
// Multiple providers
|
|
90
|
-
decorators: [
|
|
91
|
-
(Story) => (
|
|
92
|
-
<ConfigProvider config={mockConfig}>
|
|
93
|
-
<AuthProvider auth={mockAuth}>
|
|
94
|
-
<Story />
|
|
95
|
-
</AuthProvider>
|
|
96
|
-
</ConfigProvider>
|
|
97
|
-
),
|
|
98
|
-
],
|
|
64
|
+
## play() functions
|
|
65
|
+
|
|
66
|
+
```tsx
|
|
67
|
+
import { expect, userEvent, within } from 'storybook/test';
|
|
68
|
+
import { waitForStorybookReady } from '@storybook/test-utils';
|
|
69
|
+
|
|
70
|
+
play: async ({ canvasElement }) => {
|
|
71
|
+
await waitForStorybookReady(canvasElement);
|
|
72
|
+
const canvas = within(canvasElement);
|
|
73
|
+
await userEvent.click(canvas.getByRole('button', { name: /add to cart/i }));
|
|
74
|
+
await expect(canvas.getByRole('status')).toHaveTextContent(/added/i);
|
|
75
|
+
},
|
|
99
76
|
```
|
|
100
77
|
|
|
101
|
-
|
|
78
|
+
- Tag the story `interaction` so it runs in `--type=interaction`.
|
|
79
|
+
- Dialogs, popovers and toasts render into `document.body`; use `within(canvasElement.ownerDocument.body)`.
|
|
80
|
+
- Assert outcomes (role, accessible name, focus, text), not CSS classes.
|
|
81
|
+
- To re-render a story when an arg changes (keyed state), key the component on that prop.
|
|
102
82
|
|
|
103
|
-
|
|
83
|
+
## Accessibility in stories
|
|
104
84
|
|
|
105
|
-
|
|
85
|
+
The a11y addon mode is `todo` (reports, does not fail) by default. `pnpm storybook:test --type=a11y` runs with `STORYBOOK_A11Y_TEST_MODE=error`. `STORYBOOK_DISABLE_A11Y=true` turns it off. Tag `skip-a11y` excludes a story from a11y runs. To make one file strict regardless, spread `{ a11y: { test: 'error' } }` into its `parameters` (see `src/components/checkout/storybook/checkout-strict-a11y-parameters.ts`). See `storefront-next:sfnext-accessibility`.
|
|
106
86
|
|
|
107
|
-
|
|
87
|
+
## Story coverage
|
|
108
88
|
|
|
109
|
-
|
|
110
|
-
export const ErrorState: Story = {
|
|
111
|
-
tags: ['skip-a11y'],
|
|
112
|
-
args: { error: 'Missing required field' },
|
|
113
|
-
};
|
|
114
|
-
```
|
|
89
|
+
Stories count toward component coverage when they match the component path (`cart/cart-content.tsx` maps to `cart/stories/cart-content.stories.tsx`; `index.tsx` maps to `stories/index.stories.tsx`). `pnpm storybook:test --type=snapshot --coverage` generates story tests and reports; details in `docs/README-STORY-COVERAGE.md`.
|
|
115
90
|
|
|
116
|
-
##
|
|
91
|
+
## Anti-patterns
|
|
117
92
|
|
|
118
|
-
|
|
93
|
+
- Recreating the component's data shape as a giant literal instead of passing a fixture.
|
|
94
|
+
- Promises in `args`.
|
|
95
|
+
- `vi.mock` of hooks inside a story.
|
|
96
|
+
- Separate Mobile/Tablet/Desktop stories (use the viewport toolbar).
|
|
97
|
+
- Novel top-level title groups.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Unit and route tests
|
|
2
|
+
|
|
3
|
+
## Environment (`vitest.config.ts`, `vitest.setup.ts`)
|
|
4
|
+
|
|
5
|
+
- jsdom, `globals: true`, `@/` alias, `testTimeout` 15s, Testing Library `asyncUtilTimeout` 10s, `pool: 'forks'` on Windows.
|
|
6
|
+
- Setup already: jest-dom matchers, `window.__APP_CONFIG__ = mockConfig`, i18next initialized with all locales (language `en-GB`), `vitest-localstorage-mock`, and a global mock of `@/hooks/use-analytics`.
|
|
7
|
+
- The global analytics mock means a missing `track*` call will not fail an ordinary test. To assert on tracking, call `vi.unmock('@/hooks/use-analytics')` in a `beforeEach` and provide your own spy implementation.
|
|
8
|
+
- Static assets and `virtual:action-hooks` are aliased to mocks.
|
|
9
|
+
|
|
10
|
+
## Helper inventory
|
|
11
|
+
|
|
12
|
+
`@/test-utils/*` (src/test-utils):
|
|
13
|
+
|
|
14
|
+
| Import | Provides |
|
|
15
|
+
|--------|----------|
|
|
16
|
+
| `@/test-utils/config` | `mockConfig`, `mockBuildConfig`, `mockSiteObject`, `mockAltSiteObject`, `mockLocale`, `getSitePrefix`, `ConfigWrapper`, `createConfigWrapper(overrides)` |
|
|
17
|
+
| `@/test-utils/context-provider` | `ConfigWrapper`, `AllProvidersWrapper` (config + site + store locator + UI targets; props `config`, `currency`) |
|
|
18
|
+
| `@/test-utils/auth` | `buildMockAccessToken`, `buildMockTokenResponse` |
|
|
19
|
+
| `@/test-utils/request-helpers` | `createFormDataRequest(url, method, data)` |
|
|
20
|
+
| `@/test-utils/wishlist` | `resetWishlistStore`, `seedWishlistStore` |
|
|
21
|
+
| `@/test-utils/page-designer-host-provider` | `PageDesignerHostProvider` |
|
|
22
|
+
|
|
23
|
+
`@/lib/test-utils` (src/lib/test-utils):
|
|
24
|
+
|
|
25
|
+
| Export | Use |
|
|
26
|
+
|--------|-----|
|
|
27
|
+
| `createTestContext(opts)` | A `RouterContextProvider` with auth, app config, i18n, site (locale/currency), maintenance and performance-timer contexts. Options: `authSession` (`null` for no session), `rejectAuth`/`authError`, `appConfig`, `locale` (default `en-GB`), `currency` (default `GBP`), `skipI18next`. |
|
|
28
|
+
| `createLoaderArgs(request, context, { params, pattern })` | Full `LoaderFunctionArgs`; pass `<Route.LoaderArgs>` as type parameter for typed loaders. |
|
|
29
|
+
| `createActionArgs(...)` | Same for actions. |
|
|
30
|
+
| `ROUTE_PATTERN` | Safe placeholder for `pattern`. |
|
|
31
|
+
| `expectStatus(result, 400)` | Assert status of a `data()` response (missing status counts as 200). |
|
|
32
|
+
|
|
33
|
+
Fixtures: `@/components/__mocks__` (and `@/components/__mocks__/<file>`), for example `basketWithOneItem`, `emptyBasket`, `masterProduct`, `mockStandardProductOrderable`, `mockCategories`.
|
|
34
|
+
|
|
35
|
+
## Loader/action pattern
|
|
36
|
+
|
|
37
|
+
Model new tests on `src/routes/resource.basket-products.test.ts` and the `_app.p.$.loader.test.ts` / `_app.cart.test.tsx` route tests:
|
|
38
|
+
|
|
39
|
+
1. `vi.mock('@/lib/api-clients.server', () => ({ createApiClients: vi.fn() }))` and return fake SCAPI clients per test.
|
|
40
|
+
2. Mock `@/middlewares/basket.server` (`getBasket`) or auth helpers if the route reads them.
|
|
41
|
+
3. Build context with `createTestContext`, args with `createLoaderArgs`/`createActionArgs`, call the exported `loader`/`action`.
|
|
42
|
+
4. Assert the returned object, thrown `Response`, or `expectStatus`.
|
|
43
|
+
5. For routes exporting `shouldRevalidate`, call it directly (see `docs/README-REVALIDATION.md`).
|
|
44
|
+
|
|
45
|
+
Use `createFormDataRequest` for action input.
|
|
46
|
+
|
|
47
|
+
## MSW
|
|
48
|
+
|
|
49
|
+
`msw` is a dev dependency. For HTTP-level tests use `setupServer` from `msw/node` and `http`/`HttpResponse` from `msw` (example: `src/components/checkout/checkout-flow.test.tsx`). Start the server in `beforeAll`, `resetHandlers` in `afterEach`, `close` in `afterAll`.
|
|
50
|
+
|
|
51
|
+
## Hooks and components
|
|
52
|
+
|
|
53
|
+
- Hooks: `renderHook(() => useX(), { wrapper: ConfigWrapper })` with the wrapper from `@/test-utils/config`.
|
|
54
|
+
- Components needing site/config/UI targets: `render(ui, { wrapper: AllProvidersWrapper })`.
|
|
55
|
+
- Component tests that mock `react-router` must provide every export the component tree uses.
|
|
56
|
+
- Prefer `userEvent` from `@testing-library/user-event` over `fireEvent`, and role-based queries.
|
|
57
|
+
|
|
58
|
+
## i18n in tests
|
|
59
|
+
|
|
60
|
+
See `storefront-next:sfnext-i18n`: i18next is initialized globally; use `createTestContext({ locale })` for loaders.
|