Skip to content

Commit 2ac6c16

Browse files
committed
Update expectations to use resolves for response body
This gives better error output containing the response body.
1 parent a42cb01 commit 2ac6c16

20 files changed

Lines changed: 248 additions & 179 deletions

tests/e2e/backup-workflow.test.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -689,8 +689,9 @@ describe('Backup Workflow E2E', () => {
689689

690690
// Should fail with 400 (BACKUP_EXPIRED)
691691
expect(restoreResponse.status).toBe(400);
692-
const errorResult = (await restoreResponse.json()) as ErrorResponse;
693-
expect(errorResult.code).toBe('BACKUP_EXPIRED');
692+
await expect(restoreResponse.json()).resolves.toEqual(
693+
expect.objectContaining({ code: 'BACKUP_EXPIRED' })
694+
);
694695

695696
// Cleanup (unmounts FUSE overlay if present, then removes directory)
696697
await cleanupDir(workerUrl, headers, TEST_DIR);
@@ -715,8 +716,9 @@ describe('Backup Workflow E2E', () => {
715716

716717
// Should fail with 404 (BACKUP_NOT_FOUND)
717718
expect(restoreResponse.status).toBe(404);
718-
const errorResult = (await restoreResponse.json()) as ErrorResponse;
719-
expect(errorResult.code).toBe('BACKUP_NOT_FOUND');
719+
await expect(restoreResponse.json()).resolves.toEqual(
720+
expect.objectContaining({ code: 'BACKUP_NOT_FOUND' })
721+
);
720722
}, 30000);
721723

722724
test('should reject invalid backup ID format', async () => {

tests/e2e/bucket-mounting.test.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,9 @@ describe('Bucket Mounting E2E', () => {
9696
signal: AbortSignal.timeout(500)
9797
});
9898
expect(mountResponse.ok).toBe(true);
99-
const mountResult = (await mountResponse.json()) as SuccessResponse;
100-
expect(mountResult.success).toBe(true);
99+
await expect(mountResponse.json()).resolves.toEqual(
100+
expect.objectContaining({ success: true })
101+
);
101102

102103
// 3. Verify pre-existing R2 file appears in mount (R2 → Mount)
103104
const readPreExistingResponse = await fetch(
@@ -125,8 +126,9 @@ describe('Bucket Mounting E2E', () => {
125126
}),
126127
signal: AbortSignal.timeout(500)
127128
});
128-
const writeResult = (await writeResponse.json()) as ExecResult;
129-
expect(writeResult.exitCode).toBe(0);
129+
await expect(writeResponse.json()).resolves.toEqual(
130+
expect.objectContaining({ exitCode: 0 })
131+
);
130132

131133
// 5. Verify new file appears in R2 via binding (Mount → R2)
132134
const getResponse = await fetch(

tests/e2e/build-test-workflow.test.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import type { ExecResult, ReadFileResult, WriteFileResult } from '@repo/shared';
21
import { afterAll, beforeAll, describe, expect, test } from 'vitest';
32
import {
43
cleanupTestSandbox,
@@ -87,8 +86,11 @@ describe('Build and Test Workflow', () => {
8786
});
8887

8988
expect(pwdResponse.status).toBe(200);
90-
const pwdData = (await pwdResponse.json()) as ExecResult;
91-
expect(pwdData.stdout).toMatch(/\/workspace/);
89+
await expect(pwdResponse.json()).resolves.toEqual(
90+
expect.objectContaining({
91+
stdout: expect.stringMatching(/\/workspace/)
92+
})
93+
);
9294
});
9395

9496
test('should detect shell termination when exit command is used', async () => {

tests/e2e/code-interpreter-workflow.test.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,9 @@ describe('Code Interpreter Workflow (E2E)', () => {
105105
// Delete Python context
106106
const deleteResponse = await deleteContext(pythonCtx.id);
107107
expect(deleteResponse.status).toBe(200);
108-
const deleteData = (await deleteResponse.json()) as { success: boolean };
109-
expect(deleteData.success).toBe(true);
108+
await expect(deleteResponse.json()).resolves.toEqual(
109+
expect.objectContaining({ success: true })
110+
);
110111

111112
// Verify context is removed from list
112113
const listAfterDelete = await fetch(`${workerUrl}/api/code/context/list`, {
@@ -469,8 +470,9 @@ for i in range(3):
469470
signal: AbortSignal.timeout(500)
470471
});
471472
expect(fakeContextExec.status).toBeGreaterThanOrEqual(400);
472-
const fakeContextError = (await fakeContextExec.json()) as ErrorResponse;
473-
expect(fakeContextError.error).toBeTruthy();
473+
await expect(fakeContextExec.json()).resolves.toEqual(
474+
expect.objectContaining({ error: expect.anything() })
475+
);
474476

475477
// Delete non-existent context
476478
await fetch(`${workerUrl}/api/execute`, {
@@ -481,13 +483,12 @@ for i in range(3):
481483
});
482484
const deleteFakeResponse = await fetch(
483485
`${workerUrl}/api/code/context/fake-id-99999`,
484-
{ method: 'DELETE', headers,
485-
signal: AbortSignal.timeout(500)
486-
}
486+
{ method: 'DELETE', headers, signal: AbortSignal.timeout(500) }
487487
);
488488
expect(deleteFakeResponse.status).toBeGreaterThanOrEqual(400);
489-
const deleteFakeError = (await deleteFakeResponse.json()) as ErrorResponse;
490-
expect(deleteFakeError.error).toBeTruthy();
489+
await expect(deleteFakeResponse.json()).resolves.toEqual(
490+
expect.objectContaining({ error: expect.anything() })
491+
);
491492

492493
// Python unavailable on base image
493494
// Use base image headers (without python type) for this specific test

tests/e2e/command-timeout.test.ts

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import type {
2-
ExecResult,
3-
SessionCreateResult,
4-
SessionDeleteResult
5-
} from '@repo/shared';
1+
import type { ExecResult, SessionCreateResult } from '@repo/shared';
62
import { afterAll, beforeAll, describe, expect, test } from 'vitest';
73
import {
84
cleanupTestSandbox,
@@ -11,7 +7,6 @@ import {
117
type TestSandbox
128
} from './helpers/global-sandbox';
139
import { createTestHeaders } from './helpers/test-fixtures';
14-
import type { ErrorResponse } from './test-worker/types';
1510

1611
// Diagnostic instrumentation for #482 flake investigation.
1712
// Remove once root cause is confirmed.
@@ -65,9 +60,11 @@ describe('Command Timeout', () => {
6560
const elapsed = Date.now() - startTime;
6661

6762
expect(response.status).toBe(500);
68-
const data = (await response.json()) as ErrorResponse;
69-
expect(data.error).toBeDefined();
70-
expect(data.error).toMatch(/timeout/i);
63+
await expect(response.json()).resolves.toEqual(
64+
expect.objectContaining({
65+
error: expect.stringMatching(/timeout/i)
66+
})
67+
);
7168

7269
// Command timeout is 1s — elapsed should be well under 15s even with CI latency
7370
expect(elapsed).toBeLessThan(15000);
@@ -108,9 +105,11 @@ describe('Command Timeout', () => {
108105
const elapsed = Date.now() - startTime;
109106

110107
expect(execResponse.status).toBe(500);
111-
const execData = (await execResponse.json()) as ErrorResponse;
112-
expect(execData.error).toBeDefined();
113-
expect(execData.error).toMatch(/timeout/i);
108+
await expect(execResponse.json()).resolves.toEqual(
109+
expect.objectContaining({
110+
error: expect.stringMatching(/timeout/i)
111+
})
112+
);
114113

115114
// Command timeout is 1s — elapsed should be well under 15s even with CI latency
116115
expect(elapsed).toBeLessThan(15000);
@@ -153,9 +152,11 @@ describe('Command Timeout', () => {
153152
const elapsed = Date.now() - startTime;
154153

155154
expect(execResponse.status).toBe(500);
156-
const execData = (await execResponse.json()) as ErrorResponse;
157-
expect(execData.error).toBeDefined();
158-
expect(execData.error).toMatch(/timeout/i);
155+
await expect(execResponse.json()).resolves.toEqual(
156+
expect.objectContaining({
157+
error: expect.stringMatching(/timeout/i)
158+
})
159+
);
159160

160161
// Session-level timeout is 1s — elapsed should be well under 15s even with CI latency
161162
expect(elapsed).toBeLessThan(15000);
@@ -201,8 +202,11 @@ describe('Command Timeout', () => {
201202
const elapsed = Date.now() - startTime;
202203

203204
expect(execResponse.status).toBe(500);
204-
const execData = (await execResponse.json()) as ErrorResponse;
205-
expect(execData.error).toMatch(/timeout/i);
205+
await expect(execResponse.json()).resolves.toEqual(
206+
expect.objectContaining({
207+
error: expect.stringMatching(/timeout/i)
208+
})
209+
);
206210

207211
// Should have timed out in ~1s, not ~30s
208212
expect(elapsed).toBeLessThan(10000);
@@ -247,8 +251,11 @@ describe('Command Timeout', () => {
247251
const elapsed = Date.now() - startTime;
248252

249253
expect(execResponse.status).toBe(500);
250-
const execData = (await execResponse.json()) as ErrorResponse;
251-
expect(execData.error).toMatch(/timeout/i);
254+
await expect(execResponse.json()).resolves.toEqual(
255+
expect.objectContaining({
256+
error: expect.stringMatching(/timeout/i)
257+
})
258+
);
252259

253260
// Command timeout is 1s — elapsed should be well under 15s even with CI latency
254261
expect(elapsed).toBeLessThan(15000);
@@ -282,8 +289,9 @@ describe('Command Timeout', () => {
282289
);
283290

284291
expect(deleteResponse.status).toBe(200);
285-
const deleteData = (await deleteResponse.json()) as SessionDeleteResult;
286-
expect(deleteData.success).toBe(true);
292+
await expect(deleteResponse.json()).resolves.toEqual(
293+
expect.objectContaining({ success: true })
294+
);
287295

288296
// Wait briefly for process cleanup after session destruction
289297
await new Promise((resolve) => setTimeout(resolve, 1000));

tests/e2e/comprehensive-workflow.test.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,9 @@ describe('Comprehensive Workflow', () => {
100100
});
101101

102102
expect(cloneResponse.status).toBe(200);
103-
const cloneData = (await cloneResponse.json()) as GitCheckoutResult;
104-
expect(cloneData.success).toBe(true);
103+
await expect(cloneResponse.json()).resolves.toEqual(
104+
expect.objectContaining({ success: true })
105+
);
105106

106107
// Verify repo structure using listFiles
107108
const listResponse = await fetch(`${workerUrl}/api/list-files`, {
@@ -128,8 +129,9 @@ describe('Comprehensive Workflow', () => {
128129
});
129130

130131
expect(readReadmeResponse.status).toBe(200);
131-
const readmeData = (await readReadmeResponse.json()) as ReadFileResult;
132-
expect(readmeData.content).toContain('Hello');
132+
await expect(readReadmeResponse.json()).resolves.toEqual(
133+
expect.objectContaining({ content: expect.stringContaining('Hello') })
134+
);
133135

134136
// Create a new directory structure
135137
const mkdirResponse = await fetch(`${workerUrl}/api/file/mkdir`, {
@@ -209,8 +211,9 @@ export function greet(name) {
209211
});
210212

211213
expect(readRenamedResponse.status).toBe(200);
212-
const renamedData = (await readRenamedResponse.json()) as ReadFileResult;
213-
expect(renamedData.content).toContain('greet');
214+
await expect(readRenamedResponse.json()).resolves.toEqual(
215+
expect.objectContaining({ content: expect.stringContaining('greet') })
216+
);
214217

215218
// Phase 3: Run commands with environment
216219

tests/e2e/desktop-environment.test.ts

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,8 @@ type DesktopScreenshotResult = {
1919
width: number;
2020
height: number;
2121
};
22-
type SuccessResult = { success: boolean };
23-
type ScreenSizeResult = { success: boolean; width: number; height: number };
2422
type CursorPositionResult = { success: boolean; x: number; y: number };
2523
type StreamUrlResult = { url: string };
26-
type ErrorResult = { error: string };
2724

2825
const skipPortExposureTests =
2926
process.env.TEST_WORKER_URL?.endsWith('.workers.dev') ?? false;
@@ -109,8 +106,9 @@ describe('Desktop Environment', () => {
109106
});
110107

111108
expect(response.status).toBe(200);
112-
const data = (await response.json()) as SuccessResult;
113-
expect(data.success).toBe(true);
109+
await expect(response.json()).resolves.toEqual(
110+
expect.objectContaining({ success: true })
111+
);
114112
}, 15000);
115113

116114
test('should type text', async () => {
@@ -122,8 +120,9 @@ describe('Desktop Environment', () => {
122120
});
123121

124122
expect(response.status).toBe(200);
125-
const data = (await response.json()) as SuccessResult;
126-
expect(data.success).toBe(true);
123+
await expect(response.json()).resolves.toEqual(
124+
expect.objectContaining({ success: true })
125+
);
127126
}, 15000);
128127

129128
test('should press key combination', async () => {
@@ -135,8 +134,9 @@ describe('Desktop Environment', () => {
135134
});
136135

137136
expect(response.status).toBe(200);
138-
const data = (await response.json()) as SuccessResult;
139-
expect(data.success).toBe(true);
137+
await expect(response.json()).resolves.toEqual(
138+
expect.objectContaining({ success: true })
139+
);
140140
}, 15000);
141141

142142
test('should return screen size matching configured resolution', async () => {
@@ -147,12 +147,9 @@ describe('Desktop Environment', () => {
147147
});
148148

149149
expect(response.status).toBe(200);
150-
const data = (await response.json()) as ScreenSizeResult;
151-
expect(data.success).toBe(true);
152-
expect(data.width).toBeGreaterThan(0);
153-
expect(data.height).toBeGreaterThan(0);
154-
expect(data.width).toBe(1024);
155-
expect(data.height).toBe(768);
150+
await expect(response.json()).resolves.toEqual(
151+
expect.objectContaining({ success: true, width: 1024, height: 768 })
152+
);
156153
}, 15000);
157154

158155
test('should return valid cursor coordinates', async () => {
@@ -199,8 +196,9 @@ describe('Desktop Environment', () => {
199196
});
200197

201198
expect(response.status).toBe(200);
202-
const data = (await response.json()) as SuccessResult;
203-
expect(data.success).toBe(true);
199+
await expect(response.json()).resolves.toEqual(
200+
expect.objectContaining({ success: true })
201+
);
204202

205203
const posResponse = await fetch(
206204
`${workerUrl}/api/desktop/cursor/position`,
@@ -231,8 +229,9 @@ describe('Desktop Environment', () => {
231229
signal: AbortSignal.timeout(1000)
232230
});
233231

234-
const statusData = (await statusResponse.json()) as DesktopStatusResult;
235-
expect(statusData.status).toBe('active');
232+
await expect(statusResponse.json()).resolves.toEqual(
233+
expect.objectContaining({ status: 'active' })
234+
);
236235

237236
await fetch(`${workerUrl}/api/desktop/stop`, {
238237
method: 'POST',
@@ -249,8 +248,9 @@ describe('Desktop Environment', () => {
249248
});
250249

251250
expect(stopResponse.status).toBe(200);
252-
const stopData = (await stopResponse.json()) as SuccessResult;
253-
expect(stopData.success).toBe(true);
251+
await expect(stopResponse.json()).resolves.toEqual(
252+
expect.objectContaining({ success: true })
253+
);
254254

255255
const statusResponse = await fetch(`${workerUrl}/api/desktop/status`, {
256256
method: 'GET',
@@ -259,8 +259,9 @@ describe('Desktop Environment', () => {
259259
});
260260

261261
expect(statusResponse.status).toBe(200);
262-
const statusData = (await statusResponse.json()) as DesktopStatusResult;
263-
expect(statusData.status).toBe('inactive');
262+
await expect(statusResponse.json()).resolves.toEqual(
263+
expect.objectContaining({ status: 'inactive' })
264+
);
264265

265266
// Assert that attempting to make a request to a stopped instance fails.
266267
const response = await fetch(`${workerUrl}/api/desktop/screenshot`, {
@@ -271,7 +272,8 @@ describe('Desktop Environment', () => {
271272
});
272273

273274
expect(response.status).toBeGreaterThanOrEqual(400);
274-
const data = (await response.json()) as ErrorResult;
275-
expect(data.error).toBeDefined();
275+
await expect(response.json()).resolves.toEqual(
276+
expect.objectContaining({ error: expect.anything() })
277+
);
276278
}, 15000);
277279
});

tests/e2e/environment-workflow.test.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,9 @@ describe('Environment Variables', () => {
226226
});
227227

228228
expect(catResponse.status).toBe(200);
229-
const catData = (await catResponse.json()) as ExecResult;
230-
expect(catData.success).toBe(true);
231-
expect(catData.stdout).toBe('');
229+
await expect(catResponse.json()).resolves.toEqual(
230+
expect.objectContaining({ success: true, stdout: '' })
231+
);
232232

233233
// Test 2: bash read command should return immediately
234234
const readResponse = await fetch(`${workerUrl}/api/execute`, {
@@ -256,8 +256,9 @@ describe('Environment Variables', () => {
256256
});
257257

258258
expect(grepResponse.status).toBe(200);
259-
const grepData = (await grepResponse.json()) as ExecResult;
260-
expect(grepData.success).toBe(true);
259+
await expect(grepResponse.json()).resolves.toEqual(
260+
expect.objectContaining({ success: true })
261+
);
261262
}, 90000);
262263

263264
test('should handle null as unset in setEnvVars', async () => {

0 commit comments

Comments
 (0)