|
| 1 | +/** |
| 2 | + * Browser-Specific Configuration for E2E Tests |
| 3 | + * |
| 4 | + * This module centralizes all browser-specific settings, timeouts, and quirk flags. |
| 5 | + * Import these configurations in test utilities and test files to handle cross-browser |
| 6 | + * differences consistently. |
| 7 | + * |
| 8 | + * Key browser differences addressed: |
| 9 | + * - Firefox: Slower CSS rendering, NS_BINDING_ABORTED errors during navigation |
| 10 | + * - WebKit: Delayed element rendering, localStorage timing issues |
| 11 | + * - Mobile: Touch events required, smaller viewports need scroll handling |
| 12 | + */ |
| 13 | + |
| 14 | +/** |
| 15 | + * Browser-specific timeout configurations |
| 16 | + * |
| 17 | + * Chromium is the baseline. Other browsers have multipliers applied based on |
| 18 | + * observed performance characteristics. |
| 19 | + * |
| 20 | + * - Firefox: +50% for CSS rendering and form validation |
| 21 | + * - WebKit: +40% for element stabilization and animations |
| 22 | + * - Mobile: +50% for touch event registration and viewport adjustments |
| 23 | + */ |
| 24 | +export const BROWSER_TIMEOUTS = { |
| 25 | + chromium: { |
| 26 | + action: 10000, // Default actionTimeout |
| 27 | + expect: 5000, // Default expect timeout |
| 28 | + navigation: 30000, // Page navigation timeout |
| 29 | + formValidation: 3000, |
| 30 | + animation: 500, |
| 31 | + }, |
| 32 | + firefox: { |
| 33 | + action: 15000, // +50% for slower CSS rendering |
| 34 | + expect: 8000, // +60% for async form validation |
| 35 | + navigation: 45000, // +50% for network handling |
| 36 | + formValidation: 5000, // Firefox renders validation messages asynchronously |
| 37 | + animation: 800, // CSS transitions take longer |
| 38 | + }, |
| 39 | + webkit: { |
| 40 | + action: 14000, // +40% for element stabilization |
| 41 | + expect: 7000, // +40% for delayed rendering |
| 42 | + navigation: 40000, // +33% for Safari's network stack |
| 43 | + formValidation: 4000, |
| 44 | + animation: 700, // WebKit animation timing differences |
| 45 | + }, |
| 46 | + mobile: { |
| 47 | + action: 15000, // +50% for touch event registration |
| 48 | + expect: 10000, // +100% for viewport stabilization |
| 49 | + navigation: 60000, // +100% for mobile network handling |
| 50 | + formValidation: 5000, |
| 51 | + animation: 1000, // Mobile animations may be slower |
| 52 | + }, |
| 53 | +} as const; |
| 54 | + |
| 55 | +/** |
| 56 | + * Browser quirk flags |
| 57 | + * |
| 58 | + * These flags indicate which workarounds are needed for each browser. |
| 59 | + * Use these to conditionally apply browser-specific handling in tests. |
| 60 | + */ |
| 61 | +export const BROWSER_QUIRKS = { |
| 62 | + firefox: { |
| 63 | + /** Firefox needs extra wait for async form validation rendering */ |
| 64 | + needsFormValidationWait: true, |
| 65 | + /** Firefox's NS_BINDING_ABORTED error during navigation is benign */ |
| 66 | + hasNSBindingAborted: true, |
| 67 | + /** Firefox may need reducedMotion for consistent animation timing */ |
| 68 | + needsReducedMotion: true, |
| 69 | + /** Firefox click events may need explicit wait for element stability */ |
| 70 | + needsClickStability: false, |
| 71 | + /** Firefox localStorage is synchronous but needs reload for visibility */ |
| 72 | + hasDelayedLocalStorage: false, |
| 73 | + }, |
| 74 | + webkit: { |
| 75 | + /** WebKit elements may not be stable immediately after appearing */ |
| 76 | + needsElementStabilityWait: true, |
| 77 | + /** WebKit localStorage writes may not be immediately readable */ |
| 78 | + hasDelayedLocalStorage: true, |
| 79 | + /** WebKit forms need click-then-fill pattern for reliable input */ |
| 80 | + needsClickBeforeFill: true, |
| 81 | + /** WebKit animations need explicit completion wait */ |
| 82 | + needsAnimationWait: true, |
| 83 | + /** WebKit needs extra time after navigation for DOM stability */ |
| 84 | + needsPostNavigationWait: true, |
| 85 | + }, |
| 86 | + mobile: { |
| 87 | + /** Mobile browsers require touch events instead of mouse clicks */ |
| 88 | + needsTouchEvents: true, |
| 89 | + /** Mobile viewports need scroll into view before interaction */ |
| 90 | + requiresScrollIntoView: true, |
| 91 | + /** Mobile may have hamburger menu instead of full navigation */ |
| 92 | + hasResponsiveMenu: true, |
| 93 | + /** Mobile viewport may need stabilization after orientation/resize */ |
| 94 | + needsViewportStabilization: true, |
| 95 | + /** Some features are desktop-only (hover states, etc.) */ |
| 96 | + hasLimitedFeatures: true, |
| 97 | + }, |
| 98 | + chromium: { |
| 99 | + /** Chromium is the baseline - no special handling needed */ |
| 100 | + needsFormValidationWait: false, |
| 101 | + hasNSBindingAborted: false, |
| 102 | + needsElementStabilityWait: false, |
| 103 | + hasDelayedLocalStorage: false, |
| 104 | + needsTouchEvents: false, |
| 105 | + requiresScrollIntoView: false, |
| 106 | + }, |
| 107 | +} as const; |
| 108 | + |
| 109 | +/** |
| 110 | + * Error patterns to filter by browser |
| 111 | + * |
| 112 | + * These are errors that appear in specific browsers but are not actual failures. |
| 113 | + * Use with filterExpectedErrors() in test-utils.ts. |
| 114 | + */ |
| 115 | +export const BROWSER_EXPECTED_ERRORS = { |
| 116 | + firefox: [ |
| 117 | + 'NS_BINDING_ABORTED', // Normal during navigation |
| 118 | + 'AbortError', // Request abort during navigation |
| 119 | + 'NetworkError when attempting', // Sometimes appears during fast navigation |
| 120 | + ], |
| 121 | + webkit: [ |
| 122 | + 'Failed to load resource', // Sometimes appears during rapid navigation |
| 123 | + 'Load request cancelled', // WebKit's equivalent of NS_BINDING_ABORTED |
| 124 | + 'cancelled', // Generic cancellation error |
| 125 | + ], |
| 126 | + mobile: [ |
| 127 | + 'touch-action', // Touch action warnings |
| 128 | + ], |
| 129 | + chromium: [], // Baseline - no special filtering |
| 130 | + all: [ |
| 131 | + 'net::ERR_ABORTED', // Normal when navigation cancels pending requests |
| 132 | + 'Failed to fetch RSC payload', // Next.js RSC during navigation |
| 133 | + ], |
| 134 | +} as const; |
| 135 | + |
| 136 | +/** |
| 137 | + * Mobile device viewport configurations |
| 138 | + * |
| 139 | + * These match Playwright's device definitions but are exported here for |
| 140 | + * custom viewport handling in tests. |
| 141 | + */ |
| 142 | +export const MOBILE_VIEWPORTS = { |
| 143 | + 'Mobile Chrome': { width: 393, height: 851, isMobile: true, hasTouch: true }, |
| 144 | + 'Mobile Safari': { width: 390, height: 844, isMobile: true, hasTouch: true }, |
| 145 | + 'Pixel 5': { width: 393, height: 851, isMobile: true, hasTouch: true }, |
| 146 | + 'iPhone 12': { width: 390, height: 844, isMobile: true, hasTouch: true }, |
| 147 | + 'iPhone 13': { width: 390, height: 844, isMobile: true, hasTouch: true }, |
| 148 | + 'Galaxy S21': { width: 360, height: 800, isMobile: true, hasTouch: true }, |
| 149 | +} as const; |
| 150 | + |
| 151 | +/** |
| 152 | + * Browser project names as used in Playwright config |
| 153 | + */ |
| 154 | +export const BROWSER_PROJECTS = { |
| 155 | + CHROMIUM: 'chromium', |
| 156 | + FIREFOX: 'firefox', |
| 157 | + WEBKIT: 'webkit', |
| 158 | + MOBILE_CHROME: 'Mobile Chrome', |
| 159 | + MOBILE_SAFARI: 'Mobile Safari', |
| 160 | +} as const; |
| 161 | + |
| 162 | +export type BrowserName = 'chromium' | 'firefox' | 'webkit'; |
| 163 | +export type MobileProjectName = 'Mobile Chrome' | 'Mobile Safari'; |
| 164 | +export type ProjectName = BrowserName | MobileProjectName; |
0 commit comments