Skip to content

Commit 99be21c

Browse files
committed
get tests in a working state
1 parent 5357a54 commit 99be21c

File tree

63 files changed

+530
-265
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+530
-265
lines changed

epicshop/mcp-dev/dev.js

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,9 @@ async function startServers() {
206206
process: devServer,
207207
textMatch: mcpServerPort.toString(),
208208
name: '[DEV-SERVER]',
209-
}),
209+
}).then(() =>
210+
waitForResourceReady(`http://localhost:${mcpServerPort}/healthcheck`),
211+
),
210212
waitForServerReady({
211213
process: inspector,
212214
textMatch: inspectorClientPort.toString(),
@@ -360,3 +362,41 @@ async function main() {
360362
}
361363

362364
main()
365+
366+
function waitForResourceReady(resourceUrl) {
367+
const timeoutSignal = AbortSignal.timeout(10_000)
368+
let lastError = null
369+
return new Promise((resolve, reject) => {
370+
timeoutSignal.addEventListener('abort', () => {
371+
const error = lastError ?? new Error('No other errors detected')
372+
error.message = `Timed out waiting for ${resourceUrl}:\n Last Error:${error.message}`
373+
reject(error)
374+
})
375+
async function checkResource() {
376+
try {
377+
const response = await fetch(resourceUrl)
378+
if (response.ok) return resolve()
379+
} catch (error) {
380+
lastError = error instanceof Error ? error : new Error(String(error))
381+
}
382+
await sleep(100, timeoutSignal)
383+
await checkResource()
384+
}
385+
return checkResource()
386+
})
387+
}
388+
389+
function sleep(ms, signal) {
390+
return new Promise((resolve, reject) => {
391+
const timeout = setTimeout(() => {
392+
signal?.removeEventListener('abort', onAbort)
393+
resolve()
394+
}, ms)
395+
396+
function onAbort() {
397+
clearTimeout(timeout)
398+
reject(new Error('Sleep aborted'))
399+
}
400+
signal?.addEventListener('abort', onAbort)
401+
})
402+
}

exercises/01.simple/01.problem.raw-html/test/globalSetup.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -130,18 +130,14 @@ export default async function setup(project: TestProject) {
130130

131131
// Start the MCP server from the exercise directory
132132
console.log(`Starting MCP server on port ${mcpServerPort}...`)
133-
mcpServerProcess = execa(
134-
'npx',
135-
['wrangler', 'dev', '--port', mcpServerPort.toString()],
136-
{
137-
cwd: process.cwd(),
138-
stdio: ['ignore', 'pipe', 'pipe'],
139-
env: {
140-
...process.env,
141-
PORT: mcpServerPort.toString(),
142-
},
133+
mcpServerProcess = execa('npm', ['run', 'dev:server', '--silent'], {
134+
cwd: process.cwd(),
135+
stdio: ['ignore', 'pipe', 'pipe'],
136+
env: {
137+
...process.env,
138+
PORT: mcpServerPort.toString(),
143139
},
144-
)
140+
})
145141

146142
try {
147143
// Wait for both servers to be ready simultaneously
@@ -161,7 +157,9 @@ export default async function setup(project: TestProject) {
161157
textMatch: mcpServerPort.toString(),
162158
name: '[MCP-SERVER]',
163159
outputBuffer: mcpServerOutput,
164-
}),
160+
}).then(() =>
161+
waitForResourceReady(`http://localhost:${mcpServerPort}/healthcheck`),
162+
),
165163
])
166164

167165
console.log('Servers started successfully')

exercises/01.simple/01.problem.raw-html/worker/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ export default {
1010
}).fetch(request, env, ctx)
1111
}
1212

13+
if (url.pathname === '/healthcheck') {
14+
return new Response('OK', { status: 200 })
15+
}
16+
1317
return new Response('Not found', { status: 404 })
1418
},
1519
}

exercises/01.simple/01.solution.raw-html/test/globalSetup.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -130,18 +130,14 @@ export default async function setup(project: TestProject) {
130130

131131
// Start the MCP server from the exercise directory
132132
console.log(`Starting MCP server on port ${mcpServerPort}...`)
133-
mcpServerProcess = execa(
134-
'npx',
135-
['wrangler', 'dev', '--port', mcpServerPort.toString()],
136-
{
137-
cwd: process.cwd(),
138-
stdio: ['ignore', 'pipe', 'pipe'],
139-
env: {
140-
...process.env,
141-
PORT: mcpServerPort.toString(),
142-
},
133+
mcpServerProcess = execa('npm', ['run', 'dev:server', '--silent'], {
134+
cwd: process.cwd(),
135+
stdio: ['ignore', 'pipe', 'pipe'],
136+
env: {
137+
...process.env,
138+
PORT: mcpServerPort.toString(),
143139
},
144-
)
140+
})
145141

146142
try {
147143
// Wait for both servers to be ready simultaneously
@@ -161,7 +157,9 @@ export default async function setup(project: TestProject) {
161157
textMatch: mcpServerPort.toString(),
162158
name: '[MCP-SERVER]',
163159
outputBuffer: mcpServerOutput,
164-
}),
160+
}).then(() =>
161+
waitForResourceReady(`http://localhost:${mcpServerPort}/healthcheck`),
162+
),
165163
])
166164

167165
console.log('Servers started successfully')

exercises/01.simple/01.solution.raw-html/worker/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ export default {
1010
}).fetch(request, env, ctx)
1111
}
1212

13+
if (url.pathname === '/healthcheck') {
14+
return new Response('OK', { status: 200 })
15+
}
16+
1317
return new Response('Not found', { status: 404 })
1418
},
1519
}

exercises/02.consistent/01.problem.remote-dom/test/globalSetup.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -130,18 +130,14 @@ export default async function setup(project: TestProject) {
130130

131131
// Start the MCP server from the exercise directory
132132
console.log(`Starting MCP server on port ${mcpServerPort}...`)
133-
mcpServerProcess = execa(
134-
'npx',
135-
['wrangler', 'dev', '--port', mcpServerPort.toString()],
136-
{
137-
cwd: process.cwd(),
138-
stdio: ['ignore', 'pipe', 'pipe'],
139-
env: {
140-
...process.env,
141-
PORT: mcpServerPort.toString(),
142-
},
133+
mcpServerProcess = execa('npm', ['run', 'dev:server', '--silent'], {
134+
cwd: process.cwd(),
135+
stdio: ['ignore', 'pipe', 'pipe'],
136+
env: {
137+
...process.env,
138+
PORT: mcpServerPort.toString(),
143139
},
144-
)
140+
})
145141

146142
try {
147143
// Wait for both servers to be ready simultaneously
@@ -161,7 +157,9 @@ export default async function setup(project: TestProject) {
161157
textMatch: mcpServerPort.toString(),
162158
name: '[MCP-SERVER]',
163159
outputBuffer: mcpServerOutput,
164-
}),
160+
}).then(() =>
161+
waitForResourceReady(`http://localhost:${mcpServerPort}/healthcheck`),
162+
),
165163
])
166164

167165
console.log('Servers started successfully')

exercises/02.consistent/01.problem.remote-dom/worker/index.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ export default {
1010
}).fetch(request, env, ctx)
1111
}
1212

13+
if (url.pathname === '/healthcheck') {
14+
return new Response('OK', { status: 200 })
15+
}
16+
1317
return new Response('Not found', { status: 404 })
1418
},
1519
}

exercises/02.consistent/01.solution.remote-dom/test/globalSetup.ts

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -130,18 +130,14 @@ export default async function setup(project: TestProject) {
130130

131131
// Start the MCP server from the exercise directory
132132
console.log(`Starting MCP server on port ${mcpServerPort}...`)
133-
mcpServerProcess = execa(
134-
'npx',
135-
['wrangler', 'dev', '--port', mcpServerPort.toString()],
136-
{
137-
cwd: process.cwd(),
138-
stdio: ['ignore', 'pipe', 'pipe'],
139-
env: {
140-
...process.env,
141-
PORT: mcpServerPort.toString(),
142-
},
133+
mcpServerProcess = execa('npm', ['run', 'dev:server', '--silent'], {
134+
cwd: process.cwd(),
135+
stdio: ['ignore', 'pipe', 'pipe'],
136+
env: {
137+
...process.env,
138+
PORT: mcpServerPort.toString(),
143139
},
144-
)
140+
})
145141

146142
try {
147143
// Wait for both servers to be ready simultaneously
@@ -161,7 +157,9 @@ export default async function setup(project: TestProject) {
161157
textMatch: mcpServerPort.toString(),
162158
name: '[MCP-SERVER]',
163159
outputBuffer: mcpServerOutput,
164-
}),
160+
}).then(() =>
161+
waitForResourceReady(`http://localhost:${mcpServerPort}/healthcheck`),
162+
),
165163
])
166164

167165
console.log('Servers started successfully')

exercises/02.consistent/01.solution.remote-dom/worker/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@ import { EpicMeMCP } from './mcp/index.ts'
33
export default {
44
fetch: async (request: Request, env: Env, ctx: ExecutionContext) => {
55
const url = new URL(request.url)
6+
67
if (url.pathname === '/mcp') {
78
return EpicMeMCP.serve('/mcp', {
89
binding: 'EPIC_ME_MCP_OBJECT',
910
}).fetch(request, env, ctx)
1011
}
1112

13+
if (url.pathname === '/healthcheck') {
14+
return new Response('OK', { status: 200 })
15+
}
16+
1217
return new Response('Not found', { status: 404 })
1318
},
1419
}

exercises/03.complex/01.problem.iframe/app/routes.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { type RouteConfig, index, route } from '@react-router/dev/routes'
22

33
export default [
44
index('routes/index.tsx'),
5+
route('healthcheck', 'routes/healthcheck.tsx'),
56
route('ui/journal-viewer', 'routes/ui/journal-viewer.tsx'),
67
route('/*', 'routes/catch-all.tsx'),
78
] satisfies RouteConfig

0 commit comments

Comments
 (0)