Skip to content

Commit 5a27d36

Browse files
committed
fix(e2e): set MCPMUX_E2E_TEST=1 in wdio.conf.ts for consent endpoint
The previous commit gated /oauth/consent/approve behind the MCPMUX_E2E_TEST env var but the e2e test runner was not passing it to the tauri-driver process. This caused streamable-http tests to fail because obtainAccessToken() and approveOAuthClient() both depend on test-only endpoints. https://claude.ai/code/session_019gtFefwPpKWZH73DEyUpE2 Signed-off-by: Claude <noreply@anthropic.com>
1 parent 326c0e4 commit 5a27d36

1 file changed

Lines changed: 83 additions & 41 deletions

File tree

tests/e2e/wdio.conf.ts

Lines changed: 83 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ function checkTauriDriver(): boolean {
8080
}
8181
}
8282

83-
8483
// Clear the app's SQLite database and related files for a clean start
8584
function clearAppData(): void {
8685
const filesToDelete = [
@@ -125,7 +124,7 @@ function clearBundleCache(): void {
125124
async function waitForServer(port: number, name: string, timeout = 30000): Promise<void> {
126125
const start = Date.now();
127126
const healthUrl = `http://localhost:${port}/health`;
128-
127+
129128
while (Date.now() - start < timeout) {
130129
try {
131130
const response = await fetch(healthUrl);
@@ -138,44 +137,68 @@ async function waitForServer(port: number, name: string, timeout = 30000): Promi
138137
}
139138
await new Promise((resolve) => setTimeout(resolve, 200));
140139
}
141-
140+
142141
throw new Error(`[e2e] ${name} failed to start within ${timeout}ms`);
143142
}
144143

145144
// Start mock servers
146145
async function startMockServers(): Promise<void> {
147146
const mocksDir = path.resolve('./tests/e2e/mocks');
148-
147+
149148
// Start Mock Bundle API
150149
console.log('[e2e] Starting Mock Bundle API...');
151-
mockBundleApi = spawn('pnpm', ['exec', 'tsx', path.join(mocksDir, 'mock-bundle-api', 'server.ts')], {
152-
env: { ...process.env, PORT: String(MOCK_BUNDLE_API_PORT) },
153-
stdio: ['ignore', 'pipe', 'pipe'],
154-
shell: true,
155-
});
156-
mockBundleApi.stdout?.on('data', (data) => console.log(`[mock-bundle-api] ${data.toString().trim()}`));
157-
mockBundleApi.stderr?.on('data', (data) => console.error(`[mock-bundle-api] ${data.toString().trim()}`));
158-
150+
mockBundleApi = spawn(
151+
'pnpm',
152+
['exec', 'tsx', path.join(mocksDir, 'mock-bundle-api', 'server.ts')],
153+
{
154+
env: { ...process.env, PORT: String(MOCK_BUNDLE_API_PORT) },
155+
stdio: ['ignore', 'pipe', 'pipe'],
156+
shell: true,
157+
}
158+
);
159+
mockBundleApi.stdout?.on('data', (data) =>
160+
console.log(`[mock-bundle-api] ${data.toString().trim()}`)
161+
);
162+
mockBundleApi.stderr?.on('data', (data) =>
163+
console.error(`[mock-bundle-api] ${data.toString().trim()}`)
164+
);
165+
159166
// Start Stub MCP HTTP Server
160167
console.log('[e2e] Starting Stub MCP HTTP Server...');
161-
stubMcpHttp = spawn('pnpm', ['exec', 'tsx', path.join(mocksDir, 'stub-mcp-server', 'http-server.ts')], {
162-
env: { ...process.env, PORT: String(STUB_MCP_HTTP_PORT) },
163-
stdio: ['ignore', 'pipe', 'pipe'],
164-
shell: true,
165-
});
166-
stubMcpHttp.stdout?.on('data', (data) => console.log(`[stub-mcp-http] ${data.toString().trim()}`));
167-
stubMcpHttp.stderr?.on('data', (data) => console.error(`[stub-mcp-http] ${data.toString().trim()}`));
168-
168+
stubMcpHttp = spawn(
169+
'pnpm',
170+
['exec', 'tsx', path.join(mocksDir, 'stub-mcp-server', 'http-server.ts')],
171+
{
172+
env: { ...process.env, PORT: String(STUB_MCP_HTTP_PORT) },
173+
stdio: ['ignore', 'pipe', 'pipe'],
174+
shell: true,
175+
}
176+
);
177+
stubMcpHttp.stdout?.on('data', (data) =>
178+
console.log(`[stub-mcp-http] ${data.toString().trim()}`)
179+
);
180+
stubMcpHttp.stderr?.on('data', (data) =>
181+
console.error(`[stub-mcp-http] ${data.toString().trim()}`)
182+
);
183+
169184
// Start Stub MCP OAuth Server
170185
console.log('[e2e] Starting Stub MCP OAuth Server...');
171-
stubMcpOauth = spawn('pnpm', ['exec', 'tsx', path.join(mocksDir, 'stub-mcp-server', 'http-oauth-server.ts')], {
172-
env: { ...process.env, PORT: String(STUB_MCP_OAUTH_PORT) },
173-
stdio: ['ignore', 'pipe', 'pipe'],
174-
shell: true,
175-
});
176-
stubMcpOauth.stdout?.on('data', (data) => console.log(`[stub-mcp-oauth] ${data.toString().trim()}`));
177-
stubMcpOauth.stderr?.on('data', (data) => console.error(`[stub-mcp-oauth] ${data.toString().trim()}`));
178-
186+
stubMcpOauth = spawn(
187+
'pnpm',
188+
['exec', 'tsx', path.join(mocksDir, 'stub-mcp-server', 'http-oauth-server.ts')],
189+
{
190+
env: { ...process.env, PORT: String(STUB_MCP_OAUTH_PORT) },
191+
stdio: ['ignore', 'pipe', 'pipe'],
192+
shell: true,
193+
}
194+
);
195+
stubMcpOauth.stdout?.on('data', (data) =>
196+
console.log(`[stub-mcp-oauth] ${data.toString().trim()}`)
197+
);
198+
stubMcpOauth.stderr?.on('data', (data) =>
199+
console.error(`[stub-mcp-oauth] ${data.toString().trim()}`)
200+
);
201+
179202
// Wait for all servers to be ready
180203
await Promise.all([
181204
waitForServer(MOCK_BUNDLE_API_PORT, 'Mock Bundle API'),
@@ -239,7 +262,14 @@ function killPortProcesses(): void {
239262
try {
240263
if (process.platform === 'win32') {
241264
// Find PIDs listening on this port and kill them
242-
const result = spawnSync('cmd', ['/c', `for /f "tokens=5" %a in ('netstat -ano ^| findstr ":${port} " ^| findstr LISTEN') do taskkill /F /PID %a`], { stdio: 'pipe', shell: true });
265+
const result = spawnSync(
266+
'cmd',
267+
[
268+
'/c',
269+
`for /f "tokens=5" %a in ('netstat -ano ^| findstr ":${port} " ^| findstr LISTEN') do taskkill /F /PID %a`,
270+
],
271+
{ stdio: 'pipe', shell: true }
272+
);
243273
if (result.stdout?.toString().includes('SUCCESS')) {
244274
console.log(`[e2e] Killed process on port ${port}`);
245275
}
@@ -338,22 +368,30 @@ export const config: Options.Testrunner = {
338368
framework: 'mocha',
339369
reporters: [
340370
'spec',
341-
['junit', {
342-
outputDir: './tests/e2e/reports/',
343-
outputFileFormat: function(options) {
344-
return `wdio-junit-${options.cid}.xml`;
371+
[
372+
'junit',
373+
{
374+
outputDir: './tests/e2e/reports/',
375+
outputFileFormat: function (options) {
376+
return `wdio-junit-${options.cid}.xml`;
377+
},
345378
},
346-
}],
379+
],
347380
// Only enable video reporter when explicitly requested via SAVE_ALL_VIDEOS=true.
348381
// The video reporter takes a screenshot after every WebDriver command, including
349382
// during session teardown. This races with deleteSession killing the Tauri app,
350383
// causing UND_ERR_SOCKET errors that mark passing specs as FAILED.
351384
...(process.env.SAVE_ALL_VIDEOS === 'true'
352-
? [[video, {
353-
saveAllVideos: true,
354-
videoSlowdownMultiplier: 1,
355-
outputDir: './tests/e2e/videos/',
356-
}]]
385+
? [
386+
[
387+
video,
388+
{
389+
saveAllVideos: true,
390+
videoSlowdownMultiplier: 1,
391+
outputDir: './tests/e2e/videos/',
392+
},
393+
],
394+
]
357395
: []),
358396
],
359397

@@ -363,7 +401,7 @@ export const config: Options.Testrunner = {
363401
},
364402

365403
// Take screenshot on test failure
366-
afterTest: async function(test, context, { error }) {
404+
afterTest: async function (test, context, { error }) {
367405
if (error) {
368406
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
369407
// Sanitize test title: replace invalid filename chars (NTFS: " : < > | * ? \r \n) and spaces
@@ -458,12 +496,16 @@ export const config: Options.Testrunner = {
458496
process.platform === 'win32' ? 'tauri-driver.exe' : 'tauri-driver'
459497
);
460498

461-
// Pass registry URL environment variable to tauri-driver (which passes to the app)
499+
// Pass environment variables to tauri-driver (which passes to the app)
500+
// MCPMUX_E2E_TEST=1 enables test-only endpoints:
501+
// - POST /oauth/consent/approve (HTTP consent for programmatic OAuth flow)
502+
// - approve_oauth_client Tauri IPC command
462503
tauriDriver = spawn(tauriDriverPath, [], {
463504
stdio: [null, process.stdout, process.stderr],
464505
env: {
465506
...process.env,
466507
MCPMUX_REGISTRY_URL: `http://localhost:${MOCK_BUNDLE_API_PORT}`,
508+
MCPMUX_E2E_TEST: '1',
467509
},
468510
});
469511

0 commit comments

Comments
 (0)