forked from dfinity/internet-identity
-
Notifications
You must be signed in to change notification settings - Fork 0
/
test.ts
executable file
·166 lines (138 loc) · 4.83 KB
/
test.ts
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#!/usr/bin/env ts-node
/* This starts the proxy and the test suite. The proxy configuration is read
* from dfx.json and canister_ids.json. The proxy is shutdown after the tests
* are run.
* This expects the replica to be running, and expects the II canister to have
* been deployed.
*/
import { ChildProcess, execSync, spawn } from "child_process";
import * as fs from "fs";
import { dirname } from "path";
import { fileURLToPath } from "url";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
// In order to proxy the calls Node v18 requires 127.0.0.1 instead of localhost as string for the proxy
const LOCALHOST = "127.0.0.1";
// Port and URL for II and the sign in app, then exported to the tests. Here we need localhost as string because it is used by wdio in the headless browser.
const II_DAPP_PORT = 8086;
const II_DAPP_URL = `http://localhost:${II_DAPP_PORT}`;
const WEBAPP_PORT = 8087;
type Arguments = { noRun: boolean };
/** Parse CLI arguments
*/
function parseArguments(): Arguments {
if (![2, 3].includes(process.argv.length)) {
throw new Error("Usage: test.ts [--no-run]");
}
if (process.argv.length === 3) {
if (process.argv[2] !== "--no-run") {
throw new Error("Usage: test.ts [--no-run]");
}
return { noRun: true };
} else {
return { noRun: false };
}
}
type CanisterIDs = { webapp: string; internetIdentity: string };
/*
* Read the values from dfx.json and canister_ids.json
*/
function parseCanisterIDs(): CanisterIDs {
const CANISTER_IDS_PATH = `${__dirname}/.dfx/local/canister_ids.json`;
try {
const canister_ids = JSON.parse(fs.readFileSync(CANISTER_IDS_PATH, "utf8"));
return {
internetIdentity: canister_ids["internet_identity"].local,
webapp: canister_ids["webapp"].local,
};
} catch (e) {
console.log(
`Could not read 'internet_identity' and 'webapp' local canister IDs from ${CANISTER_IDS_PATH}`
);
throw e;
}
}
function getReplicaHost(): string {
let port = execSync("dfx info webserver-port");
return `http://${LOCALHOST}:${port}`;
}
/*
* Start the proxy
*
* Any port would do here, it just needs to be the same the test runner uses,
* hence we set it as the `II_DAPP_URL` environment variable which is read by
* wdio.conf.js..
*/
function spawnProxy(
canisterIds: CanisterIDs,
replicaHost: string
): ChildProcess {
return spawn("proxy", [
"--replica-host",
replicaHost,
`${canisterIds.internetIdentity}:${II_DAPP_PORT}`,
`${canisterIds.webapp}:${WEBAPP_PORT}`,
]);
}
function main() {
// Read values and spawn proxy
const canisterIds = parseCanisterIDs();
console.log(
`Using canister IDs: internet_identity: ${canisterIds.internetIdentity}, webapp: ${canisterIds.webapp}`
);
const replicaHost = getReplicaHost();
console.log(`Using replica host: ${replicaHost}`);
const proxy = spawnProxy(canisterIds, replicaHost);
const runTests = !parseArguments().noRun;
let testsStarted = false;
let proxyOutput = "";
proxy.stdout!.on("data", (data) => {
console.log(`proxy: ${data}`);
if (!testsStarted) {
// Wait for proxy to output "Proxy created" before we start the tests, otherwise the
// tests may start before the proxy is running.
proxyOutput = `${proxyOutput}${data}`;
if (proxyOutput.includes("Proxy created")) {
console.log("Proxy is up and running");
testsStarted = true;
// if runTests is true, then the tests are run, and then we return.
// Otherwise, we simply leave the proxy running and wait to be killed by the user.
if (runTests) {
/*
* Start the tests
*/
console.log("Starting tests");
const wdio = spawn("npm", ["run", "wdio"], {
env: { ...process.env, II_DAPP_URL: II_DAPP_URL },
});
wdio.stdout.on("data", (data) => {
console.log(`wdio: ${data}`);
});
wdio.stderr.on("data", (data) => {
console.log(`wdio: ${data}`);
});
wdio.on("exit", (code, signal) => {
console.log("Killing proxy");
proxy.kill();
if (code !== null && code > 0) {
// if code is set and non-zero, bubble up error from wdio tests
throw new Error(`End-to-end tests returned with ${code}`);
} else if (signal) {
// otherwise, if the child was killed externally
throw new Error(`End-to-end tests killed with signal ${signal}`);
} else {
console.log("End-to-end tests finished successfully");
}
});
}
}
}
});
proxy.stderr!.on("data", (data) => {
console.log(`proxy: ${data}`);
});
proxy.on("exit", (code, signal) => {
console.log(`proxy returned (return code: ${code}, signal: ${signal})`);
});
}
main();