1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
import { ChildProcess, spawn } from "child_process";
import * as fs from "fs";
import { EOL } from "os";
import * as path from "path";
import { PassThrough, Readable } from "stream";
import { run } from "../../webdriver-tap-runner/lib";
import * as _debug from "debug";
const debug = _debug("signalr-functional-tests:run");
process.on("unhandledRejection", (reason) => {
console.error(`Unhandled promise rejection: ${reason}`);
process.exit(1);
});
// Don't let us hang the build. If this process takes more than 10 minutes, we're outta here
setTimeout(() => {
console.error("Bail out! Tests took more than 10 minutes to run. Aborting.");
process.exit(1);
}, 1000 * 60 * 10);
function waitForMatch(command: string, process: ChildProcess, regex: RegExp): Promise<RegExpMatchArray> {
return new Promise<RegExpMatchArray>((resolve, reject) => {
const commandDebug = _debug(`signalr-functional-tests:${command}`);
try {
let lastLine = "";
async function onData(this: Readable, chunk: string | Buffer): Promise<void> {
try {
chunk = chunk.toString();
// Process lines
let lineEnd = chunk.indexOf(EOL);
while (lineEnd >= 0) {
const chunkLine = lastLine + chunk.substring(0, lineEnd);
lastLine = "";
chunk = chunk.substring(lineEnd + EOL.length);
const results = regex.exec(chunkLine);
commandDebug(chunkLine);
if (results && results.length > 0) {
resolve(results);
return;
}
lineEnd = chunk.indexOf(EOL);
}
lastLine = chunk.toString();
} catch (e) {
this.removeAllListeners("data");
reject(e);
}
}
process.on("close", async (code, signal) => {
console.log(`${command} process exited with code: ${code}`);
global.process.exit(1);
});
process.stdout.on("data", onData.bind(process.stdout));
process.stderr.on("data", (chunk) => {
onData.bind(process.stderr)(chunk);
console.error(`${command} | ${chunk.toString()}`);
});
} catch (e) {
reject(e);
}
});
}
let configuration = "Debug";
let chromePath: string;
let spec: string;
for (let i = 2; i < process.argv.length; i += 1) {
switch (process.argv[i]) {
case "--configuration":
i += 1;
configuration = process.argv[i];
break;
case "-v":
case "--verbose":
_debug.enable("signalr-functional-tests:*");
break;
case "--chrome":
i += 1;
chromePath = process.argv[i];
break;
case "--spec":
i += 1;
spec = process.argv[i];
break;
}
}
if (chromePath) {
debug(`Using Google Chrome at: '${chromePath}'`);
}
(async () => {
try {
const serverPath = path.resolve(__dirname, "..", "bin", configuration, "netcoreapp2.1", "FunctionalTests.dll");
debug(`Launching Functional Test Server: ${serverPath}`);
const dotnet = spawn("dotnet", [serverPath], {
env: {
...process.env,
["ASPNETCORE_URLS"]: "http://127.0.0.1:0"
},
});
function cleanup() {
if (dotnet && !dotnet.killed) {
console.log("Terminating dotnet process");
dotnet.kill();
}
}
process.on("SIGINT", cleanup);
process.on("exit", cleanup);
debug("Waiting for Functional Test Server to start");
const results = await waitForMatch("dotnet", dotnet, /Now listening on: (http:\/\/[^\/]+:[\d]+)/);
debug(`Functional Test Server has started at ${results[1]}`);
let url = results[1] + "?cacheBust=true";
if (spec) {
url += `&spec=${encodeURI(spec)}`;
}
debug(`Using server url: ${url}`);
const failureCount = await run("SignalR Browser Functional Tests", {
browser: "chrome",
chromeBinaryPath: chromePath,
output: process.stdout,
url,
webdriverPort: 9515,
});
process.exit(failureCount);
} catch (e) {
console.error("Error: " + e.toString());
process.exit(1);
}
})();
|