Skip to content

Commit 396df64

Browse files
patnikoCopilot
andcommitted
Fix E2E tests: add missing onPermissionRequest, fix assertions, fix promise leak
- Add onPermissionRequest: approveAll to all createSession()/resumeSession() calls in new E2E test files (CI blocker) - Fix no-op assertion in client_lifecycle.test.ts (was testing lambda return) - Fix weak assertion in tool_results.test.ts (now checks 'service is down') - Fix resumeSession in error_resilience.test.ts (was missing required arg) - Fix hanging Promise leak in replayingCapiProxy.ts (return without await) - Add TODO comment on skipped Compaction test suite Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 2ee58d5 commit 396df64

12 files changed

Lines changed: 60 additions & 40 deletions

nodejs/test/e2e/builtin_tools.test.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55
import { writeFile, mkdir } from "fs/promises";
66
import { join } from "path";
77
import { describe, expect, it } from "vitest";
8+
import { approveAll } from "../../src/index.js";
89
import { createSdkTestContext } from "./harness/sdkTestContext";
910

1011
describe("Built-in Tools", async () => {
1112
const { copilotClient: client, workDir } = await createSdkTestContext();
1213

1314
describe("bash", () => {
1415
it("should capture exit code in output", async () => {
15-
const session = await client.createSession();
16+
const session = await client.createSession({ onPermissionRequest: approveAll });
1617
const msg = await session.sendAndWait({
1718
prompt: "Run 'echo hello && echo world'. Tell me the exact output.",
1819
});
@@ -21,7 +22,7 @@ describe("Built-in Tools", async () => {
2122
});
2223

2324
it("should capture stderr output", async () => {
24-
const session = await client.createSession();
25+
const session = await client.createSession({ onPermissionRequest: approveAll });
2526
const msg = await session.sendAndWait({
2627
prompt: "Run 'echo error_msg >&2; echo ok' and tell me what stderr said. Reply with just the stderr content.",
2728
});
@@ -32,7 +33,7 @@ describe("Built-in Tools", async () => {
3233
describe("view", () => {
3334
it("should read file with line range", async () => {
3435
await writeFile(join(workDir, "lines.txt"), "line1\nline2\nline3\nline4\nline5\n");
35-
const session = await client.createSession();
36+
const session = await client.createSession({ onPermissionRequest: approveAll });
3637
const msg = await session.sendAndWait({
3738
prompt: "Read lines 2 through 4 of the file 'lines.txt' in this directory. Tell me what those lines contain.",
3839
});
@@ -41,7 +42,7 @@ describe("Built-in Tools", async () => {
4142
});
4243

4344
it("should handle nonexistent file gracefully", async () => {
44-
const session = await client.createSession();
45+
const session = await client.createSession({ onPermissionRequest: approveAll });
4546
const msg = await session.sendAndWait({
4647
prompt: "Try to read the file 'does_not_exist.txt'. If it doesn't exist, say 'FILE_NOT_FOUND'.",
4748
});
@@ -54,7 +55,7 @@ describe("Built-in Tools", async () => {
5455
describe("edit", () => {
5556
it("should edit a file successfully", async () => {
5657
await writeFile(join(workDir, "edit_me.txt"), "Hello World\nGoodbye World\n");
57-
const session = await client.createSession();
58+
const session = await client.createSession({ onPermissionRequest: approveAll });
5859
const msg = await session.sendAndWait({
5960
prompt: "Edit the file 'edit_me.txt': replace 'Hello World' with 'Hi Universe'. Then read it back and tell me its contents.",
6061
});
@@ -64,7 +65,7 @@ describe("Built-in Tools", async () => {
6465

6566
describe("create_file", () => {
6667
it("should create a new file", async () => {
67-
const session = await client.createSession();
68+
const session = await client.createSession({ onPermissionRequest: approveAll });
6869
const msg = await session.sendAndWait({
6970
prompt: "Create a file called 'new_file.txt' with the content 'Created by test'. Then read it back to confirm.",
7071
});
@@ -75,7 +76,7 @@ describe("Built-in Tools", async () => {
7576
describe("grep", () => {
7677
it("should search for patterns in files", async () => {
7778
await writeFile(join(workDir, "data.txt"), "apple\nbanana\napricot\ncherry\n");
78-
const session = await client.createSession();
79+
const session = await client.createSession({ onPermissionRequest: approveAll });
7980
const msg = await session.sendAndWait({
8081
prompt: "Search for lines starting with 'ap' in the file 'data.txt'. Tell me which lines matched.",
8182
});
@@ -90,7 +91,7 @@ describe("Built-in Tools", async () => {
9091
await writeFile(join(workDir, "src", "app.ts"), "export const app = 1;");
9192
await writeFile(join(workDir, "src", "index.ts"), "export const index = 1;");
9293
await writeFile(join(workDir, "README.md"), "# Readme");
93-
const session = await client.createSession();
94+
const session = await client.createSession({ onPermissionRequest: approveAll });
9495
const msg = await session.sendAndWait({
9596
prompt: "Find all .ts files in this directory (recursively). List the filenames you found.",
9697
});

nodejs/test/e2e/client_lifecycle.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
*--------------------------------------------------------------------------------------------*/
44

55
import { describe, expect, it } from "vitest";
6-
import { SessionLifecycleEvent } from "../../src/index.js";
6+
import { SessionLifecycleEvent, approveAll } from "../../src/index.js";
77
import { createSdkTestContext } from "./harness/sdkTestContext";
88

99
describe("Client Lifecycle", async () => {
1010
const { copilotClient: client } = await createSdkTestContext();
1111

1212
it("should return last session id after sending a message", async () => {
13-
const session = await client.createSession();
13+
const session = await client.createSession({ onPermissionRequest: approveAll });
1414

1515
await session.sendAndWait({ prompt: "Say hello" });
1616

@@ -26,7 +26,7 @@ describe("Client Lifecycle", async () => {
2626
it("should return undefined for getLastSessionId with no sessions", async () => {
2727
// On a fresh client this may return undefined or an older session ID
2828
const lastSessionId = await client.getLastSessionId();
29-
expect(() => lastSessionId).not.toThrow();
29+
expect(lastSessionId === undefined || typeof lastSessionId === "string").toBe(true);
3030
});
3131

3232
it("should emit session lifecycle events", async () => {
@@ -36,7 +36,7 @@ describe("Client Lifecycle", async () => {
3636
});
3737

3838
try {
39-
const session = await client.createSession();
39+
const session = await client.createSession({ onPermissionRequest: approveAll });
4040

4141
await session.sendAndWait({ prompt: "Say hello" });
4242

nodejs/test/e2e/compaction.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
22
import { SessionEvent, approveAll } from "../../src/index.js";
33
import { createSdkTestContext } from "./harness/sdkTestContext.js";
44

5+
// TODO: Compaction tests are skipped due to flakiness — re-enable once stabilized
56
describe.skip("Compaction", async () => {
67
const { copilotClient: client } = await createSdkTestContext();
78

nodejs/test/e2e/error_resilience.test.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,28 @@
33
*--------------------------------------------------------------------------------------------*/
44

55
import { describe, expect, it } from "vitest";
6+
import { approveAll } from "../../src/index.js";
67
import { createSdkTestContext } from "./harness/sdkTestContext";
78

89
describe("Error Resilience", async () => {
910
const { copilotClient: client } = await createSdkTestContext();
1011

1112
it("should throw when sending to destroyed session", async () => {
12-
const session = await client.createSession();
13+
const session = await client.createSession({ onPermissionRequest: approveAll });
1314
await session.destroy();
1415

1516
await expect(session.sendAndWait({ prompt: "Hello" })).rejects.toThrow();
1617
});
1718

1819
it("should throw when getting messages from destroyed session", async () => {
19-
const session = await client.createSession();
20+
const session = await client.createSession({ onPermissionRequest: approveAll });
2021
await session.destroy();
2122

2223
await expect(session.getMessages()).rejects.toThrow();
2324
});
2425

2526
it("should handle double abort without error", async () => {
26-
const session = await client.createSession();
27+
const session = await client.createSession({ onPermissionRequest: approveAll });
2728

2829
// First abort should be fine
2930
await session.abort();
@@ -35,6 +36,6 @@ describe("Error Resilience", async () => {
3536
});
3637

3738
it("should throw when resuming non-existent session", async () => {
38-
await expect(client.resumeSession("non-existent-session-id-12345")).rejects.toThrow();
39+
await expect(client.resumeSession("non-existent-session-id-12345", { onPermissionRequest: approveAll })).rejects.toThrow();
3940
});
4041
});

nodejs/test/e2e/event_fidelity.test.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import { writeFile } from "fs/promises";
66
import { join } from "path";
77
import { describe, expect, it } from "vitest";
8-
import { SessionEvent } from "../../src/index.js";
8+
import { SessionEvent, approveAll } from "../../src/index.js";
99
import { createSdkTestContext } from "./harness/sdkTestContext";
1010

1111
describe("Event Fidelity", async () => {
@@ -14,7 +14,7 @@ describe("Event Fidelity", async () => {
1414
it("should emit events in correct order for tool-using conversation", async () => {
1515
await writeFile(join(workDir, "hello.txt"), "Hello World");
1616

17-
const session = await client.createSession();
17+
const session = await client.createSession({ onPermissionRequest: approveAll });
1818
const events: SessionEvent[] = [];
1919
session.on((event) => {
2020
events.push(event);
@@ -43,7 +43,7 @@ describe("Event Fidelity", async () => {
4343
});
4444

4545
it("should include valid fields on all events", async () => {
46-
const session = await client.createSession();
46+
const session = await client.createSession({ onPermissionRequest: approveAll });
4747
const events: SessionEvent[] = [];
4848
session.on((event) => {
4949
events.push(event);
@@ -80,7 +80,7 @@ describe("Event Fidelity", async () => {
8080
it("should emit tool execution events with correct fields", async () => {
8181
await writeFile(join(workDir, "data.txt"), "test data");
8282

83-
const session = await client.createSession();
83+
const session = await client.createSession({ onPermissionRequest: approveAll });
8484
const events: SessionEvent[] = [];
8585
session.on((event) => {
8686
events.push(event);
@@ -110,7 +110,7 @@ describe("Event Fidelity", async () => {
110110
});
111111

112112
it("should emit assistant.message with messageId", async () => {
113-
const session = await client.createSession();
113+
const session = await client.createSession({ onPermissionRequest: approveAll });
114114
const events: SessionEvent[] = [];
115115
session.on((event) => {
116116
events.push(event);

nodejs/test/e2e/hooks_extended.test.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*--------------------------------------------------------------------------------------------*/
44

55
import { describe, expect, it } from "vitest";
6+
import { approveAll } from "../../src/index.js";
67
import type {
78
ErrorOccurredHookInput,
89
SessionEndHookInput,
@@ -18,6 +19,7 @@ describe("Extended session hooks", async () => {
1819
const sessionStartInputs: SessionStartHookInput[] = [];
1920

2021
const session = await client.createSession({
22+
onPermissionRequest: approveAll,
2123
hooks: {
2224
onSessionStart: async (input, invocation) => {
2325
sessionStartInputs.push(input);
@@ -42,6 +44,7 @@ describe("Extended session hooks", async () => {
4244
const userPromptInputs: UserPromptSubmittedHookInput[] = [];
4345

4446
const session = await client.createSession({
47+
onPermissionRequest: approveAll,
4548
hooks: {
4649
onUserPromptSubmitted: async (input, invocation) => {
4750
userPromptInputs.push(input);
@@ -66,6 +69,7 @@ describe("Extended session hooks", async () => {
6669
const sessionEndInputs: SessionEndHookInput[] = [];
6770

6871
const session = await client.createSession({
72+
onPermissionRequest: approveAll,
6973
hooks: {
7074
onSessionEnd: async (input, invocation) => {
7175
sessionEndInputs.push(input);
@@ -90,6 +94,7 @@ describe("Extended session hooks", async () => {
9094
const errorInputs: ErrorOccurredHookInput[] = [];
9195

9296
const session = await client.createSession({
97+
onPermissionRequest: approveAll,
9398
hooks: {
9499
onErrorOccurred: async (input, invocation) => {
95100
errorInputs.push(input);

nodejs/test/e2e/multi_turn.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import { writeFile } from "fs/promises";
66
import { join } from "path";
77
import { describe, expect, it } from "vitest";
8+
import { approveAll } from "../../src/index.js";
89
import { createSdkTestContext } from "./harness/sdkTestContext";
910

1011
describe("Multi-turn Tool Usage", async () => {
@@ -13,7 +14,7 @@ describe("Multi-turn Tool Usage", async () => {
1314
it("should use tool results from previous turns", async () => {
1415
// Write a file, then ask the model to read it and reason about its content
1516
await writeFile(join(workDir, "secret.txt"), "The magic number is 42.");
16-
const session = await client.createSession();
17+
const session = await client.createSession({ onPermissionRequest: approveAll });
1718

1819
const msg1 = await session.sendAndWait({
1920
prompt: "Read the file 'secret.txt' and tell me what the magic number is.",
@@ -28,7 +29,7 @@ describe("Multi-turn Tool Usage", async () => {
2829
});
2930

3031
it("should handle file creation then reading across turns", async () => {
31-
const session = await client.createSession();
32+
const session = await client.createSession({ onPermissionRequest: approveAll });
3233

3334
// First turn: create a file
3435
await session.sendAndWait({

nodejs/test/e2e/session_config.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { describe, expect, it } from "vitest";
22
import { writeFile, mkdir } from "fs/promises";
33
import { join } from "path";
4+
import { approveAll } from "../../src/index.js";
45
import { createSdkTestContext } from "./harness/sdkTestContext.js";
56

67
describe("Session Configuration", async () => {
@@ -12,6 +13,7 @@ describe("Session Configuration", async () => {
1213
await writeFile(join(subDir, "marker.txt"), "I am in the subdirectory");
1314

1415
const session = await client.createSession({
16+
onPermissionRequest: approveAll,
1517
workingDirectory: subDir,
1618
});
1719

@@ -25,6 +27,7 @@ describe("Session Configuration", async () => {
2527

2628
it("should create session with custom provider config", async () => {
2729
const session = await client.createSession({
30+
onPermissionRequest: approveAll,
2831
provider: {
2932
baseUrl: "https://api.example.com/v1",
3033
apiKey: "test-key",
@@ -43,7 +46,7 @@ describe("Session Configuration", async () => {
4346
it("should accept message attachments", async () => {
4447
await writeFile(join(workDir, "attached.txt"), "This file is attached");
4548

46-
const session = await client.createSession();
49+
const session = await client.createSession({ onPermissionRequest: approveAll });
4750

4851
await session.send({
4952
prompt: "Summarize the attached file",

nodejs/test/e2e/session_lifecycle.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
*--------------------------------------------------------------------------------------------*/
44

55
import { describe, expect, it } from "vitest";
6-
import { SessionEvent } from "../../src/index.js";
6+
import { SessionEvent, approveAll } from "../../src/index.js";
77
import { createSdkTestContext } from "./harness/sdkTestContext";
88

99
describe("Session Lifecycle", async () => {
1010
const { copilotClient: client } = await createSdkTestContext();
1111

1212
it("should list created sessions after sending a message", async () => {
13-
const session1 = await client.createSession();
14-
const session2 = await client.createSession();
13+
const session1 = await client.createSession({ onPermissionRequest: approveAll });
14+
const session2 = await client.createSession({ onPermissionRequest: approveAll });
1515

1616
// Sessions must have activity to be persisted to disk
1717
await session1.sendAndWait({ prompt: "Say hello" });
@@ -31,7 +31,7 @@ describe("Session Lifecycle", async () => {
3131
});
3232

3333
it("should delete session permanently", async () => {
34-
const session = await client.createSession();
34+
const session = await client.createSession({ onPermissionRequest: approveAll });
3535
const sessionId = session.sessionId;
3636

3737
// Send a message so the session is persisted
@@ -53,7 +53,7 @@ describe("Session Lifecycle", async () => {
5353
});
5454

5555
it("should return events via getMessages after conversation", async () => {
56-
const session = await client.createSession();
56+
const session = await client.createSession({ onPermissionRequest: approveAll });
5757

5858
await session.sendAndWait({
5959
prompt: "What is 2+2? Reply with just the number.",
@@ -72,8 +72,8 @@ describe("Session Lifecycle", async () => {
7272
});
7373

7474
it("should support multiple concurrent sessions", async () => {
75-
const session1 = await client.createSession();
76-
const session2 = await client.createSession();
75+
const session1 = await client.createSession({ onPermissionRequest: approveAll });
76+
const session2 = await client.createSession({ onPermissionRequest: approveAll });
7777

7878
// Send to both sessions
7979
const [msg1, msg2] = await Promise.all([

nodejs/test/e2e/streaming_fidelity.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,14 @@
33
*--------------------------------------------------------------------------------------------*/
44

55
import { describe, expect, it } from "vitest";
6-
import { SessionEvent } from "../../src/index.js";
6+
import { SessionEvent, approveAll } from "../../src/index.js";
77
import { createSdkTestContext } from "./harness/sdkTestContext";
88

99
describe("Streaming Fidelity", async () => {
1010
const { copilotClient: client } = await createSdkTestContext();
1111

1212
it("should produce delta events when streaming is enabled", async () => {
13-
const session = await client.createSession({ streaming: true });
13+
const session = await client.createSession({ onPermissionRequest: approveAll, streaming: true });
1414
const events: SessionEvent[] = [];
1515
session.on((event) => {
1616
events.push(event);
@@ -44,7 +44,7 @@ describe("Streaming Fidelity", async () => {
4444
});
4545

4646
it("should not produce deltas when streaming is disabled", async () => {
47-
const session = await client.createSession({ streaming: false });
47+
const session = await client.createSession({ onPermissionRequest: approveAll, streaming: false });
4848
const events: SessionEvent[] = [];
4949
session.on((event) => {
5050
events.push(event);

0 commit comments

Comments
 (0)