|
| 1 | +import { runInNewContext } from 'node:vm' |
| 2 | +import { describe, expect, it } from 'vitest' |
| 3 | +import { hmrSseBridgeClientScript, shouldUseHmrSseBridge } from '../src/hmr-sse-bridge' |
| 4 | + |
| 5 | +const userAgents = { |
| 6 | + macosSafari: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.6 Safari/605.1.15', |
| 7 | + iphoneSafari: 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.6 Mobile/15E148 Safari/604.1', |
| 8 | + ipadSafari: 'Mozilla/5.0 (iPad; CPU OS 18_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.6 Mobile/15E148 Safari/604.1', |
| 9 | + macosChrome: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36', |
| 10 | + iphoneChrome: 'Mozilla/5.0 (iPhone; CPU iPhone OS 18_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/140.0.0.0 Mobile/15E148 Safari/604.1', |
| 11 | + macosFirefox: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:142.0) Gecko/20100101 Firefox/142.0', |
| 12 | + windowsSafari: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2', |
| 13 | +} |
| 14 | + |
| 15 | +describe('shouldUseHmrSseBridge', () => { |
| 16 | + it('only enables the bridge for Safari on macOS and iOS over HTTPS', () => { |
| 17 | + const result = Object.fromEntries( |
| 18 | + Object.entries(userAgents).map(([browser, userAgent]) => [ |
| 19 | + browser, |
| 20 | + shouldUseHmrSseBridge('https:', userAgent), |
| 21 | + ]), |
| 22 | + ) |
| 23 | + |
| 24 | + expect(result).toMatchInlineSnapshot(` |
| 25 | + { |
| 26 | + "ipadSafari": true, |
| 27 | + "iphoneChrome": false, |
| 28 | + "iphoneSafari": true, |
| 29 | + "macosChrome": false, |
| 30 | + "macosFirefox": false, |
| 31 | + "macosSafari": true, |
| 32 | + "windowsSafari": false, |
| 33 | + } |
| 34 | + `) |
| 35 | + }) |
| 36 | + |
| 37 | + it('keeps native WebSocket on HTTP', () => { |
| 38 | + expect(shouldUseHmrSseBridge('http:', userAgents.macosSafari)).toBe(false) |
| 39 | + }) |
| 40 | + |
| 41 | + it('uses the same guard in the injected client script', () => { |
| 42 | + function isWebSocketPatched(userAgent: string): boolean { |
| 43 | + const OriginalWebSocket = function WebSocket() {} |
| 44 | + const context = { |
| 45 | + location: { protocol: 'https:' }, |
| 46 | + navigator: { userAgent }, |
| 47 | + window: { WebSocket: OriginalWebSocket }, |
| 48 | + } |
| 49 | + |
| 50 | + runInNewContext(hmrSseBridgeClientScript, context) |
| 51 | + |
| 52 | + return context.window.WebSocket !== OriginalWebSocket |
| 53 | + } |
| 54 | + |
| 55 | + expect({ |
| 56 | + macosChrome: isWebSocketPatched(userAgents.macosChrome), |
| 57 | + macosSafari: isWebSocketPatched(userAgents.macosSafari), |
| 58 | + }).toMatchInlineSnapshot(` |
| 59 | + { |
| 60 | + "macosChrome": false, |
| 61 | + "macosSafari": true, |
| 62 | + } |
| 63 | + `) |
| 64 | + }) |
| 65 | +}) |
0 commit comments