Skip to content

Commit 364e0fd

Browse files
committed
fix: move MSW setup to --require preload for v2 compatibility
MSW v2 interceptors break when bundled by esbuild (Remix server build). Move MSW setup from entry.server.tsx to a --require preload script (mocks/setup.cjs) that runs before Remix boots, ensuring fetch interception works correctly for e2e tests.
1 parent 80e7d50 commit 364e0fd

3 files changed

Lines changed: 64 additions & 8 deletions

File tree

app/entry.server.tsx

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,9 @@ import type { EntryContext } from '@remix-run/node'
22
import { RemixServer } from '@remix-run/react'
33
import { renderToString } from 'react-dom/server'
44

5-
// Start MSW mock server in E2E mode to intercept external API calls
6-
if (process.env.RUNNING_E2E === 'true') {
7-
// Dynamic import to avoid bundling MSW in production
8-
// eslint-disable-next-line @typescript-eslint/no-var-requires
9-
require('../mocks/server').startMockServer()
10-
}
5+
// MSW mock server for E2E tests is loaded via --require preload (mocks/setup.cjs)
6+
// to ensure interceptors are installed before the Remix server boots.
7+
// See start:e2e script in package.json.
118

129
export default function handleRequest(
1310
request: Request,

mocks/setup.cjs

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* MSW v2 preload script for E2E tests.
3+
*
4+
* MSW v2 interceptors must run as native Node modules — they break when
5+
* bundled by esbuild (Remix server build). Loading via --require ensures
6+
* interceptors are installed before the Remix server boots.
7+
*/
8+
if (process.env.RUNNING_E2E === 'true') {
9+
const { setupServer } = require('msw/node')
10+
const { http, HttpResponse } = require('msw')
11+
const fs = require('fs')
12+
const path = require('path')
13+
14+
const MAGIC_LINK_FIXTURE_PATH = path.join(
15+
__dirname,
16+
'../e2e/fixtures/magic.local.json'
17+
)
18+
19+
function extractMagicLink(html) {
20+
const match = html.match(/href="([^"]*magic[^"]*)"/)
21+
return match ? match[1] : null
22+
}
23+
24+
const server = setupServer(
25+
http.post(
26+
'https://api.mailgun.net/v3/:domain/messages',
27+
async ({ request, params }) => {
28+
const body = Object.fromEntries(
29+
new URLSearchParams(await request.text())
30+
)
31+
console.info('🔶 MSW intercepted email request:', {
32+
to: body.to,
33+
subject: body.subject,
34+
})
35+
36+
if (body.html) {
37+
const magicLink = extractMagicLink(body.html)
38+
if (magicLink) {
39+
console.info('🔶 Captured magic link:', magicLink)
40+
fs.writeFileSync(
41+
MAGIC_LINK_FIXTURE_PATH,
42+
JSON.stringify({ magicLink }, null, 2)
43+
)
44+
}
45+
}
46+
47+
const randomId = '20210321210543.1.E01B8B612C44B41B'
48+
const id = `<${randomId}>@${String(params.domain)}`
49+
return HttpResponse.json({ id, message: 'Queued. Thank you.' })
50+
}
51+
)
52+
)
53+
54+
server.listen({ onUnhandledRequest: 'warn' })
55+
console.info('🔶 MSW mock server installed (via --require preload)')
56+
57+
process.once('SIGINT', () => server.close())
58+
process.once('SIGTERM', () => server.close())
59+
}

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,12 @@
2020
"prepare": "husky install",
2121
"start": "remix-serve build",
2222
"prestart:e2e": "DATABASE_URL=file:./test.db prisma migrate reset --force && npm run build:css",
23-
"start:e2e": "cross-env RUNNING_E2E=true DATABASE_URL=file:./test.db remix dev",
23+
"start:e2e": "cross-env RUNNING_E2E=true DATABASE_URL=file:./test.db NODE_OPTIONS='--require ./mocks/setup.cjs' remix dev",
2424
"test": "vitest run",
2525
"test:coverage": "vitest run --coverage",
2626
"test:watch": "vitest",
2727
"test:e2e": "playwright test",
28-
"test:e2e:dev": "cross-env RUNNING_E2E=true start-server-and-test dev http-get://localhost:3000/ test:e2e",
28+
"test:e2e:dev": "cross-env RUNNING_E2E=true NODE_OPTIONS='--require ./mocks/setup.cjs' start-server-and-test dev http-get://localhost:3000/ test:e2e",
2929
"test:e2e:run": "cross-env RUNNING_E2E=true DATABASE_URL=file:./test.db start-server-and-test start:e2e http-get://localhost:3000/ test:e2e",
3030
"test:e2e:docker": "playwright test --config=playwright.docker.config.ts",
3131
"test:e2e:staging": "playwright test --config=playwright.staging.config.ts",

0 commit comments

Comments
 (0)