Skip to content

Commit bd914d9

Browse files
committed
fixed the case when the client is disconnected while tests were running
1 parent 7ae541e commit bd914d9

File tree

4 files changed

+111
-1
lines changed

4 files changed

+111
-1
lines changed

packages/server/fixtures/client.js.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const { Client } = require("mocha-remote-client");
2+
3+
const client = new Client({
4+
autoConnect: true,
5+
tests: () => {
6+
it("should reject", (done) => {
7+
done(new Error("This should not happen"));
8+
});
9+
}
10+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const { Client } = require("mocha-remote-client");
2+
3+
const client = new Client({
4+
autoConnect: true,
5+
timeout: 1000000,
6+
tests: () => {
7+
it("endless", (done) => {
8+
setTimeout(() => {
9+
done();
10+
}, 1000000);
11+
});
12+
}
13+
});

packages/server/src/Server.test.ts

+83
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { expect } from "chai";
22
import { WebSocket } from "ws";
33
import flatted from "flatted";
4+
import { ChildProcess, fork } from "child_process";
5+
import { resolve } from "path";
46

57
import { Server } from "./Server";
68

@@ -91,4 +93,85 @@ describe("Mocha Remote Server", () => {
9193
}
9294
}
9395
});
96+
97+
const startRemoteClient = (script: string, server: Server) => {
98+
return new Promise<ChildProcess>((resolve) => {
99+
const clientProcess = fork(script, { stdio: "inherit" });
100+
const onConnection = () => {
101+
cleanup();
102+
resolve(clientProcess);
103+
};
104+
const cleanup = () => {
105+
server.off("connection", onConnection);
106+
}
107+
server.on("connection", onConnection);
108+
});
109+
};
110+
111+
const stopRemoteClient = (childClientProcess: ChildProcess) => {
112+
return new Promise<void>((resolve, reject) => {
113+
childClientProcess.once("exit", () => {
114+
resolve();
115+
});
116+
childClientProcess.kill();
117+
});
118+
};
119+
120+
const runTests = (server: Server) => {
121+
return new Promise<number>((resolve, reject) => {
122+
server.run((failures) => {
123+
resolve(failures);
124+
});
125+
});
126+
};
127+
128+
it("should be able to start again, when the server is stopped during a run", async () => {
129+
// Create and start the server
130+
const server = new Server({
131+
port: 8090,
132+
reporter: "base",
133+
autoRun: false,
134+
});
135+
136+
await server.start();
137+
138+
const clientThatHangsScriptPath = resolve(__dirname, "../fixtures/clientVeryLongRun.js");
139+
const childClientProcess = await startRemoteClient(clientThatHangsScriptPath, server);
140+
141+
server.run(() => {
142+
//
143+
});
144+
145+
await server.stop();
146+
await server.start();
147+
148+
await server.stop();
149+
await stopRemoteClient(childClientProcess);
150+
});
151+
152+
it("should be able to start again, on client disconnection while running", async () => {
153+
// Create and start the server
154+
const server = new Server({
155+
port: 8090,
156+
reporter: "base",
157+
autoRun: false,
158+
});
159+
160+
await server.start();
161+
162+
const clientThatHangsScriptPath = resolve(__dirname, "../fixtures/clientVeryLongRun.js");
163+
const childClientProcess = await startRemoteClient(clientThatHangsScriptPath, server);
164+
165+
const results = await Promise.all([runTests(server), stopRemoteClient(childClientProcess)]);
166+
const failures = results[0];
167+
expect(failures).to.equal(0);
168+
169+
const clientScriptPath = resolve(__dirname, "../fixtures/client.js");
170+
const remoteClientProcess = await startRemoteClient(clientScriptPath, server);
171+
172+
const result = await runTests(server);
173+
expect(result).to.equal(1);
174+
await server.stop();
175+
await stopRemoteClient(remoteClientProcess);
176+
});
94177
});

packages/server/src/Server.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,6 @@ export class Server extends ServerEventEmitter {
151151
this.wss.close(err => {
152152
// Delete the runner to allow another run
153153
delete this.runner;
154-
155154
// Forget about the server
156155
delete this.wss;
157156
// Reject or resolve the promise
@@ -324,6 +323,11 @@ export class Server extends ServerEventEmitter {
324323
// Check that the protocol matches
325324
const expectedProtocol = `mocha-remote-${this.config.id}`;
326325
ws.on("close", (code, reason) => {
326+
if(this.runner) {
327+
this.debug("Client disconnected while tests were running");
328+
this.runner.emit("end");
329+
delete this.runner;
330+
}
327331
this.emit("disconnection", ws, code, reason.toString());
328332
});
329333
// Signal that a client has connected

0 commit comments

Comments
 (0)