@empline/preflight 1.1.11 → 1.1.13
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/dist/checks/consolidated/auth-storage-state.d.ts +3 -0
- package/dist/checks/consolidated/auth-storage-state.d.ts.map +1 -0
- package/dist/checks/consolidated/auth-storage-state.js +146 -0
- package/dist/checks/consolidated/auth-storage-state.js.map +1 -0
- package/dist/checks/consolidated/business.d.ts +50 -0
- package/dist/checks/consolidated/business.d.ts.map +1 -0
- package/dist/checks/consolidated/business.js +252 -0
- package/dist/checks/consolidated/business.js.map +1 -0
- package/dist/checks/consolidated/caching-strategy.d.ts +104 -0
- package/dist/checks/consolidated/caching-strategy.d.ts.map +1 -0
- package/dist/checks/consolidated/caching-strategy.js +725 -0
- package/dist/checks/consolidated/caching-strategy.js.map +1 -0
- package/dist/checks/consolidated/code-quality.d.ts +83 -0
- package/dist/checks/consolidated/code-quality.d.ts.map +1 -0
- package/dist/checks/consolidated/code-quality.js +445 -0
- package/dist/checks/consolidated/code-quality.js.map +1 -0
- package/dist/checks/consolidated/console-statements.d.ts +32 -0
- package/dist/checks/consolidated/console-statements.d.ts.map +1 -0
- package/dist/checks/consolidated/console-statements.js +304 -0
- package/dist/checks/consolidated/console-statements.js.map +1 -0
- package/dist/checks/consolidated/css-advanced-validation.d.ts +24 -0
- package/dist/checks/consolidated/css-advanced-validation.d.ts.map +1 -0
- package/dist/checks/consolidated/css-advanced-validation.js +415 -0
- package/dist/checks/consolidated/css-advanced-validation.js.map +1 -0
- package/dist/checks/consolidated/css-organization.d.ts +14 -0
- package/dist/checks/consolidated/css-organization.d.ts.map +1 -0
- package/dist/checks/consolidated/css-organization.js +432 -0
- package/dist/checks/consolidated/css-organization.js.map +1 -0
- package/dist/checks/consolidated/css-runtime-validation.d.ts +22 -0
- package/dist/checks/consolidated/css-runtime-validation.d.ts.map +1 -0
- package/dist/checks/consolidated/css-runtime-validation.js +330 -0
- package/dist/checks/consolidated/css-runtime-validation.js.map +1 -0
- package/dist/checks/consolidated/css-variable-validation.d.ts +17 -0
- package/dist/checks/consolidated/css-variable-validation.d.ts.map +1 -0
- package/dist/checks/consolidated/css-variable-validation.js +412 -0
- package/dist/checks/consolidated/css-variable-validation.js.map +1 -0
- package/dist/checks/consolidated/dark-mode-consistency.d.ts +23 -0
- package/dist/checks/consolidated/dark-mode-consistency.d.ts.map +1 -0
- package/dist/checks/consolidated/dark-mode-consistency.js +291 -0
- package/dist/checks/consolidated/dark-mode-consistency.js.map +1 -0
- package/dist/checks/consolidated/database.d.ts +95 -0
- package/dist/checks/consolidated/database.d.ts.map +1 -0
- package/dist/checks/consolidated/database.js +427 -0
- package/dist/checks/consolidated/database.js.map +1 -0
- package/dist/checks/consolidated/e2e-checks.d.ts +52 -0
- package/dist/checks/consolidated/e2e-checks.d.ts.map +1 -0
- package/dist/checks/consolidated/e2e-checks.js +157 -0
- package/dist/checks/consolidated/e2e-checks.js.map +1 -0
- package/dist/checks/consolidated/e2e-regression-coverage.d.ts +14 -0
- package/dist/checks/consolidated/e2e-regression-coverage.d.ts.map +1 -0
- package/dist/checks/consolidated/e2e-regression-coverage.js +151 -0
- package/dist/checks/consolidated/e2e-regression-coverage.js.map +1 -0
- package/dist/checks/consolidated/e2e-validation.d.ts +137 -0
- package/dist/checks/consolidated/e2e-validation.d.ts.map +1 -0
- package/dist/checks/consolidated/e2e-validation.js +1001 -0
- package/dist/checks/consolidated/e2e-validation.js.map +1 -0
- package/dist/checks/consolidated/enterprise-baseline.d.ts +9 -0
- package/dist/checks/consolidated/enterprise-baseline.d.ts.map +1 -0
- package/dist/checks/consolidated/enterprise-baseline.js +277 -0
- package/dist/checks/consolidated/enterprise-baseline.js.map +1 -0
- package/dist/checks/consolidated/generate-pageload-config.d.ts +6 -0
- package/dist/checks/consolidated/generate-pageload-config.d.ts.map +1 -0
- package/dist/checks/consolidated/generate-pageload-config.js +161 -0
- package/dist/checks/consolidated/generate-pageload-config.js.map +1 -0
- package/dist/checks/consolidated/hardened-checks.d.ts +276 -0
- package/dist/checks/consolidated/hardened-checks.d.ts.map +1 -0
- package/dist/checks/consolidated/hardened-checks.js +3056 -0
- package/dist/checks/consolidated/hardened-checks.js.map +1 -0
- package/dist/checks/consolidated/homepage-ux.d.ts +12 -0
- package/dist/checks/consolidated/homepage-ux.d.ts.map +1 -0
- package/dist/checks/consolidated/homepage-ux.js +242 -0
- package/dist/checks/consolidated/homepage-ux.js.map +1 -0
- package/dist/checks/consolidated/images.d.ts +76 -0
- package/dist/checks/consolidated/images.d.ts.map +1 -0
- package/dist/checks/consolidated/images.js +311 -0
- package/dist/checks/consolidated/images.js.map +1 -0
- package/dist/checks/consolidated/import-cycles.d.ts +63 -0
- package/dist/checks/consolidated/import-cycles.d.ts.map +1 -0
- package/dist/checks/consolidated/import-cycles.js +291 -0
- package/dist/checks/consolidated/import-cycles.js.map +1 -0
- package/dist/checks/consolidated/imports.d.ts +112 -0
- package/dist/checks/consolidated/imports.d.ts.map +1 -0
- package/dist/checks/consolidated/imports.js +977 -0
- package/dist/checks/consolidated/imports.js.map +1 -0
- package/dist/checks/consolidated/inline-style-conflicts.d.ts +21 -0
- package/dist/checks/consolidated/inline-style-conflicts.d.ts.map +1 -0
- package/dist/checks/consolidated/inline-style-conflicts.js +300 -0
- package/dist/checks/consolidated/inline-style-conflicts.js.map +1 -0
- package/dist/checks/consolidated/lib-organization.d.ts +12 -0
- package/dist/checks/consolidated/lib-organization.d.ts.map +1 -0
- package/dist/checks/consolidated/lib-organization.js +419 -0
- package/dist/checks/consolidated/lib-organization.js.map +1 -0
- package/dist/checks/consolidated/n-plus-one.d.ts +63 -0
- package/dist/checks/consolidated/n-plus-one.d.ts.map +1 -0
- package/dist/checks/consolidated/n-plus-one.js +331 -0
- package/dist/checks/consolidated/n-plus-one.js.map +1 -0
- package/dist/checks/consolidated/nextjs.d.ts +51 -0
- package/dist/checks/consolidated/nextjs.d.ts.map +1 -0
- package/dist/checks/consolidated/nextjs.js +205 -0
- package/dist/checks/consolidated/nextjs.js.map +1 -0
- package/dist/checks/consolidated/organization.d.ts +54 -0
- package/dist/checks/consolidated/organization.d.ts.map +1 -0
- package/dist/checks/consolidated/organization.js +158 -0
- package/dist/checks/consolidated/organization.js.map +1 -0
- package/dist/checks/consolidated/pageload.d.ts +12 -0
- package/dist/checks/consolidated/pageload.d.ts.map +1 -0
- package/dist/checks/consolidated/pageload.js +138 -0
- package/dist/checks/consolidated/pageload.js.map +1 -0
- package/dist/checks/consolidated/performance.d.ts +112 -0
- package/dist/checks/consolidated/performance.d.ts.map +1 -0
- package/dist/checks/consolidated/performance.js +1546 -0
- package/dist/checks/consolidated/performance.js.map +1 -0
- package/dist/checks/consolidated/quality.d.ts +52 -0
- package/dist/checks/consolidated/quality.d.ts.map +1 -0
- package/dist/checks/consolidated/quality.js +253 -0
- package/dist/checks/consolidated/quality.js.map +1 -0
- package/dist/checks/consolidated/react.d.ts +48 -0
- package/dist/checks/consolidated/react.d.ts.map +1 -0
- package/dist/checks/consolidated/react.js +203 -0
- package/dist/checks/consolidated/react.js.map +1 -0
- package/dist/checks/consolidated/regression-hygiene.d.ts +17 -0
- package/dist/checks/consolidated/regression-hygiene.d.ts.map +1 -0
- package/dist/checks/consolidated/regression-hygiene.js +242 -0
- package/dist/checks/consolidated/regression-hygiene.js.map +1 -0
- package/dist/checks/consolidated/regression.d.ts +20 -0
- package/dist/checks/consolidated/regression.d.ts.map +1 -0
- package/dist/checks/consolidated/regression.js +121 -0
- package/dist/checks/consolidated/regression.js.map +1 -0
- package/dist/checks/consolidated/runtime.d.ts +53 -0
- package/dist/checks/consolidated/runtime.d.ts.map +1 -0
- package/dist/checks/consolidated/runtime.js +160 -0
- package/dist/checks/consolidated/runtime.js.map +1 -0
- package/dist/checks/consolidated/script-performance.d.ts +17 -0
- package/dist/checks/consolidated/script-performance.d.ts.map +1 -0
- package/dist/checks/consolidated/script-performance.js +137 -0
- package/dist/checks/consolidated/script-performance.js.map +1 -0
- package/dist/checks/consolidated/security.d.ts +78 -0
- package/dist/checks/consolidated/security.d.ts.map +1 -0
- package/dist/checks/consolidated/security.js +404 -0
- package/dist/checks/consolidated/security.js.map +1 -0
- package/dist/checks/consolidated/seo.d.ts +31 -0
- package/dist/checks/consolidated/seo.d.ts.map +1 -0
- package/dist/checks/consolidated/seo.js +1438 -0
- package/dist/checks/consolidated/seo.js.map +1 -0
- package/dist/checks/consolidated/sx-prop-deprecation.d.ts +22 -0
- package/dist/checks/consolidated/sx-prop-deprecation.d.ts.map +1 -0
- package/dist/checks/consolidated/sx-prop-deprecation.js +280 -0
- package/dist/checks/consolidated/sx-prop-deprecation.js.map +1 -0
- package/dist/checks/consolidated/tailwind-class-validation.d.ts +25 -0
- package/dist/checks/consolidated/tailwind-class-validation.d.ts.map +1 -0
- package/dist/checks/consolidated/tailwind-class-validation.js +533 -0
- package/dist/checks/consolidated/tailwind-class-validation.js.map +1 -0
- package/dist/checks/consolidated/testing.d.ts +54 -0
- package/dist/checks/consolidated/testing.d.ts.map +1 -0
- package/dist/checks/consolidated/testing.js +163 -0
- package/dist/checks/consolidated/testing.js.map +1 -0
- package/dist/checks/consolidated/typescript.d.ts +3 -0
- package/dist/checks/consolidated/typescript.d.ts.map +1 -0
- package/dist/checks/consolidated/typescript.js +31 -0
- package/dist/checks/consolidated/typescript.js.map +1 -0
- package/dist/checks/consolidated/ui-accessibility-advanced.d.ts +104 -0
- package/dist/checks/consolidated/ui-accessibility-advanced.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-accessibility-advanced.js +689 -0
- package/dist/checks/consolidated/ui-accessibility-advanced.js.map +1 -0
- package/dist/checks/consolidated/ui-accessibility.d.ts +121 -0
- package/dist/checks/consolidated/ui-accessibility.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-accessibility.js +776 -0
- package/dist/checks/consolidated/ui-accessibility.js.map +1 -0
- package/dist/checks/consolidated/ui-advanced-spacing.d.ts +142 -0
- package/dist/checks/consolidated/ui-advanced-spacing.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-advanced-spacing.js +1220 -0
- package/dist/checks/consolidated/ui-advanced-spacing.js.map +1 -0
- package/dist/checks/consolidated/ui-animation-duration.d.ts +108 -0
- package/dist/checks/consolidated/ui-animation-duration.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-animation-duration.js +531 -0
- package/dist/checks/consolidated/ui-animation-duration.js.map +1 -0
- package/dist/checks/consolidated/ui-border-radius.d.ts +90 -0
- package/dist/checks/consolidated/ui-border-radius.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-border-radius.js +519 -0
- package/dist/checks/consolidated/ui-border-radius.js.map +1 -0
- package/dist/checks/consolidated/ui-buttons.d.ts +32 -0
- package/dist/checks/consolidated/ui-buttons.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-buttons.js +481 -0
- package/dist/checks/consolidated/ui-buttons.js.map +1 -0
- package/dist/checks/consolidated/ui-cards.d.ts +29 -0
- package/dist/checks/consolidated/ui-cards.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-cards.js +504 -0
- package/dist/checks/consolidated/ui-cards.js.map +1 -0
- package/dist/checks/consolidated/ui-checks.d.ts +48 -0
- package/dist/checks/consolidated/ui-checks.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-checks.js +264 -0
- package/dist/checks/consolidated/ui-checks.js.map +1 -0
- package/dist/checks/consolidated/ui-cleanup.d.ts +81 -0
- package/dist/checks/consolidated/ui-cleanup.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-cleanup.js +650 -0
- package/dist/checks/consolidated/ui-cleanup.js.map +1 -0
- package/dist/checks/consolidated/ui-components.d.ts +255 -0
- package/dist/checks/consolidated/ui-components.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-components.js +2008 -0
- package/dist/checks/consolidated/ui-components.js.map +1 -0
- package/dist/checks/consolidated/ui-consistency-advanced.d.ts +130 -0
- package/dist/checks/consolidated/ui-consistency-advanced.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-consistency-advanced.js +982 -0
- package/dist/checks/consolidated/ui-consistency-advanced.js.map +1 -0
- package/dist/checks/consolidated/ui-consistency-comprehensive.d.ts +30 -0
- package/dist/checks/consolidated/ui-consistency-comprehensive.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-consistency-comprehensive.js +1018 -0
- package/dist/checks/consolidated/ui-consistency-comprehensive.js.map +1 -0
- package/dist/checks/consolidated/ui-consistency-extended.d.ts +26 -0
- package/dist/checks/consolidated/ui-consistency-extended.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-consistency-extended.js +606 -0
- package/dist/checks/consolidated/ui-consistency-extended.js.map +1 -0
- package/dist/checks/consolidated/ui-data-display.d.ts +103 -0
- package/dist/checks/consolidated/ui-data-display.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-data-display.js +740 -0
- package/dist/checks/consolidated/ui-data-display.js.map +1 -0
- package/dist/checks/consolidated/ui-deprecated.d.ts +22 -0
- package/dist/checks/consolidated/ui-deprecated.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-deprecated.js +336 -0
- package/dist/checks/consolidated/ui-deprecated.js.map +1 -0
- package/dist/checks/consolidated/ui-empty-null-states.d.ts +90 -0
- package/dist/checks/consolidated/ui-empty-null-states.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-empty-null-states.js +511 -0
- package/dist/checks/consolidated/ui-empty-null-states.js.map +1 -0
- package/dist/checks/consolidated/ui-error-states.d.ts +99 -0
- package/dist/checks/consolidated/ui-error-states.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-error-states.js +694 -0
- package/dist/checks/consolidated/ui-error-states.js.map +1 -0
- package/dist/checks/consolidated/ui-feedback-confirmations.d.ts +90 -0
- package/dist/checks/consolidated/ui-feedback-confirmations.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-feedback-confirmations.js +596 -0
- package/dist/checks/consolidated/ui-feedback-confirmations.js.map +1 -0
- package/dist/checks/consolidated/ui-forms.d.ts +32 -0
- package/dist/checks/consolidated/ui-forms.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-forms.js +568 -0
- package/dist/checks/consolidated/ui-forms.js.map +1 -0
- package/dist/checks/consolidated/ui-gradient-shadow.d.ts +90 -0
- package/dist/checks/consolidated/ui-gradient-shadow.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-gradient-shadow.js +568 -0
- package/dist/checks/consolidated/ui-gradient-shadow.js.map +1 -0
- package/dist/checks/consolidated/ui-grid-responsive.d.ts +27 -0
- package/dist/checks/consolidated/ui-grid-responsive.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-grid-responsive.js +441 -0
- package/dist/checks/consolidated/ui-grid-responsive.js.map +1 -0
- package/dist/checks/consolidated/ui-icon-size-tokens.d.ts +104 -0
- package/dist/checks/consolidated/ui-icon-size-tokens.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-icon-size-tokens.js +514 -0
- package/dist/checks/consolidated/ui-icon-size-tokens.js.map +1 -0
- package/dist/checks/consolidated/ui-iconography.d.ts +90 -0
- package/dist/checks/consolidated/ui-iconography.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-iconography.js +565 -0
- package/dist/checks/consolidated/ui-iconography.js.map +1 -0
- package/dist/checks/consolidated/ui-interactive-states.d.ts +240 -0
- package/dist/checks/consolidated/ui-interactive-states.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-interactive-states.js +2474 -0
- package/dist/checks/consolidated/ui-interactive-states.js.map +1 -0
- package/dist/checks/consolidated/ui-layout.d.ts +256 -0
- package/dist/checks/consolidated/ui-layout.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-layout.js +1371 -0
- package/dist/checks/consolidated/ui-layout.js.map +1 -0
- package/dist/checks/consolidated/ui-loading-skeletons.d.ts +11 -0
- package/dist/checks/consolidated/ui-loading-skeletons.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-loading-skeletons.js +145 -0
- package/dist/checks/consolidated/ui-loading-skeletons.js.map +1 -0
- package/dist/checks/consolidated/ui-loading-state-skeletons.d.ts +9 -0
- package/dist/checks/consolidated/ui-loading-state-skeletons.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-loading-state-skeletons.js +125 -0
- package/dist/checks/consolidated/ui-loading-state-skeletons.js.map +1 -0
- package/dist/checks/consolidated/ui-media.d.ts +74 -0
- package/dist/checks/consolidated/ui-media.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-media.js +408 -0
- package/dist/checks/consolidated/ui-media.js.map +1 -0
- package/dist/checks/consolidated/ui-micro-interactions.d.ts +107 -0
- package/dist/checks/consolidated/ui-micro-interactions.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-micro-interactions.js +825 -0
- package/dist/checks/consolidated/ui-micro-interactions.js.map +1 -0
- package/dist/checks/consolidated/ui-microcopy-consistency.d.ts +114 -0
- package/dist/checks/consolidated/ui-microcopy-consistency.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-microcopy-consistency.js +566 -0
- package/dist/checks/consolidated/ui-microcopy-consistency.js.map +1 -0
- package/dist/checks/consolidated/ui-mobile-ux.d.ts +251 -0
- package/dist/checks/consolidated/ui-mobile-ux.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-mobile-ux.js +2212 -0
- package/dist/checks/consolidated/ui-mobile-ux.js.map +1 -0
- package/dist/checks/consolidated/ui-motion-accessibility.d.ts +93 -0
- package/dist/checks/consolidated/ui-motion-accessibility.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-motion-accessibility.js +450 -0
- package/dist/checks/consolidated/ui-motion-accessibility.js.map +1 -0
- package/dist/checks/consolidated/ui-navigation.d.ts +85 -0
- package/dist/checks/consolidated/ui-navigation.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-navigation.js +673 -0
- package/dist/checks/consolidated/ui-navigation.js.map +1 -0
- package/dist/checks/consolidated/ui-patterns.d.ts +174 -0
- package/dist/checks/consolidated/ui-patterns.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-patterns.js +1532 -0
- package/dist/checks/consolidated/ui-patterns.js.map +1 -0
- package/dist/checks/consolidated/ui-responsive.d.ts +89 -0
- package/dist/checks/consolidated/ui-responsive.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-responsive.js +588 -0
- package/dist/checks/consolidated/ui-responsive.js.map +1 -0
- package/dist/checks/consolidated/ui-spacing-standards.d.ts +43 -0
- package/dist/checks/consolidated/ui-spacing-standards.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-spacing-standards.js +874 -0
- package/dist/checks/consolidated/ui-spacing-standards.js.map +1 -0
- package/dist/checks/consolidated/ui-spacing.d.ts +751 -0
- package/dist/checks/consolidated/ui-spacing.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-spacing.js +4996 -0
- package/dist/checks/consolidated/ui-spacing.js.map +1 -0
- package/dist/checks/consolidated/ui-standards-auto-fixer.d.ts +70 -0
- package/dist/checks/consolidated/ui-standards-auto-fixer.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-standards-auto-fixer.js +429 -0
- package/dist/checks/consolidated/ui-standards-auto-fixer.js.map +1 -0
- package/dist/checks/consolidated/ui-standards-enforcement.d.ts +100 -0
- package/dist/checks/consolidated/ui-standards-enforcement.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-standards-enforcement.js +935 -0
- package/dist/checks/consolidated/ui-standards-enforcement.js.map +1 -0
- package/dist/checks/consolidated/ui-state-consistency.d.ts +90 -0
- package/dist/checks/consolidated/ui-state-consistency.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-state-consistency.js +659 -0
- package/dist/checks/consolidated/ui-state-consistency.js.map +1 -0
- package/dist/checks/consolidated/ui-style-validation.d.ts +74 -0
- package/dist/checks/consolidated/ui-style-validation.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-style-validation.js +403 -0
- package/dist/checks/consolidated/ui-style-validation.js.map +1 -0
- package/dist/checks/consolidated/ui-tokens.d.ts +110 -0
- package/dist/checks/consolidated/ui-tokens.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-tokens.js +990 -0
- package/dist/checks/consolidated/ui-tokens.js.map +1 -0
- package/dist/checks/consolidated/ui-typography.d.ts +77 -0
- package/dist/checks/consolidated/ui-typography.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-typography.js +416 -0
- package/dist/checks/consolidated/ui-typography.js.map +1 -0
- package/dist/checks/consolidated/ui-visual-hierarchy.d.ts +90 -0
- package/dist/checks/consolidated/ui-visual-hierarchy.d.ts.map +1 -0
- package/dist/checks/consolidated/ui-visual-hierarchy.js +562 -0
- package/dist/checks/consolidated/ui-visual-hierarchy.js.map +1 -0
- package/dist/checks/consolidated/woocommerce.d.ts +50 -0
- package/dist/checks/consolidated/woocommerce.d.ts.map +1 -0
- package/dist/checks/consolidated/woocommerce.js +198 -0
- package/dist/checks/consolidated/woocommerce.js.map +1 -0
- package/dist/checks/core/api-route-protection.d.ts +2 -0
- package/dist/checks/core/api-route-protection.d.ts.map +1 -0
- package/dist/checks/core/api-route-protection.js +101 -0
- package/dist/checks/core/api-route-protection.js.map +1 -0
- package/dist/checks/core/critical.d.ts +8 -0
- package/dist/checks/core/critical.d.ts.map +1 -0
- package/dist/checks/core/critical.js +200 -0
- package/dist/checks/core/critical.js.map +1 -0
- package/dist/checks/core/database.d.ts +8 -0
- package/dist/checks/core/database.d.ts.map +1 -0
- package/dist/checks/core/database.js +699 -0
- package/dist/checks/core/database.js.map +1 -0
- package/dist/checks/core/development.d.ts +8 -0
- package/dist/checks/core/development.d.ts.map +1 -0
- package/dist/checks/core/development.js +417 -0
- package/dist/checks/core/development.js.map +1 -0
- package/dist/checks/core/hydration-mismatch-check.d.ts +38 -0
- package/dist/checks/core/hydration-mismatch-check.d.ts.map +1 -0
- package/dist/checks/core/hydration-mismatch-check.js +411 -0
- package/dist/checks/core/hydration-mismatch-check.js.map +1 -0
- package/dist/checks/core/performance.d.ts +8 -0
- package/dist/checks/core/performance.d.ts.map +1 -0
- package/dist/checks/core/performance.js +474 -0
- package/dist/checks/core/performance.js.map +1 -0
- package/dist/checks/core/security.d.ts +8 -0
- package/dist/checks/core/security.d.ts.map +1 -0
- package/dist/checks/core/security.js +275 -0
- package/dist/checks/core/security.js.map +1 -0
- package/dist/checks/core/standardized-error-handling.d.ts +43 -0
- package/dist/checks/core/standardized-error-handling.d.ts.map +1 -0
- package/dist/checks/core/standardized-error-handling.js +384 -0
- package/dist/checks/core/standardized-error-handling.js.map +1 -0
- package/dist/checks/core/supercatch.d.ts +8 -0
- package/dist/checks/core/supercatch.d.ts.map +1 -0
- package/dist/checks/core/supercatch.js +750 -0
- package/dist/checks/core/supercatch.js.map +1 -0
- package/dist/checks/core/suppression-check.d.ts +2 -0
- package/dist/checks/core/suppression-check.d.ts.map +1 -0
- package/dist/checks/core/suppression-check.js +129 -0
- package/dist/checks/core/suppression-check.js.map +1 -0
- package/dist/checks/core/ui-quality.d.ts +8 -0
- package/dist/checks/core/ui-quality.d.ts.map +1 -0
- package/dist/checks/core/ui-quality.js +1736 -0
- package/dist/checks/core/ui-quality.js.map +1 -0
- package/dist/checks/core/unused-assets-check.d.ts +2 -0
- package/dist/checks/core/unused-assets-check.d.ts.map +1 -0
- package/dist/checks/core/unused-assets-check.js +112 -0
- package/dist/checks/core/unused-assets-check.js.map +1 -0
- package/dist/checks/core/use-status-ssr-safety.d.ts +34 -0
- package/dist/checks/core/use-status-ssr-safety.d.ts.map +1 -0
- package/dist/checks/core/use-status-ssr-safety.js +283 -0
- package/dist/checks/core/use-status-ssr-safety.js.map +1 -0
- package/dist/checks/email/email-flow-validation.d.ts +23 -0
- package/dist/checks/email/email-flow-validation.d.ts.map +1 -0
- package/dist/checks/email/email-flow-validation.js +468 -0
- package/dist/checks/email/email-flow-validation.js.map +1 -0
- package/dist/checks/email/email-template-db-verification.d.ts +20 -0
- package/dist/checks/email/email-template-db-verification.d.ts.map +1 -0
- package/dist/checks/email/email-template-db-verification.js +46 -0
- package/dist/checks/email/email-template-db-verification.js.map +1 -0
- package/dist/checks/email/email-template-validation.d.ts +24 -0
- package/dist/checks/email/email-template-validation.d.ts.map +1 -0
- package/dist/checks/email/email-template-validation.js +688 -0
- package/dist/checks/email/email-template-validation.js.map +1 -0
- package/dist/checks/jsx/comment-placement.d.ts +45 -0
- package/dist/checks/jsx/comment-placement.d.ts.map +1 -0
- package/dist/checks/jsx/comment-placement.js +316 -0
- package/dist/checks/jsx/comment-placement.js.map +1 -0
- package/dist/checks/specialized/admin-layout-check.d.ts +19 -0
- package/dist/checks/specialized/admin-layout-check.d.ts.map +1 -0
- package/dist/checks/specialized/admin-layout-check.js +166 -0
- package/dist/checks/specialized/admin-layout-check.js.map +1 -0
- package/dist/checks/specialized/client-server-separation.d.ts +14 -0
- package/dist/checks/specialized/client-server-separation.d.ts.map +1 -0
- package/dist/checks/specialized/client-server-separation.js +197 -0
- package/dist/checks/specialized/client-server-separation.js.map +1 -0
- package/dist/checks/specialized/cost-optimization.d.ts +18 -0
- package/dist/checks/specialized/cost-optimization.d.ts.map +1 -0
- package/dist/checks/specialized/cost-optimization.js +78 -0
- package/dist/checks/specialized/cost-optimization.js.map +1 -0
- package/dist/checks/specialized/database-migration-sync.d.ts +21 -0
- package/dist/checks/specialized/database-migration-sync.d.ts.map +1 -0
- package/dist/checks/specialized/database-migration-sync.js +150 -0
- package/dist/checks/specialized/database-migration-sync.js.map +1 -0
- package/dist/checks/specialized/database-model-validation.d.ts +15 -0
- package/dist/checks/specialized/database-model-validation.d.ts.map +1 -0
- package/dist/checks/specialized/database-model-validation.js +35 -0
- package/dist/checks/specialized/database-model-validation.js.map +1 -0
- package/dist/checks/specialized/database-schema-migrations-diff.d.ts +27 -0
- package/dist/checks/specialized/database-schema-migrations-diff.d.ts.map +1 -0
- package/dist/checks/specialized/database-schema-migrations-diff.js +177 -0
- package/dist/checks/specialized/database-schema-migrations-diff.js.map +1 -0
- package/dist/checks/specialized/database-schema-sync.d.ts +23 -0
- package/dist/checks/specialized/database-schema-sync.d.ts.map +1 -0
- package/dist/checks/specialized/database-schema-sync.js +77 -0
- package/dist/checks/specialized/database-schema-sync.js.map +1 -0
- package/dist/checks/specialized/decimal-serialization.d.ts +24 -0
- package/dist/checks/specialized/decimal-serialization.d.ts.map +1 -0
- package/dist/checks/specialized/decimal-serialization.js +400 -0
- package/dist/checks/specialized/decimal-serialization.js.map +1 -0
- package/dist/checks/specialized/detect-router-issues.d.ts +14 -0
- package/dist/checks/specialized/detect-router-issues.d.ts.map +1 -0
- package/dist/checks/specialized/detect-router-issues.js +96 -0
- package/dist/checks/specialized/detect-router-issues.js.map +1 -0
- package/dist/checks/specialized/enum-validation.d.ts +15 -0
- package/dist/checks/specialized/enum-validation.d.ts.map +1 -0
- package/dist/checks/specialized/enum-validation.js +35 -0
- package/dist/checks/specialized/enum-validation.js.map +1 -0
- package/dist/checks/specialized/hash-collision.d.ts +18 -0
- package/dist/checks/specialized/hash-collision.d.ts.map +1 -0
- package/dist/checks/specialized/hash-collision.js +78 -0
- package/dist/checks/specialized/hash-collision.js.map +1 -0
- package/dist/checks/specialized/id-generation-enforcement.d.ts +16 -0
- package/dist/checks/specialized/id-generation-enforcement.d.ts.map +1 -0
- package/dist/checks/specialized/id-generation-enforcement.js +307 -0
- package/dist/checks/specialized/id-generation-enforcement.js.map +1 -0
- package/dist/checks/specialized/image-data-integrity.d.ts +15 -0
- package/dist/checks/specialized/image-data-integrity.d.ts.map +1 -0
- package/dist/checks/specialized/image-data-integrity.js +79 -0
- package/dist/checks/specialized/image-data-integrity.js.map +1 -0
- package/dist/checks/specialized/image-health.d.ts +14 -0
- package/dist/checks/specialized/image-health.d.ts.map +1 -0
- package/dist/checks/specialized/image-health.js +122 -0
- package/dist/checks/specialized/image-health.js.map +1 -0
- package/dist/checks/specialized/image-metadata-validation.d.ts +14 -0
- package/dist/checks/specialized/image-metadata-validation.d.ts.map +1 -0
- package/dist/checks/specialized/image-metadata-validation.js +95 -0
- package/dist/checks/specialized/image-metadata-validation.js.map +1 -0
- package/dist/checks/specialized/image-optimization.d.ts +16 -0
- package/dist/checks/specialized/image-optimization.d.ts.map +1 -0
- package/dist/checks/specialized/image-optimization.js +86 -0
- package/dist/checks/specialized/image-optimization.js.map +1 -0
- package/dist/checks/specialized/invalid-module-imports.d.ts +24 -0
- package/dist/checks/specialized/invalid-module-imports.d.ts.map +1 -0
- package/dist/checks/specialized/invalid-module-imports.js +209 -0
- package/dist/checks/specialized/invalid-module-imports.js.map +1 -0
- package/dist/checks/specialized/lint-validation.d.ts +26 -0
- package/dist/checks/specialized/lint-validation.d.ts.map +1 -0
- package/dist/checks/specialized/lint-validation.js +193 -0
- package/dist/checks/specialized/lint-validation.js.map +1 -0
- package/dist/checks/specialized/listing-workflow.d.ts +19 -0
- package/dist/checks/specialized/listing-workflow.d.ts.map +1 -0
- package/dist/checks/specialized/listing-workflow.js +89 -0
- package/dist/checks/specialized/listing-workflow.js.map +1 -0
- package/dist/checks/specialized/mui-imports-validation.d.ts +18 -0
- package/dist/checks/specialized/mui-imports-validation.d.ts.map +1 -0
- package/dist/checks/specialized/mui-imports-validation.js +134 -0
- package/dist/checks/specialized/mui-imports-validation.js.map +1 -0
- package/dist/checks/specialized/nextauth-v5-compliance.d.ts +16 -0
- package/dist/checks/specialized/nextauth-v5-compliance.d.ts.map +1 -0
- package/dist/checks/specialized/nextauth-v5-compliance.js +164 -0
- package/dist/checks/specialized/nextauth-v5-compliance.js.map +1 -0
- package/dist/checks/specialized/nextjs-params-check.d.ts +14 -0
- package/dist/checks/specialized/nextjs-params-check.d.ts.map +1 -0
- package/dist/checks/specialized/nextjs-params-check.js +140 -0
- package/dist/checks/specialized/nextjs-params-check.js.map +1 -0
- package/dist/checks/specialized/no-legacy-catalog-aliases-validation.d.ts +16 -0
- package/dist/checks/specialized/no-legacy-catalog-aliases-validation.d.ts.map +1 -0
- package/dist/checks/specialized/no-legacy-catalog-aliases-validation.js +36 -0
- package/dist/checks/specialized/no-legacy-catalog-aliases-validation.js.map +1 -0
- package/dist/checks/specialized/no-wata-cardgraded-validation.d.ts +22 -0
- package/dist/checks/specialized/no-wata-cardgraded-validation.d.ts.map +1 -0
- package/dist/checks/specialized/no-wata-cardgraded-validation.js +97 -0
- package/dist/checks/specialized/no-wata-cardgraded-validation.js.map +1 -0
- package/dist/checks/specialized/parameter-consistency-check.d.ts +20 -0
- package/dist/checks/specialized/parameter-consistency-check.d.ts.map +1 -0
- package/dist/checks/specialized/parameter-consistency-check.js +115 -0
- package/dist/checks/specialized/parameter-consistency-check.js.map +1 -0
- package/dist/checks/specialized/prisma-field-names-validation.d.ts +15 -0
- package/dist/checks/specialized/prisma-field-names-validation.d.ts.map +1 -0
- package/dist/checks/specialized/prisma-field-names-validation.js +35 -0
- package/dist/checks/specialized/prisma-field-names-validation.js.map +1 -0
- package/dist/checks/specialized/prisma-null-syntax.d.ts +34 -0
- package/dist/checks/specialized/prisma-null-syntax.d.ts.map +1 -0
- package/dist/checks/specialized/prisma-null-syntax.js +330 -0
- package/dist/checks/specialized/prisma-null-syntax.js.map +1 -0
- package/dist/checks/specialized/prisma-query-validation.d.ts +15 -0
- package/dist/checks/specialized/prisma-query-validation.d.ts.map +1 -0
- package/dist/checks/specialized/prisma-query-validation.js +35 -0
- package/dist/checks/specialized/prisma-query-validation.js.map +1 -0
- package/dist/checks/specialized/product-type-validation.d.ts +17 -0
- package/dist/checks/specialized/product-type-validation.d.ts.map +1 -0
- package/dist/checks/specialized/product-type-validation.js +129 -0
- package/dist/checks/specialized/product-type-validation.js.map +1 -0
- package/dist/checks/specialized/responsive-image-validation.d.ts +14 -0
- package/dist/checks/specialized/responsive-image-validation.d.ts.map +1 -0
- package/dist/checks/specialized/responsive-image-validation.js +101 -0
- package/dist/checks/specialized/responsive-image-validation.js.map +1 -0
- package/dist/checks/specialized/root-cleanliness.d.ts +21 -0
- package/dist/checks/specialized/root-cleanliness.d.ts.map +1 -0
- package/dist/checks/specialized/root-cleanliness.js +251 -0
- package/dist/checks/specialized/root-cleanliness.js.map +1 -0
- package/dist/checks/specialized/rotation-detection-validation.d.ts +16 -0
- package/dist/checks/specialized/rotation-detection-validation.d.ts.map +1 -0
- package/dist/checks/specialized/rotation-detection-validation.js +113 -0
- package/dist/checks/specialized/rotation-detection-validation.js.map +1 -0
- package/dist/checks/specialized/script-organization.d.ts +17 -0
- package/dist/checks/specialized/script-organization.d.ts.map +1 -0
- package/dist/checks/specialized/script-organization.js +487 -0
- package/dist/checks/specialized/script-organization.js.map +1 -0
- package/dist/checks/specialized/shared-components-migration.d.ts +137 -0
- package/dist/checks/specialized/shared-components-migration.d.ts.map +1 -0
- package/dist/checks/specialized/shared-components-migration.js +1288 -0
- package/dist/checks/specialized/shared-components-migration.js.map +1 -0
- package/dist/checks/specialized/store-specialties-normalization.d.ts +10 -0
- package/dist/checks/specialized/store-specialties-normalization.d.ts.map +1 -0
- package/dist/checks/specialized/store-specialties-normalization.js +126 -0
- package/dist/checks/specialized/store-specialties-normalization.js.map +1 -0
- package/dist/checks/specialized/two-stage-trim-validation.d.ts +16 -0
- package/dist/checks/specialized/two-stage-trim-validation.d.ts.map +1 -0
- package/dist/checks/specialized/two-stage-trim-validation.js +115 -0
- package/dist/checks/specialized/two-stage-trim-validation.js.map +1 -0
- package/dist/checks/specialized/underscore-variable-audit.d.ts +26 -0
- package/dist/checks/specialized/underscore-variable-audit.d.ts.map +1 -0
- package/dist/checks/specialized/underscore-variable-audit.js +219 -0
- package/dist/checks/specialized/underscore-variable-audit.js.map +1 -0
- package/dist/checks/specialized/unified-badge-consistency.d.ts +16 -0
- package/dist/checks/specialized/unified-badge-consistency.d.ts.map +1 -0
- package/dist/checks/specialized/unified-badge-consistency.js +284 -0
- package/dist/checks/specialized/unified-badge-consistency.js.map +1 -0
- package/dist/checks/specialized/validate-integration-enums.d.ts +15 -0
- package/dist/checks/specialized/validate-integration-enums.d.ts.map +1 -0
- package/dist/checks/specialized/validate-integration-enums.js +131 -0
- package/dist/checks/specialized/validate-integration-enums.js.map +1 -0
- package/dist/checks/testing/action-regression.d.ts +23 -0
- package/dist/checks/testing/action-regression.d.ts.map +1 -0
- package/dist/checks/testing/action-regression.js +192 -0
- package/dist/checks/testing/action-regression.js.map +1 -0
- package/dist/checks/testing/critical-api-coverage.d.ts +21 -0
- package/dist/checks/testing/critical-api-coverage.d.ts.map +1 -0
- package/dist/checks/testing/critical-api-coverage.js +158 -0
- package/dist/checks/testing/critical-api-coverage.js.map +1 -0
- package/dist/checks/testing/data-entry-regression-required.d.ts +24 -0
- package/dist/checks/testing/data-entry-regression-required.d.ts.map +1 -0
- package/dist/checks/testing/data-entry-regression-required.js +378 -0
- package/dist/checks/testing/data-entry-regression-required.js.map +1 -0
- package/dist/checks/testing/e2e-best-practices.d.ts +24 -0
- package/dist/checks/testing/e2e-best-practices.d.ts.map +1 -0
- package/dist/checks/testing/e2e-best-practices.js +791 -0
- package/dist/checks/testing/e2e-best-practices.js.map +1 -0
- package/dist/checks/testing/e2e-flake-patterns.d.ts +26 -0
- package/dist/checks/testing/e2e-flake-patterns.d.ts.map +1 -0
- package/dist/checks/testing/e2e-flake-patterns.js +305 -0
- package/dist/checks/testing/e2e-flake-patterns.js.map +1 -0
- package/dist/checks/testing/e2e-redundant-visibility-checks.d.ts +25 -0
- package/dist/checks/testing/e2e-redundant-visibility-checks.d.ts.map +1 -0
- package/dist/checks/testing/e2e-redundant-visibility-checks.js +613 -0
- package/dist/checks/testing/e2e-redundant-visibility-checks.js.map +1 -0
- package/dist/checks/testing/e2e-slow-tests.d.ts +9 -0
- package/dist/checks/testing/e2e-slow-tests.d.ts.map +1 -0
- package/dist/checks/testing/e2e-slow-tests.js +142 -0
- package/dist/checks/testing/e2e-slow-tests.js.map +1 -0
- package/dist/checks/testing/e2e-timeouts.d.ts +9 -0
- package/dist/checks/testing/e2e-timeouts.d.ts.map +1 -0
- package/dist/checks/testing/e2e-timeouts.js +82 -0
- package/dist/checks/testing/e2e-timeouts.js.map +1 -0
- package/dist/checks/testing/integration-e2e-depth.d.ts +20 -0
- package/dist/checks/testing/integration-e2e-depth.d.ts.map +1 -0
- package/dist/checks/testing/integration-e2e-depth.js +575 -0
- package/dist/checks/testing/integration-e2e-depth.js.map +1 -0
- package/dist/checks/testing/playwright-feature-coverage-gaps.d.ts +31 -0
- package/dist/checks/testing/playwright-feature-coverage-gaps.d.ts.map +1 -0
- package/dist/checks/testing/playwright-feature-coverage-gaps.js +1582 -0
- package/dist/checks/testing/playwright-feature-coverage-gaps.js.map +1 -0
- package/dist/checks/testing/playwright-mock-inventory.d.ts +24 -0
- package/dist/checks/testing/playwright-mock-inventory.d.ts.map +1 -0
- package/dist/checks/testing/playwright-mock-inventory.js +380 -0
- package/dist/checks/testing/playwright-mock-inventory.js.map +1 -0
- package/dist/checks/testing/test-coverage-threshold.d.ts +25 -0
- package/dist/checks/testing/test-coverage-threshold.d.ts.map +1 -0
- package/dist/checks/testing/test-coverage-threshold.js +166 -0
- package/dist/checks/testing/test-coverage-threshold.js.map +1 -0
- package/dist/checks/testing/test-flakiness-score.d.ts +27 -0
- package/dist/checks/testing/test-flakiness-score.d.ts.map +1 -0
- package/dist/checks/testing/test-flakiness-score.js +358 -0
- package/dist/checks/testing/test-flakiness-score.js.map +1 -0
- package/dist/checks/testing/test-patterns.d.ts +16 -0
- package/dist/checks/testing/test-patterns.d.ts.map +1 -0
- package/dist/checks/testing/test-patterns.js +156 -0
- package/dist/checks/testing/test-patterns.js.map +1 -0
- package/dist/checks/workflows/a-plus-rating-validation.d.ts +42 -0
- package/dist/checks/workflows/a-plus-rating-validation.d.ts.map +1 -0
- package/dist/checks/workflows/a-plus-rating-validation.js +527 -0
- package/dist/checks/workflows/a-plus-rating-validation.js.map +1 -0
- package/dist/checks/workflows/affected.d.ts +14 -0
- package/dist/checks/workflows/affected.d.ts.map +1 -0
- package/dist/checks/workflows/affected.js +126 -0
- package/dist/checks/workflows/affected.js.map +1 -0
- package/dist/checks/workflows/ai.d.ts +6 -0
- package/dist/checks/workflows/ai.d.ts.map +1 -0
- package/dist/checks/workflows/ai.js +42 -0
- package/dist/checks/workflows/ai.js.map +1 -0
- package/dist/checks/workflows/all.d.ts +31 -0
- package/dist/checks/workflows/all.d.ts.map +1 -0
- package/dist/checks/workflows/all.js +2688 -0
- package/dist/checks/workflows/all.js.map +1 -0
- package/dist/checks/workflows/commit.d.ts +19 -0
- package/dist/checks/workflows/commit.d.ts.map +1 -0
- package/dist/checks/workflows/commit.js +207 -0
- package/dist/checks/workflows/commit.js.map +1 -0
- package/dist/checks/workflows/critical.d.ts +9 -0
- package/dist/checks/workflows/critical.d.ts.map +1 -0
- package/dist/checks/workflows/critical.js +213 -0
- package/dist/checks/workflows/critical.js.map +1 -0
- package/dist/checks/workflows/database-id-validation.d.ts +9 -0
- package/dist/checks/workflows/database-id-validation.d.ts.map +1 -0
- package/dist/checks/workflows/database-id-validation.js +13 -0
- package/dist/checks/workflows/database-id-validation.js.map +1 -0
- package/dist/checks/workflows/deploy.d.ts +20 -0
- package/dist/checks/workflows/deploy.d.ts.map +1 -0
- package/dist/checks/workflows/deploy.js +107 -0
- package/dist/checks/workflows/deploy.js.map +1 -0
- package/dist/checks/workflows/deployment-readiness.d.ts +12 -0
- package/dist/checks/workflows/deployment-readiness.d.ts.map +1 -0
- package/dist/checks/workflows/deployment-readiness.js +403 -0
- package/dist/checks/workflows/deployment-readiness.js.map +1 -0
- package/dist/checks/workflows/dev.d.ts +19 -0
- package/dist/checks/workflows/dev.d.ts.map +1 -0
- package/dist/checks/workflows/dev.js +88 -0
- package/dist/checks/workflows/dev.js.map +1 -0
- package/dist/checks/workflows/development.d.ts +9 -0
- package/dist/checks/workflows/development.d.ts.map +1 -0
- package/dist/checks/workflows/development.js +65 -0
- package/dist/checks/workflows/development.js.map +1 -0
- package/dist/checks/workflows/enterprise.d.ts +10 -0
- package/dist/checks/workflows/enterprise.d.ts.map +1 -0
- package/dist/checks/workflows/enterprise.js +359 -0
- package/dist/checks/workflows/enterprise.js.map +1 -0
- package/dist/checks/workflows/images.d.ts +6 -0
- package/dist/checks/workflows/images.d.ts.map +1 -0
- package/dist/checks/workflows/images.js +58 -0
- package/dist/checks/workflows/images.js.map +1 -0
- package/dist/checks/workflows/naming.d.ts +19 -0
- package/dist/checks/workflows/naming.d.ts.map +1 -0
- package/dist/checks/workflows/naming.js +42 -0
- package/dist/checks/workflows/naming.js.map +1 -0
- package/dist/checks/workflows/performance.d.ts +8 -0
- package/dist/checks/workflows/performance.d.ts.map +1 -0
- package/dist/checks/workflows/performance.js +77 -0
- package/dist/checks/workflows/performance.js.map +1 -0
- package/dist/checks/workflows/pre-deploy.d.ts +6 -0
- package/dist/checks/workflows/pre-deploy.d.ts.map +1 -0
- package/dist/checks/workflows/pre-deploy.js +41 -0
- package/dist/checks/workflows/pre-deploy.js.map +1 -0
- package/dist/checks/workflows/security.d.ts +8 -0
- package/dist/checks/workflows/security.d.ts.map +1 -0
- package/dist/checks/workflows/security.js +71 -0
- package/dist/checks/workflows/security.js.map +1 -0
- package/dist/checks/workflows/supercatch.d.ts +8 -0
- package/dist/checks/workflows/supercatch.d.ts.map +1 -0
- package/dist/checks/workflows/supercatch.js +127 -0
- package/dist/checks/workflows/supercatch.js.map +1 -0
- package/dist/checks/workflows/ui-quality.d.ts +9 -0
- package/dist/checks/workflows/ui-quality.d.ts.map +1 -0
- package/dist/checks/workflows/ui-quality.js +264 -0
- package/dist/checks/workflows/ui-quality.js.map +1 -0
- package/dist/checks/workflows/ui-uniformity.d.ts +18 -0
- package/dist/checks/workflows/ui-uniformity.d.ts.map +1 -0
- package/dist/checks/workflows/ui-uniformity.js +265 -0
- package/dist/checks/workflows/ui-uniformity.js.map +1 -0
- package/dist/checks/workflows/vercel.d.ts +16 -0
- package/dist/checks/workflows/vercel.d.ts.map +1 -0
- package/dist/checks/workflows/vercel.js +173 -0
- package/dist/checks/workflows/vercel.js.map +1 -0
- package/dist/utils/validation-helpers.d.ts +43 -0
- package/dist/utils/validation-helpers.d.ts.map +1 -0
- package/dist/utils/validation-helpers.js +370 -0
- package/dist/utils/validation-helpers.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,1001 @@
|
|
|
1
|
+
#!/usr/bin/env tsx
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Consolidated E2E Validation Preflight
|
|
5
|
+
*
|
|
6
|
+
* MASTER module for all E2E test validation. Consolidates 18+ separate preflights into one.
|
|
7
|
+
*
|
|
8
|
+
* Sub-checks included (10 total):
|
|
9
|
+
* 1. Best Practices - No hardcoded waits, force clicks, page.pause, .only tests
|
|
10
|
+
* 2. Outcome Validation - Critical actions have outcome verification
|
|
11
|
+
* 3. Flake Patterns - Patterns that cause flaky tests
|
|
12
|
+
* 4. Timeout Limits - Playwright config timeout limits
|
|
13
|
+
* 5. Performance - Slow patterns and excessive timeouts
|
|
14
|
+
* 6. Test Organization - test.describe blocks and imports
|
|
15
|
+
* 7. Assertion Quality - Detects weak assertions (visibility-only tests)
|
|
16
|
+
* 8. Test Isolation - Shared state and beforeAll issues
|
|
17
|
+
* 9. Selector Stability - Brittle selectors (class, nth-child, nested divs)
|
|
18
|
+
* 10. Critical Route Coverage - Ensures critical paths have E2E tests
|
|
19
|
+
*
|
|
20
|
+
* Usage:
|
|
21
|
+
* pnpm preflight:e2e # All checks
|
|
22
|
+
* pnpm preflight:e2e best-practices # Best practices only
|
|
23
|
+
* pnpm preflight:e2e outcomes # Outcome validation only
|
|
24
|
+
* pnpm preflight:e2e flakes # Flake patterns only
|
|
25
|
+
* pnpm preflight:e2e timeouts # Timeout limits only
|
|
26
|
+
* pnpm preflight:e2e performance # Performance patterns only
|
|
27
|
+
* pnpm preflight:e2e organization # Test organization only
|
|
28
|
+
* pnpm preflight:e2e assertions # Assertion quality only
|
|
29
|
+
* pnpm preflight:e2e isolation # Test isolation only
|
|
30
|
+
* pnpm preflight:e2e selectors # Selector stability only
|
|
31
|
+
* pnpm preflight:e2e coverage # Critical route coverage only
|
|
32
|
+
* pnpm preflight:e2e --warn # All checks as warnings
|
|
33
|
+
* pnpm preflight:e2e --verbose # Show all issues
|
|
34
|
+
*
|
|
35
|
+
* Replaces:
|
|
36
|
+
* - e2e/e2e-outcome-validation.ts
|
|
37
|
+
* - e2e/e2e-interaction-regression.ts
|
|
38
|
+
* - e2e/e2e-interaction-coverage-scan.ts
|
|
39
|
+
* - e2e/e2e-action-outcome-validator.ts
|
|
40
|
+
* - e2e/e2e-button-functionality-audit.ts
|
|
41
|
+
* - e2e/e2e-performance-regression.ts
|
|
42
|
+
* - e2e/e2e-performance-baseline.ts
|
|
43
|
+
* - e2e/e2e-performance-patterns.ts
|
|
44
|
+
* - e2e/e2e-resource-monitoring.ts
|
|
45
|
+
* - testing/e2e-best-practices.ts
|
|
46
|
+
* - testing/e2e-flake-patterns.ts
|
|
47
|
+
* - testing/e2e-timeouts.ts
|
|
48
|
+
* - testing/e2e-slow-tests.ts
|
|
49
|
+
* - testing/e2e-redundant-visibility-checks.ts
|
|
50
|
+
* - consolidated/e2e-regression-coverage.ts
|
|
51
|
+
* - consolidated/regression-hygiene.ts (E2E parts)
|
|
52
|
+
*/
|
|
53
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
54
|
+
if (k2 === undefined) k2 = k;
|
|
55
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
56
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
57
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
58
|
+
}
|
|
59
|
+
Object.defineProperty(o, k2, desc);
|
|
60
|
+
}) : (function(o, m, k, k2) {
|
|
61
|
+
if (k2 === undefined) k2 = k;
|
|
62
|
+
o[k2] = m[k];
|
|
63
|
+
}));
|
|
64
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
65
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
66
|
+
}) : function(o, v) {
|
|
67
|
+
o["default"] = v;
|
|
68
|
+
});
|
|
69
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
70
|
+
var ownKeys = function(o) {
|
|
71
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
72
|
+
var ar = [];
|
|
73
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
74
|
+
return ar;
|
|
75
|
+
};
|
|
76
|
+
return ownKeys(o);
|
|
77
|
+
};
|
|
78
|
+
return function (mod) {
|
|
79
|
+
if (mod && mod.__esModule) return mod;
|
|
80
|
+
var result = {};
|
|
81
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
82
|
+
__setModuleDefault(result, mod);
|
|
83
|
+
return result;
|
|
84
|
+
};
|
|
85
|
+
})();
|
|
86
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
87
|
+
exports.E2EValidationModule = void 0;
|
|
88
|
+
const fs = __importStar(require("fs"));
|
|
89
|
+
const path = __importStar(require("path"));
|
|
90
|
+
const console_chars_1 = require("../../utils/console-chars");
|
|
91
|
+
const file_cache_1 = require("../../shared/file-cache");
|
|
92
|
+
const glob_patterns_1 = require("../../shared/glob-patterns");
|
|
93
|
+
const concurrency_config_1 = require("../../shared/concurrency-config");
|
|
94
|
+
// CACHED FILE LISTS - Scan once, use everywhere
|
|
95
|
+
let _cachedE2ESpecFiles = null;
|
|
96
|
+
async function getE2ESpecFiles() {
|
|
97
|
+
if (!_cachedE2ESpecFiles) {
|
|
98
|
+
_cachedE2ESpecFiles = await file_cache_1.fileCache.getE2ESpecFiles();
|
|
99
|
+
}
|
|
100
|
+
return _cachedE2ESpecFiles;
|
|
101
|
+
}
|
|
102
|
+
// CONFIGURATION
|
|
103
|
+
const EXCLUDED = [...glob_patterns_1.STANDARD_EXCLUDES];
|
|
104
|
+
const E2E_TEST_GLOB = "tests/e2e/**/*.spec.ts";
|
|
105
|
+
// Best practices rules
|
|
106
|
+
// NOTE: These are all warnings (non-blocking) because the original e2e-best-practices.ts
|
|
107
|
+
// was NOT included in preflight:all. Making them blocking would be a regression.
|
|
108
|
+
// To make blocking in future: change severity to 'error' and fix all violations first.
|
|
109
|
+
const BEST_PRACTICE_RULES = {
|
|
110
|
+
"no-hardcoded-waits": {
|
|
111
|
+
pattern: /waitForTimeout\s*\(\s*(\d+)\s*\)/g,
|
|
112
|
+
threshold: 500,
|
|
113
|
+
severity: "warning", // Non-blocking - original preflight wasn't in all.ts
|
|
114
|
+
message: (timeout) => `Hardcoded wait of ${timeout}ms found`,
|
|
115
|
+
suggestion: "Use waitForSelector, waitForLoadState, or expect().toBeVisible()",
|
|
116
|
+
},
|
|
117
|
+
"no-force-click": {
|
|
118
|
+
pattern: /force:\s*true/g,
|
|
119
|
+
contextPattern: /click/,
|
|
120
|
+
severity: "warning", // Non-blocking - sometimes needed for mobile tests
|
|
121
|
+
message: "Using force: true bypasses actionability checks",
|
|
122
|
+
suggestion: "Fix element visibility/interactability instead of using force: true",
|
|
123
|
+
},
|
|
124
|
+
"no-page-pause": {
|
|
125
|
+
pattern: /page\.pause\(\)/g,
|
|
126
|
+
severity: "error",
|
|
127
|
+
message: "page.pause() should not be committed to tests",
|
|
128
|
+
suggestion: "Remove page.pause() - it's only for debugging",
|
|
129
|
+
},
|
|
130
|
+
"no-only-tests": {
|
|
131
|
+
pattern: /test\.only\(|\.only\(/g,
|
|
132
|
+
severity: "error",
|
|
133
|
+
message: "test.only() should not be committed",
|
|
134
|
+
suggestion: "Remove .only() to run all tests in CI",
|
|
135
|
+
},
|
|
136
|
+
"no-skip-without-reason": {
|
|
137
|
+
pattern: /test\.skip\(/g,
|
|
138
|
+
checkPrevLineForTodo: true, // Special handling - check for TODO/FIXME on previous line
|
|
139
|
+
severity: "warning",
|
|
140
|
+
message: "test.skip() should have a reason comment",
|
|
141
|
+
suggestion: 'Add a TODO comment on the line before, or use test.skip("reason", ...)',
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
// Critical actions that MUST have outcome verification
|
|
145
|
+
const CRITICAL_ACTIONS = [
|
|
146
|
+
{
|
|
147
|
+
pattern: /\.click\s*\([^)]*(?:delete|remove|trash)/i,
|
|
148
|
+
name: "Delete",
|
|
149
|
+
severity: "critical",
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
pattern: /\.click\s*\([^)]*(?:checkout|place.*order|pay|purchase)/i,
|
|
153
|
+
name: "Checkout",
|
|
154
|
+
severity: "critical",
|
|
155
|
+
},
|
|
156
|
+
{ pattern: /\.click\s*\([^)]*(?:refund)/i, name: "Refund", severity: "critical" },
|
|
157
|
+
{
|
|
158
|
+
pattern: /\.click\s*\([^)]*(?:submit|save|confirm)/i,
|
|
159
|
+
name: "Submit",
|
|
160
|
+
severity: "high",
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
pattern: /\.click\s*\([^)]*(?:approve|reject)/i,
|
|
164
|
+
name: "Approve/Reject",
|
|
165
|
+
severity: "high",
|
|
166
|
+
},
|
|
167
|
+
{ pattern: /\.click\s*\([^)]*(?:ship|fulfill)/i, name: "Ship", severity: "high" },
|
|
168
|
+
{ pattern: /\.click\s*\([^)]*(?:cancel)/i, name: "Cancel", severity: "high" },
|
|
169
|
+
{
|
|
170
|
+
pattern: /\.click\s*\([^)]*(?:add.*cart|buy)/i,
|
|
171
|
+
name: "Add to Cart",
|
|
172
|
+
severity: "high",
|
|
173
|
+
},
|
|
174
|
+
];
|
|
175
|
+
// Strong outcome patterns
|
|
176
|
+
const STRONG_OUTCOMES = [
|
|
177
|
+
/toHaveURL\s*\(/,
|
|
178
|
+
/toHaveText\s*\(/,
|
|
179
|
+
/toContainText\s*\(/,
|
|
180
|
+
/toHaveValue\s*\(/,
|
|
181
|
+
/toHaveCount\s*\(/,
|
|
182
|
+
/not\.toBeVisible\s*\(/,
|
|
183
|
+
/toBeHidden\s*\(/,
|
|
184
|
+
/waitForResponse\s*\(/,
|
|
185
|
+
/waitForRequest\s*\(/,
|
|
186
|
+
/waitForURL\s*\(/,
|
|
187
|
+
/expect\.poll\s*\(/,
|
|
188
|
+
];
|
|
189
|
+
// Flake patterns
|
|
190
|
+
const FLAKE_PATTERNS = [
|
|
191
|
+
{
|
|
192
|
+
pattern: /:text\s*\(/g,
|
|
193
|
+
name: "text-selector",
|
|
194
|
+
message: "Text selectors are brittle",
|
|
195
|
+
suggestion: "Use getByRole, getByTestId, or getByLabel",
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
pattern: /\.catch\s*\(\s*\(\s*\)\s*=>\s*\{\s*\}\s*\)/g,
|
|
199
|
+
name: "empty-catch",
|
|
200
|
+
message: "Empty catch swallows errors",
|
|
201
|
+
suggestion: "Log or rethrow the error",
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
pattern: /page\.content\(\)/g,
|
|
205
|
+
name: "page-content",
|
|
206
|
+
message: "page.content() is brittle for assertions",
|
|
207
|
+
suggestion: "Use specific element assertions",
|
|
208
|
+
},
|
|
209
|
+
];
|
|
210
|
+
// Timeout limits
|
|
211
|
+
const TIMEOUT_LIMITS = {
|
|
212
|
+
testTimeoutMs: 90_000,
|
|
213
|
+
actionTimeoutMs: 15_000,
|
|
214
|
+
expectTimeoutMs: 30_000,
|
|
215
|
+
navigationTimeoutMs: 60_000,
|
|
216
|
+
};
|
|
217
|
+
// Performance patterns
|
|
218
|
+
const SLOW_PATTERNS = [
|
|
219
|
+
{
|
|
220
|
+
pattern: /timeout:\s*(1[2-9]\d{4,}|[2-9]\d{5,}|\d{6,})/g,
|
|
221
|
+
severity: "error",
|
|
222
|
+
message: "Very excessive timeout (120s+)",
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
pattern: /timeout:\s*([6-9]\d{4}|1[01]\d{4})/g,
|
|
226
|
+
severity: "warning",
|
|
227
|
+
message: "Long timeout (60s+)",
|
|
228
|
+
},
|
|
229
|
+
{
|
|
230
|
+
pattern: /waitForTimeout\(\s*([2-9]\d{3,}|\d{5,})\s*\)/g,
|
|
231
|
+
severity: "error",
|
|
232
|
+
message: "Very long waitForTimeout (2s+)",
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
pattern: /page\.waitForSelector\(/g,
|
|
236
|
+
severity: "warning",
|
|
237
|
+
message: "waitForSelector is deprecated",
|
|
238
|
+
},
|
|
239
|
+
];
|
|
240
|
+
// ENHANCEMENT: Missing Test Coverage Detection
|
|
241
|
+
// Routes that MUST have E2E coverage (critical user paths)
|
|
242
|
+
const CRITICAL_ROUTES_REQUIRING_TESTS = [
|
|
243
|
+
{ route: "/checkout", minTests: 1, severity: "critical" },
|
|
244
|
+
{ route: "/login", minTests: 1, severity: "critical" },
|
|
245
|
+
{ route: "/register", minTests: 1, severity: "critical" },
|
|
246
|
+
{ route: "/store", minTests: 1, severity: "high" },
|
|
247
|
+
{ route: "/marketplace", minTests: 1, severity: "high" },
|
|
248
|
+
{ route: "/cart", minTests: 1, severity: "high" },
|
|
249
|
+
{ route: "/account", minTests: 1, severity: "medium" },
|
|
250
|
+
];
|
|
251
|
+
// Assertion patterns that indicate test completeness
|
|
252
|
+
const ASSERTION_QUALITY_PATTERNS = {
|
|
253
|
+
// Strong assertions - actually verify functionality
|
|
254
|
+
strong: [
|
|
255
|
+
/toHaveURL\s*\(/,
|
|
256
|
+
/toHaveText\s*\(/,
|
|
257
|
+
/toContainText\s*\(/,
|
|
258
|
+
/toHaveValue\s*\(/,
|
|
259
|
+
/toHaveCount\s*\(/,
|
|
260
|
+
/toBeChecked\s*\(/,
|
|
261
|
+
/not\.toBeVisible\s*\(/,
|
|
262
|
+
/toBeHidden\s*\(/,
|
|
263
|
+
/waitForResponse\s*\(/,
|
|
264
|
+
/waitForURL\s*\(/,
|
|
265
|
+
/expect\.poll\s*\(/,
|
|
266
|
+
],
|
|
267
|
+
// Weak assertions - may pass even when broken
|
|
268
|
+
weak: [
|
|
269
|
+
/toBeVisible\s*\(\s*\)\s*;?\s*$/, // Just visibility check with no content
|
|
270
|
+
/toBeTruthy\s*\(\s*\)/, // Too generic
|
|
271
|
+
/toBeDefined\s*\(\s*\)/, // Too generic
|
|
272
|
+
],
|
|
273
|
+
};
|
|
274
|
+
// Test isolation patterns - detecting shared state issues
|
|
275
|
+
const ISOLATION_ANTI_PATTERNS = [
|
|
276
|
+
{
|
|
277
|
+
pattern: /let\s+\w+\s*=\s*[^;]+;[\s\S]*test\(/g,
|
|
278
|
+
name: "module-level-variable",
|
|
279
|
+
message: "Module-level variable may cause test pollution",
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
pattern: /beforeAll\s*\([^)]*\)\s*=>\s*\{[\s\S]*page\./g,
|
|
283
|
+
name: "beforeAll-page-access",
|
|
284
|
+
message: "Accessing page in beforeAll can cause isolation issues",
|
|
285
|
+
},
|
|
286
|
+
];
|
|
287
|
+
// E2E VALIDATION MODULE
|
|
288
|
+
// Get concurrency from shared config (respects PREFLIGHT_CONCURRENCY env var)
|
|
289
|
+
const concurrencyConfig = (0, concurrency_config_1.getConcurrencyConfig)();
|
|
290
|
+
class E2EValidationModule {
|
|
291
|
+
warnOnly;
|
|
292
|
+
constructor(options = {}) {
|
|
293
|
+
this.warnOnly = options.warnOnly ?? false;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Check 1: Best Practices
|
|
297
|
+
*/
|
|
298
|
+
async checkBestPractices() {
|
|
299
|
+
const startTime = Date.now();
|
|
300
|
+
const issues = [];
|
|
301
|
+
const files = await getE2ESpecFiles();
|
|
302
|
+
for (const file of files) {
|
|
303
|
+
const content = fs.readFileSync(file, "utf8");
|
|
304
|
+
const lines = content.split("\n");
|
|
305
|
+
// Check each rule
|
|
306
|
+
for (const [ruleName, rule] of Object.entries(BEST_PRACTICE_RULES)) {
|
|
307
|
+
if ("threshold" in rule) {
|
|
308
|
+
// Pattern with threshold (e.g., waitForTimeout)
|
|
309
|
+
let match;
|
|
310
|
+
while ((match = rule.pattern.exec(content)) !== null) {
|
|
311
|
+
const value = parseInt(match[1] ?? "0", 10);
|
|
312
|
+
if (value > rule.threshold) {
|
|
313
|
+
const lineNum = content.substring(0, match.index).split("\n").length;
|
|
314
|
+
issues.push({
|
|
315
|
+
file,
|
|
316
|
+
line: lineNum,
|
|
317
|
+
type: ruleName,
|
|
318
|
+
severity: this.warnOnly ? "warning" : rule.severity,
|
|
319
|
+
message: rule.message(value),
|
|
320
|
+
suggestion: rule.suggestion,
|
|
321
|
+
rule: ruleName,
|
|
322
|
+
});
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
else if ("contextPattern" in rule) {
|
|
327
|
+
// Pattern with context check
|
|
328
|
+
lines.forEach((line, index) => {
|
|
329
|
+
if (rule.pattern.test(line) && rule.contextPattern.test(line)) {
|
|
330
|
+
issues.push({
|
|
331
|
+
file,
|
|
332
|
+
line: index + 1,
|
|
333
|
+
type: ruleName,
|
|
334
|
+
severity: this.warnOnly ? "warning" : rule.severity,
|
|
335
|
+
message: rule.message,
|
|
336
|
+
suggestion: rule.suggestion,
|
|
337
|
+
rule: ruleName,
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
else if ("checkPrevLineForTodo" in rule && rule.checkPrevLineForTodo) {
|
|
343
|
+
// test.skip() pattern - check for TODO/FIXME on previous line or inline reason
|
|
344
|
+
lines.forEach((line, index) => {
|
|
345
|
+
if (rule.pattern.test(line) && !line.trim().startsWith("//")) {
|
|
346
|
+
const prevLine = index > 0 ? (lines[index - 1] ?? "") : "";
|
|
347
|
+
// Allow if previous line has TODO or FIXME
|
|
348
|
+
if (prevLine.includes("TODO") || prevLine.includes("FIXME")) {
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
// Allow if line has inline comment
|
|
352
|
+
if (line.includes("//") || line.includes("/*")) {
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
// Allow if previous line has any comment
|
|
356
|
+
if (prevLine.trim().startsWith("//")) {
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
359
|
+
// Check for inline reason string in various formats:
|
|
360
|
+
// test.skip("reason", async () => {
|
|
361
|
+
// test.skip(condition, "reason")
|
|
362
|
+
// test.skip(!visible, "Reason text")
|
|
363
|
+
// test.skip(await emptyState.isVisible().catch(() => false), "No posts")
|
|
364
|
+
const lookahead = [
|
|
365
|
+
lines[index] ?? "",
|
|
366
|
+
lines[index + 1] ?? "",
|
|
367
|
+
lines[index + 2] ?? "",
|
|
368
|
+
lines[index + 3] ?? "",
|
|
369
|
+
].join("\n");
|
|
370
|
+
// Check for test.skip with a reason string - look for pattern with comma followed by string
|
|
371
|
+
// Handle complex expressions by looking for ", " or ",\n" followed by a quote
|
|
372
|
+
const hasInlineReason = /test\.skip\([\s\S]*?,\s*['"`][^'"`]+['"`]/.test(lookahead) ||
|
|
373
|
+
/test\.skip\(\s*['"`][^'"`]+['"`]\s*,/.test(lookahead);
|
|
374
|
+
if (hasInlineReason) {
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
issues.push({
|
|
378
|
+
file,
|
|
379
|
+
line: index + 1,
|
|
380
|
+
type: ruleName,
|
|
381
|
+
severity: this.warnOnly ? "warning" : rule.severity,
|
|
382
|
+
message: rule.message,
|
|
383
|
+
suggestion: rule.suggestion,
|
|
384
|
+
rule: ruleName,
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
else {
|
|
390
|
+
// Simple pattern match
|
|
391
|
+
lines.forEach((line, index) => {
|
|
392
|
+
if (rule.pattern.test(line) && !line.trim().startsWith("//")) {
|
|
393
|
+
issues.push({
|
|
394
|
+
file,
|
|
395
|
+
line: index + 1,
|
|
396
|
+
type: ruleName,
|
|
397
|
+
severity: this.warnOnly ? "warning" : rule.severity,
|
|
398
|
+
message: rule.message,
|
|
399
|
+
suggestion: rule.suggestion,
|
|
400
|
+
rule: ruleName,
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
const hasErrors = issues.some((i) => i.severity === "error");
|
|
408
|
+
return {
|
|
409
|
+
name: "E2E Best Practices",
|
|
410
|
+
passed: !hasErrors,
|
|
411
|
+
blocking: !this.warnOnly,
|
|
412
|
+
issues,
|
|
413
|
+
duration: Date.now() - startTime,
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Check 2: Outcome Validation
|
|
418
|
+
*/
|
|
419
|
+
async checkOutcomeValidation() {
|
|
420
|
+
const startTime = Date.now();
|
|
421
|
+
const issues = [];
|
|
422
|
+
const files = await getE2ESpecFiles();
|
|
423
|
+
for (const file of files) {
|
|
424
|
+
const content = fs.readFileSync(file, "utf8");
|
|
425
|
+
const lines = content.split("\n");
|
|
426
|
+
for (let i = 0; i < lines.length; i++) {
|
|
427
|
+
const line = lines[i] ?? "";
|
|
428
|
+
for (const action of CRITICAL_ACTIONS) {
|
|
429
|
+
if (action.pattern.test(line)) {
|
|
430
|
+
// Check if there's an outcome assertion within 10 lines
|
|
431
|
+
const contextEnd = Math.min(i + 10, lines.length);
|
|
432
|
+
const context = lines.slice(i, contextEnd).join("\n");
|
|
433
|
+
const hasOutcome = STRONG_OUTCOMES.some((p) => p.test(context));
|
|
434
|
+
if (!hasOutcome) {
|
|
435
|
+
issues.push({
|
|
436
|
+
file,
|
|
437
|
+
line: i + 1,
|
|
438
|
+
type: "missing-outcome",
|
|
439
|
+
severity: action.severity === "critical" ? "error" : "warning",
|
|
440
|
+
message: `${action.name} action without outcome verification`,
|
|
441
|
+
suggestion: "Add toHaveURL, toHaveText, waitForResponse, or similar assertion",
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
const hasErrors = issues.some((i) => i.severity === "error");
|
|
449
|
+
return {
|
|
450
|
+
name: "E2E Outcome Validation",
|
|
451
|
+
passed: !hasErrors || this.warnOnly,
|
|
452
|
+
blocking: !this.warnOnly,
|
|
453
|
+
issues,
|
|
454
|
+
duration: Date.now() - startTime,
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Check 3: Flake Patterns
|
|
459
|
+
*/
|
|
460
|
+
async checkFlakePatterns() {
|
|
461
|
+
const startTime = Date.now();
|
|
462
|
+
const issues = [];
|
|
463
|
+
const files = await getE2ESpecFiles();
|
|
464
|
+
for (const file of files) {
|
|
465
|
+
const content = fs.readFileSync(file, "utf8");
|
|
466
|
+
const lines = content.split("\n");
|
|
467
|
+
for (const flake of FLAKE_PATTERNS) {
|
|
468
|
+
let match;
|
|
469
|
+
while ((match = flake.pattern.exec(content)) !== null) {
|
|
470
|
+
const lineNum = content.substring(0, match.index).split("\n").length;
|
|
471
|
+
// Check for suppression comment
|
|
472
|
+
// lineNum is 1-indexed, but slice is 0-indexed, so use lineNum - 1
|
|
473
|
+
// Look 4 lines before to catch multi-line locators where comment is before const
|
|
474
|
+
const lineIndex = lineNum - 1;
|
|
475
|
+
const contextStart = Math.max(0, lineIndex - 4);
|
|
476
|
+
const contextEnd = Math.min(lineIndex + 1, lines.length);
|
|
477
|
+
const context = lines.slice(contextStart, contextEnd).join("\n");
|
|
478
|
+
if (!context.includes("e2e-allow-flake-pattern")) {
|
|
479
|
+
issues.push({
|
|
480
|
+
file,
|
|
481
|
+
line: lineNum,
|
|
482
|
+
type: flake.name,
|
|
483
|
+
severity: "warning",
|
|
484
|
+
message: flake.message,
|
|
485
|
+
suggestion: flake.suggestion,
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
return {
|
|
492
|
+
name: "E2E Flake Patterns",
|
|
493
|
+
passed: true, // Non-blocking
|
|
494
|
+
blocking: false,
|
|
495
|
+
issues,
|
|
496
|
+
duration: Date.now() - startTime,
|
|
497
|
+
};
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Check 4: Timeout Limits
|
|
501
|
+
*/
|
|
502
|
+
async checkTimeoutLimits() {
|
|
503
|
+
const startTime = Date.now();
|
|
504
|
+
const issues = [];
|
|
505
|
+
try {
|
|
506
|
+
// Dynamic import of playwright config
|
|
507
|
+
const configPath = path.join(process.cwd(), "playwright.config.ts");
|
|
508
|
+
if (!fs.existsSync(configPath)) {
|
|
509
|
+
return {
|
|
510
|
+
name: "E2E Timeout Limits",
|
|
511
|
+
passed: true,
|
|
512
|
+
blocking: false,
|
|
513
|
+
issues: [
|
|
514
|
+
{
|
|
515
|
+
file: "playwright.config.ts",
|
|
516
|
+
line: 0,
|
|
517
|
+
type: "missing-config",
|
|
518
|
+
severity: "info",
|
|
519
|
+
message: "No playwright.config.ts found",
|
|
520
|
+
},
|
|
521
|
+
],
|
|
522
|
+
duration: Date.now() - startTime,
|
|
523
|
+
};
|
|
524
|
+
}
|
|
525
|
+
// Read and parse config (simplified check)
|
|
526
|
+
const configContent = fs.readFileSync(configPath, "utf8");
|
|
527
|
+
// Check for excessive timeouts in config
|
|
528
|
+
const timeoutMatch = configContent.match(/timeout:\s*(\d+)/);
|
|
529
|
+
if (timeoutMatch) {
|
|
530
|
+
const timeout = parseInt(timeoutMatch[1] ?? "0", 10);
|
|
531
|
+
if (timeout > TIMEOUT_LIMITS.testTimeoutMs) {
|
|
532
|
+
issues.push({
|
|
533
|
+
file: "playwright.config.ts",
|
|
534
|
+
line: 1,
|
|
535
|
+
type: "excessive-timeout",
|
|
536
|
+
severity: "error",
|
|
537
|
+
message: `Test timeout ${timeout}ms exceeds limit of ${TIMEOUT_LIMITS.testTimeoutMs}ms`,
|
|
538
|
+
suggestion: "Reduce timeout or break tests into smaller units",
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
catch {
|
|
544
|
+
// Config parsing failed, skip this check
|
|
545
|
+
}
|
|
546
|
+
const hasErrors = issues.some((i) => i.severity === "error");
|
|
547
|
+
return {
|
|
548
|
+
name: "E2E Timeout Limits",
|
|
549
|
+
passed: !hasErrors,
|
|
550
|
+
blocking: true,
|
|
551
|
+
issues,
|
|
552
|
+
duration: Date.now() - startTime,
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Check 5: Performance Patterns
|
|
557
|
+
*/
|
|
558
|
+
async checkPerformancePatterns() {
|
|
559
|
+
const startTime = Date.now();
|
|
560
|
+
const issues = [];
|
|
561
|
+
const files = await getE2ESpecFiles();
|
|
562
|
+
for (const file of files) {
|
|
563
|
+
const content = fs.readFileSync(file, "utf8");
|
|
564
|
+
for (const slow of SLOW_PATTERNS) {
|
|
565
|
+
let match;
|
|
566
|
+
while ((match = slow.pattern.exec(content)) !== null) {
|
|
567
|
+
const lineNum = content.substring(0, match.index).split("\n").length;
|
|
568
|
+
issues.push({
|
|
569
|
+
file,
|
|
570
|
+
line: lineNum,
|
|
571
|
+
type: "slow-pattern",
|
|
572
|
+
severity: slow.severity,
|
|
573
|
+
message: slow.message,
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
const hasErrors = issues.some((i) => i.severity === "error");
|
|
579
|
+
return {
|
|
580
|
+
name: "E2E Performance Patterns",
|
|
581
|
+
passed: !hasErrors || this.warnOnly,
|
|
582
|
+
blocking: false, // Performance is non-blocking
|
|
583
|
+
issues,
|
|
584
|
+
duration: Date.now() - startTime,
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Check 6: Test Organization
|
|
589
|
+
*/
|
|
590
|
+
async checkTestOrganization() {
|
|
591
|
+
const startTime = Date.now();
|
|
592
|
+
const issues = [];
|
|
593
|
+
const files = await getE2ESpecFiles();
|
|
594
|
+
for (const file of files) {
|
|
595
|
+
const content = fs.readFileSync(file, "utf8");
|
|
596
|
+
// Check for test.describe usage (also accept .skip, .serial, .parallel variants)
|
|
597
|
+
const hasDescribe = /test\.describe(\.(skip|serial|parallel|only|fixme))?\s*\(/.test(content);
|
|
598
|
+
if (!hasDescribe && content.includes("test(")) {
|
|
599
|
+
issues.push({
|
|
600
|
+
file,
|
|
601
|
+
line: 1,
|
|
602
|
+
type: "missing-describe",
|
|
603
|
+
severity: "warning",
|
|
604
|
+
message: "Tests should be organized with test.describe()",
|
|
605
|
+
suggestion: "Wrap related tests in test.describe() blocks",
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
// Check for proper imports
|
|
609
|
+
if (!content.includes("from '@playwright/test'") &&
|
|
610
|
+
!content.includes('from "@playwright/test"')) {
|
|
611
|
+
issues.push({
|
|
612
|
+
file,
|
|
613
|
+
line: 1,
|
|
614
|
+
type: "missing-import",
|
|
615
|
+
severity: "warning",
|
|
616
|
+
message: "Missing Playwright test import",
|
|
617
|
+
suggestion: "Add: import { test, expect } from '@playwright/test'",
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
return {
|
|
622
|
+
name: "E2E Test Organization",
|
|
623
|
+
passed: true, // Non-blocking
|
|
624
|
+
blocking: false,
|
|
625
|
+
issues,
|
|
626
|
+
duration: Date.now() - startTime,
|
|
627
|
+
};
|
|
628
|
+
}
|
|
629
|
+
/**
|
|
630
|
+
* Check 7: Assertion Quality
|
|
631
|
+
* Detects tests that only use weak assertions (toBeVisible only) without verifying actual content/state
|
|
632
|
+
*/
|
|
633
|
+
async checkAssertionQuality() {
|
|
634
|
+
const startTime = Date.now();
|
|
635
|
+
const issues = [];
|
|
636
|
+
const files = await getE2ESpecFiles();
|
|
637
|
+
for (const file of files) {
|
|
638
|
+
const content = fs.readFileSync(file, "utf8");
|
|
639
|
+
// Split into test blocks
|
|
640
|
+
const testBlocks = content.split(/\btest\s*\(/);
|
|
641
|
+
testBlocks.forEach((block, blockIndex) => {
|
|
642
|
+
if (blockIndex === 0)
|
|
643
|
+
return; // Skip before first test
|
|
644
|
+
// Extract test name
|
|
645
|
+
const nameMatch = block.match(/^["'`]([^"'`]+)["'`]/);
|
|
646
|
+
const testName = nameMatch ? nameMatch[1] : `test #${blockIndex}`;
|
|
647
|
+
// Get test body (up to closing of test)
|
|
648
|
+
const testBody = block.substring(0, Math.min(block.length, 2000));
|
|
649
|
+
// Count assertion types
|
|
650
|
+
const strongAssertions = ASSERTION_QUALITY_PATTERNS.strong.filter((p) => p.test(testBody)).length;
|
|
651
|
+
const weakAssertions = ASSERTION_QUALITY_PATTERNS.weak.filter((p) => p.test(testBody)).length;
|
|
652
|
+
const totalExpects = (testBody.match(/expect\s*\(/g) ?? []).length;
|
|
653
|
+
// Flag tests with only weak assertions
|
|
654
|
+
if (totalExpects > 0 && strongAssertions === 0 && weakAssertions > 0) {
|
|
655
|
+
// Skip display/render tests
|
|
656
|
+
const isDisplayTest = /\b(display|render|show|visible|appear|load)\b/i.test(testName);
|
|
657
|
+
if (!isDisplayTest) {
|
|
658
|
+
issues.push({
|
|
659
|
+
file,
|
|
660
|
+
line: 1,
|
|
661
|
+
type: "weak-assertions-only",
|
|
662
|
+
severity: "warning",
|
|
663
|
+
message: `Test "${testName}" uses only weak assertions (visibility checks)`,
|
|
664
|
+
suggestion: "Add content verification: toHaveText, toContainText, toHaveValue, or toHaveURL",
|
|
665
|
+
});
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
return {
|
|
671
|
+
name: "E2E Assertion Quality",
|
|
672
|
+
passed: true, // Non-blocking
|
|
673
|
+
blocking: false,
|
|
674
|
+
issues,
|
|
675
|
+
duration: Date.now() - startTime,
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
/**
|
|
679
|
+
* Check 8: Test Isolation
|
|
680
|
+
* Detects patterns that can cause flaky tests due to shared state
|
|
681
|
+
*/
|
|
682
|
+
async checkTestIsolation() {
|
|
683
|
+
const startTime = Date.now();
|
|
684
|
+
const issues = [];
|
|
685
|
+
const files = await getE2ESpecFiles();
|
|
686
|
+
for (const file of files) {
|
|
687
|
+
const content = fs.readFileSync(file, "utf8");
|
|
688
|
+
const lines = content.split("\n");
|
|
689
|
+
// Track if we're inside a function/block
|
|
690
|
+
let braceDepth = 0;
|
|
691
|
+
let inDescribeOrTest = false;
|
|
692
|
+
// Check for module-level mutable state
|
|
693
|
+
for (let i = 0; i < lines.length; i++) {
|
|
694
|
+
const line = lines[i] ?? "";
|
|
695
|
+
// Track brace depth to detect module-level vs function-level variables
|
|
696
|
+
const openBraces = (line.match(/\{/g) ?? []).length;
|
|
697
|
+
const closeBraces = (line.match(/\}/g) ?? []).length;
|
|
698
|
+
// Check if entering a describe/test block
|
|
699
|
+
if (/test\.describe\s*\(|test\s*\(/.test(line)) {
|
|
700
|
+
inDescribeOrTest = true;
|
|
701
|
+
}
|
|
702
|
+
braceDepth += openBraces - closeBraces;
|
|
703
|
+
// Only flag module-level let (braceDepth 0 and not yet in test blocks)
|
|
704
|
+
if (braceDepth === 0 && !inDescribeOrTest && i < 50) {
|
|
705
|
+
// Detect: let someVar = ... at module level (not inside function)
|
|
706
|
+
if (/^let\s+\w+\s*=/.test(line.trim()) &&
|
|
707
|
+
!line.includes("readonly") &&
|
|
708
|
+
!line.includes("// isolation-ok")) {
|
|
709
|
+
// Check if this is before any test block
|
|
710
|
+
const remainingContent = lines.slice(i).join("\n");
|
|
711
|
+
if (remainingContent.includes("test(") || remainingContent.includes("test.describe(")) {
|
|
712
|
+
issues.push({
|
|
713
|
+
file,
|
|
714
|
+
line: i + 1,
|
|
715
|
+
type: "mutable-module-state",
|
|
716
|
+
severity: "warning",
|
|
717
|
+
message: "Mutable module-level variable may cause test pollution",
|
|
718
|
+
suggestion: "Use test.beforeEach() to reset state, or use const/readonly, or add // isolation-ok",
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
// Detect beforeAll with page access (can cause isolation issues)
|
|
724
|
+
if (/beforeAll\s*\(\s*async/.test(line)) {
|
|
725
|
+
const blockEnd = Math.min(i + 20, lines.length);
|
|
726
|
+
const beforeAllBlock = lines.slice(i, blockEnd).join("\n");
|
|
727
|
+
if (/page\./.test(beforeAllBlock) && !beforeAllBlock.includes("// isolation-ok")) {
|
|
728
|
+
issues.push({
|
|
729
|
+
file,
|
|
730
|
+
line: i + 1,
|
|
731
|
+
type: "beforeAll-page-access",
|
|
732
|
+
severity: "warning",
|
|
733
|
+
message: "Accessing page in beforeAll can cause parallel execution issues",
|
|
734
|
+
suggestion: "Use beforeEach for page setup, or add // isolation-ok comment if intentional",
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
return {
|
|
741
|
+
name: "E2E Test Isolation",
|
|
742
|
+
passed: true, // Non-blocking
|
|
743
|
+
blocking: false,
|
|
744
|
+
issues,
|
|
745
|
+
duration: Date.now() - startTime,
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Check 9: Selector Stability
|
|
750
|
+
* Detects brittle selectors that can cause flaky tests
|
|
751
|
+
*/
|
|
752
|
+
async checkSelectorStability() {
|
|
753
|
+
const startTime = Date.now();
|
|
754
|
+
const issues = [];
|
|
755
|
+
const files = await getE2ESpecFiles();
|
|
756
|
+
const brittlePatterns = [
|
|
757
|
+
{
|
|
758
|
+
pattern: /locator\s*\(\s*['"`]\.[\w-]+['"`]\s*\)/g,
|
|
759
|
+
name: "class-selector",
|
|
760
|
+
message: "Class selectors are brittle",
|
|
761
|
+
},
|
|
762
|
+
{
|
|
763
|
+
pattern: /locator\s*\(\s*['"`]div\s*>\s*div/g,
|
|
764
|
+
name: "nested-div",
|
|
765
|
+
message: "Nested div selectors are very brittle",
|
|
766
|
+
},
|
|
767
|
+
{
|
|
768
|
+
pattern: /locator\s*\(\s*['"`]#(?!root|app|__next)[\w-]+['"`]\s*\)/g,
|
|
769
|
+
name: "id-selector",
|
|
770
|
+
message: "ID selectors can be brittle (prefer data-testid)",
|
|
771
|
+
},
|
|
772
|
+
{
|
|
773
|
+
pattern: /:nth-child\s*\(/g,
|
|
774
|
+
name: "nth-child",
|
|
775
|
+
message: "nth-child selectors break when order changes",
|
|
776
|
+
},
|
|
777
|
+
{
|
|
778
|
+
pattern: /\[class\*?=/g,
|
|
779
|
+
name: "class-attribute",
|
|
780
|
+
message: "Class attribute selectors are brittle",
|
|
781
|
+
},
|
|
782
|
+
];
|
|
783
|
+
for (const file of files) {
|
|
784
|
+
const content = fs.readFileSync(file, "utf8");
|
|
785
|
+
const lines = content.split("\n");
|
|
786
|
+
for (const { pattern, name, message } of brittlePatterns) {
|
|
787
|
+
let match;
|
|
788
|
+
const regex = new RegExp(pattern.source, pattern.flags);
|
|
789
|
+
while ((match = regex.exec(content)) !== null) {
|
|
790
|
+
const lineNum = content.substring(0, match.index).split("\n").length;
|
|
791
|
+
// Allow suppression with comment on same line or up to 3 lines before
|
|
792
|
+
const lineIndex = lineNum - 1;
|
|
793
|
+
const contextStart = Math.max(0, lineIndex - 3);
|
|
794
|
+
const contextEnd = Math.min(lineIndex + 1, lines.length);
|
|
795
|
+
const context = lines.slice(contextStart, contextEnd).join("\n");
|
|
796
|
+
if (context.includes("selector-ok") || context.includes("e2e-allow")) {
|
|
797
|
+
continue;
|
|
798
|
+
}
|
|
799
|
+
issues.push({
|
|
800
|
+
file,
|
|
801
|
+
line: lineNum,
|
|
802
|
+
type: name,
|
|
803
|
+
severity: "info",
|
|
804
|
+
message,
|
|
805
|
+
suggestion: "Use getByRole, getByLabel, getByTestId, or getByText instead",
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
return {
|
|
811
|
+
name: "E2E Selector Stability",
|
|
812
|
+
passed: true, // Non-blocking (info only)
|
|
813
|
+
blocking: false,
|
|
814
|
+
issues,
|
|
815
|
+
duration: Date.now() - startTime,
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
/**
|
|
819
|
+
* Check 10: Critical Route Coverage
|
|
820
|
+
* Ensures critical user paths have E2E test coverage
|
|
821
|
+
*/
|
|
822
|
+
async checkCriticalRouteCoverage() {
|
|
823
|
+
const startTime = Date.now();
|
|
824
|
+
const issues = [];
|
|
825
|
+
const files = await getE2ESpecFiles();
|
|
826
|
+
// Build a map of routes tested
|
|
827
|
+
const testedRoutes = new Map();
|
|
828
|
+
for (const file of files) {
|
|
829
|
+
const content = fs.readFileSync(file, "utf8");
|
|
830
|
+
// Find goto() calls - supports both page.goto() and goto(page, url) patterns
|
|
831
|
+
// Pattern 1: page.goto("/route") or page.goto('/route') or page.goto(`/route`)
|
|
832
|
+
// Pattern 2: goto(page, "/route") - custom helper pattern
|
|
833
|
+
const gotoPatterns = [
|
|
834
|
+
/page\.goto\s*\(\s*['"`]([^'"`]+)['"`]/g,
|
|
835
|
+
/goto\s*\(\s*page\s*,\s*['"`]([^'"`]+)['"`]/g,
|
|
836
|
+
/goto\s*\(\s*['"`]([^'"`]+)['"`]/g,
|
|
837
|
+
];
|
|
838
|
+
for (const pattern of gotoPatterns) {
|
|
839
|
+
const gotoMatches = Array.from(content.matchAll(pattern));
|
|
840
|
+
for (const match of gotoMatches) {
|
|
841
|
+
const route = match[1] ?? "";
|
|
842
|
+
for (const criticalRoute of CRITICAL_ROUTES_REQUIRING_TESTS) {
|
|
843
|
+
if (route.startsWith(criticalRoute.route) || route.includes(criticalRoute.route)) {
|
|
844
|
+
testedRoutes.set(criticalRoute.route, (testedRoutes.get(criticalRoute.route) ?? 0) + 1);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
// Check which critical routes lack coverage
|
|
851
|
+
for (const { route, minTests, severity } of CRITICAL_ROUTES_REQUIRING_TESTS) {
|
|
852
|
+
const testCount = testedRoutes.get(route) ?? 0;
|
|
853
|
+
if (testCount < minTests) {
|
|
854
|
+
issues.push({
|
|
855
|
+
file: "tests/e2e/",
|
|
856
|
+
line: 0,
|
|
857
|
+
type: "missing-route-coverage",
|
|
858
|
+
severity: severity === "critical" ? "error" : "warning",
|
|
859
|
+
message: `Critical route "${route}" has ${testCount}/${minTests} required E2E tests`,
|
|
860
|
+
suggestion: `Add E2E tests that navigate to and verify ${route} functionality`,
|
|
861
|
+
});
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
const hasErrors = issues.some((i) => i.severity === "error");
|
|
865
|
+
return {
|
|
866
|
+
name: "E2E Critical Route Coverage",
|
|
867
|
+
passed: !hasErrors || this.warnOnly,
|
|
868
|
+
blocking: !this.warnOnly,
|
|
869
|
+
issues,
|
|
870
|
+
duration: Date.now() - startTime,
|
|
871
|
+
};
|
|
872
|
+
}
|
|
873
|
+
/**
|
|
874
|
+
* Run all checks
|
|
875
|
+
*/
|
|
876
|
+
async runAll() {
|
|
877
|
+
const checks = [];
|
|
878
|
+
checks.push(await this.checkBestPractices());
|
|
879
|
+
checks.push(await this.checkOutcomeValidation());
|
|
880
|
+
checks.push(await this.checkFlakePatterns());
|
|
881
|
+
checks.push(await this.checkTimeoutLimits());
|
|
882
|
+
checks.push(await this.checkPerformancePatterns());
|
|
883
|
+
checks.push(await this.checkTestOrganization());
|
|
884
|
+
checks.push(await this.checkAssertionQuality());
|
|
885
|
+
checks.push(await this.checkTestIsolation());
|
|
886
|
+
checks.push(await this.checkSelectorStability());
|
|
887
|
+
checks.push(await this.checkCriticalRouteCoverage());
|
|
888
|
+
const passed = checks.every((c) => c.passed || !c.blocking);
|
|
889
|
+
const totalDuration = checks.reduce((sum, c) => sum + c.duration, 0);
|
|
890
|
+
const allIssues = checks.flatMap((c) => c.issues);
|
|
891
|
+
const errors = allIssues.filter((i) => i.severity === "error").length;
|
|
892
|
+
const warnings = allIssues.filter((i) => i.severity === "warning").length;
|
|
893
|
+
return {
|
|
894
|
+
module: "E2E Validation",
|
|
895
|
+
passed,
|
|
896
|
+
totalDuration,
|
|
897
|
+
checks,
|
|
898
|
+
summary: {
|
|
899
|
+
total: checks.length,
|
|
900
|
+
passed: checks.filter((c) => c.passed).length,
|
|
901
|
+
failed: checks.filter((c) => !c.passed).length,
|
|
902
|
+
errors,
|
|
903
|
+
warnings,
|
|
904
|
+
},
|
|
905
|
+
};
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
exports.E2EValidationModule = E2EValidationModule;
|
|
909
|
+
// CLI
|
|
910
|
+
async function main() {
|
|
911
|
+
const args = process.argv.slice(2);
|
|
912
|
+
const subCommand = args.find((a) => !a.startsWith("--"));
|
|
913
|
+
const warnOnly = args.includes("--warn");
|
|
914
|
+
const verbose = args.includes("--verbose");
|
|
915
|
+
console.log(`\n${console_chars_1.emoji.search} E2E Validation Preflight (Consolidated)\n`);
|
|
916
|
+
console.log((0, console_chars_1.createDivider)(70, "heavy"));
|
|
917
|
+
const module = new E2EValidationModule({ verbose, warnOnly });
|
|
918
|
+
let result;
|
|
919
|
+
switch (subCommand) {
|
|
920
|
+
case "best-practices":
|
|
921
|
+
result = await module.checkBestPractices();
|
|
922
|
+
break;
|
|
923
|
+
case "outcomes":
|
|
924
|
+
result = await module.checkOutcomeValidation();
|
|
925
|
+
break;
|
|
926
|
+
case "flakes":
|
|
927
|
+
result = await module.checkFlakePatterns();
|
|
928
|
+
break;
|
|
929
|
+
case "timeouts":
|
|
930
|
+
result = await module.checkTimeoutLimits();
|
|
931
|
+
break;
|
|
932
|
+
case "performance":
|
|
933
|
+
result = await module.checkPerformancePatterns();
|
|
934
|
+
break;
|
|
935
|
+
case "organization":
|
|
936
|
+
result = await module.checkTestOrganization();
|
|
937
|
+
break;
|
|
938
|
+
case "assertions":
|
|
939
|
+
case "assertion-quality":
|
|
940
|
+
result = await module.checkAssertionQuality();
|
|
941
|
+
break;
|
|
942
|
+
case "isolation":
|
|
943
|
+
result = await module.checkTestIsolation();
|
|
944
|
+
break;
|
|
945
|
+
case "selectors":
|
|
946
|
+
case "selector-stability":
|
|
947
|
+
result = await module.checkSelectorStability();
|
|
948
|
+
break;
|
|
949
|
+
case "coverage":
|
|
950
|
+
case "route-coverage":
|
|
951
|
+
result = await module.checkCriticalRouteCoverage();
|
|
952
|
+
break;
|
|
953
|
+
default:
|
|
954
|
+
result = await module.runAll();
|
|
955
|
+
}
|
|
956
|
+
// Report results
|
|
957
|
+
if ("checks" in result) {
|
|
958
|
+
// Full module result
|
|
959
|
+
const moduleResult = result;
|
|
960
|
+
for (const check of moduleResult.checks) {
|
|
961
|
+
const status = check.passed ? console_chars_1.emoji.success : check.blocking ? console_chars_1.emoji.error : console_chars_1.emoji.warning;
|
|
962
|
+
console.log(`\n${status} ${check.name} (${check.duration}ms)`);
|
|
963
|
+
if (check.issues.length > 0 && (verbose || !check.passed)) {
|
|
964
|
+
const displayIssues = verbose ? check.issues : check.issues.slice(0, 5);
|
|
965
|
+
for (const issue of displayIssues) {
|
|
966
|
+
const icon = issue.severity === "error" ? console_chars_1.emoji.error : console_chars_1.emoji.warning;
|
|
967
|
+
console.log(` ${icon} ${path.basename(issue.file)}:${issue.line} - ${issue.message}`);
|
|
968
|
+
}
|
|
969
|
+
if (!verbose && check.issues.length > 5) {
|
|
970
|
+
console.log(` ... and ${check.issues.length - 5} more issues`);
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
}
|
|
974
|
+
console.log(`\n${(0, console_chars_1.createDivider)(70, "heavy")}`);
|
|
975
|
+
console.log(`${console_chars_1.emoji.chart} Summary: ${moduleResult.summary.passed}/${moduleResult.summary.total} checks passed`);
|
|
976
|
+
console.log(` Errors: ${moduleResult.summary.errors}, Warnings: ${moduleResult.summary.warnings}`);
|
|
977
|
+
console.log(` Duration: ${moduleResult.totalDuration}ms`);
|
|
978
|
+
if (!moduleResult.passed) {
|
|
979
|
+
console.log(`\n${console_chars_1.emoji.error} E2E validation failed\n`);
|
|
980
|
+
process.exit(1);
|
|
981
|
+
}
|
|
982
|
+
else {
|
|
983
|
+
console.log(`\n${console_chars_1.emoji.success} E2E validation passed\n`);
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
else {
|
|
987
|
+
// Single check result
|
|
988
|
+
const checkResult = result;
|
|
989
|
+
const status = checkResult.passed ? console_chars_1.emoji.success : console_chars_1.emoji.error;
|
|
990
|
+
console.log(`\n${status} ${checkResult.name} (${checkResult.duration}ms)`);
|
|
991
|
+
console.log(` Issues: ${checkResult.issues.length}`);
|
|
992
|
+
if (!checkResult.passed) {
|
|
993
|
+
process.exit(1);
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
main().catch((err) => {
|
|
998
|
+
console.error(`${console_chars_1.emoji.error} E2E validation crashed:`, err);
|
|
999
|
+
process.exit(1);
|
|
1000
|
+
});
|
|
1001
|
+
//# sourceMappingURL=e2e-validation.js.map
|