Skip to content

Commit 3c96ae9

Browse files
Simplify GUI test script
1 parent 3ce056f commit 3c96ae9

File tree

3 files changed

+28
-238
lines changed

3 files changed

+28
-238
lines changed

dockerfiles/Dockerfile-gui-tests

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,7 @@ COPY ../package.json /build/package.json
7474
# We also specify the version in case we need to update it to go around cache limitations.
7575
RUN npm install --unsafe-perm=true --loglevel verbose --force
7676

77+
# Used in gui-tests/tester.js
78+
ENV NODE_MODULE_PATH="/build/node_modules"
79+
7780
CMD ["node", "/build/out/gui-tests/tester.js"]

dockerfiles/run-gui-tests.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ cargo run -- start-web-server &
3737
SERVER_PID=$!
3838

3939
# status="docker run . -v `pwd`:/build/out:ro gui_tests"
40-
docker compose run --rm gui_tests
40+
docker compose build gui_tests
41+
docker compose run --rm --remove-orphans gui_tests
4142
status=$?
4243
kill $SERVER_PID
4344
exit $status

gui-tests/tester.js

Lines changed: 23 additions & 237 deletions
Original file line numberDiff line numberDiff line change
@@ -4,247 +4,33 @@
44
// npm install browser-ui-test
55
// ```
66

7-
const fs = require("fs");
87
const path = require("path");
9-
const os = require("os");
10-
const {Options, runTest} = require("browser-ui-test");
11-
12-
function showHelp() {
13-
console.log("docs-rs-gui-js options:");
14-
console.log(" --file [PATH] : file to run (can be repeated)");
15-
console.log(" --debug : show extra information about script run");
16-
console.log(" --show-text : render font in pages");
17-
console.log(" --no-headless : disable headless mode");
18-
console.log(" --help : show this message then quit");
19-
console.log(" --jobs [NUMBER] : number of threads to run tests on");
20-
}
21-
22-
function isNumeric(s) {
23-
return /^\d+$/.test(s);
24-
}
25-
26-
function parseOptions(args) {
27-
const opts = {
28-
"files": [],
29-
"debug": false,
30-
"show_text": false,
31-
"no_headless": false,
32-
"jobs": -1,
33-
};
34-
const correspondences = {
35-
"--debug": "debug",
36-
"--show-text": "show_text",
37-
"--no-headless": "no_headless",
38-
};
39-
40-
for (let i = 0; i < args.length; ++i) {
41-
if (args[i] === "--file"
42-
|| args[i] === "--jobs") {
43-
i += 1;
44-
if (i >= args.length) {
45-
console.log("Missing argument after `" + args[i - 1] + "` option.");
46-
return null;
47-
}
48-
if (args[i - 1] === "--jobs") {
49-
if (!isNumeric(args[i])) {
50-
console.log(
51-
"`--jobs` option expects a positive number, found `" + args[i] + "`");
52-
return null;
53-
}
54-
opts["jobs"] = parseInt(args[i]);
55-
} else if (args[i - 1] !== "--file") {
56-
opts[correspondences[args[i - 1]]] = args[i];
57-
} else {
58-
opts["files"].push(args[i]);
59-
}
60-
} else if (args[i] === "--help") {
61-
showHelp();
62-
process.exit(0);
63-
} else if (correspondences[args[i]]) {
64-
opts[correspondences[args[i]]] = true;
65-
} else {
66-
console.log("Unknown option `" + args[i] + "`.");
67-
console.log("Use `--help` to see the list of options");
68-
return null;
69-
}
70-
}
71-
return opts;
72-
}
73-
74-
/// Print single char status information without \n
75-
function char_printer(n_tests) {
76-
const max_per_line = 10;
77-
let current = 0;
78-
return {
79-
successful: function() {
80-
current += 1;
81-
if (current % max_per_line === 0) {
82-
process.stdout.write(`. (${current}/${n_tests})${os.EOL}`);
83-
} else {
84-
process.stdout.write(".");
85-
}
86-
},
87-
erroneous: function() {
88-
current += 1;
89-
if (current % max_per_line === 0) {
90-
process.stderr.write(`F (${current}/${n_tests})${os.EOL}`);
91-
} else {
92-
process.stderr.write("F");
93-
}
94-
},
95-
finish: function() {
96-
if (current % max_per_line === 0) {
97-
// Don't output if we are already at a matching line end
98-
console.log("");
99-
} else {
100-
const spaces = " ".repeat(max_per_line - (current % max_per_line));
101-
process.stdout.write(`${spaces} (${current}/${n_tests})${os.EOL}${os.EOL}`);
102-
}
103-
},
104-
};
105-
}
106-
107-
/// Sort array by .file_name property
108-
function by_filename(a, b) {
109-
return a.file_name - b.file_name;
110-
}
8+
const spawn = require("child_process").spawn;
1119

11210
async function main(argv) {
113-
const opts = parseOptions(argv.slice(2));
114-
if (opts === null) {
115-
process.exit(1);
116-
}
117-
118-
// Print successful tests too
119-
let debug = false;
120-
// Run tests in sequentially
121-
let headless = true;
122-
const options = new Options();
123-
try {
124-
// This is more convenient that setting fields one by one.
125-
const args = [];
126-
if (typeof process.env.SERVER_URL !== "undefined") {
127-
args.push("--variable", "DOC_PATH", process.env.SERVER_URL);
128-
} else {
129-
args.push("--variable", "DOC_PATH", "http://127.0.0.1:3000");
11+
let server = "http://127.0.0.1:3000";
12+
if (typeof process.env.SERVER_URL !== "undefined") {
13+
server = process.env.SERVER_URL;
14+
}
15+
let nodeModulePath = "./node_modules";
16+
if (typeof process.env.NODE_MODULE_PATH !== "undefined") {
17+
nodeModulePath = process.env.NODE_MODULE_PATH;
18+
}
19+
await spawn("node", [
20+
path.join(nodeModulePath, "browser-ui-test/src/index.js"),
21+
"--display-format",
22+
"compact",
23+
"--variable",
24+
"DOC_PATH",
25+
server,
26+
"--test-folder",
27+
__dirname,
28+
...argv.slice(2),
29+
], {stdio: "inherit", stderr: "inherit"}).on("exit", code => {
30+
if (code !== 0) {
31+
process.exit(1);
13032
}
131-
if (opts["debug"]) {
132-
debug = true;
133-
args.push("--debug");
134-
}
135-
if (opts["show_text"]) {
136-
args.push("--show-text");
137-
}
138-
if (opts["no_headless"]) {
139-
args.push("--no-headless");
140-
headless = false;
141-
}
142-
options.parseArguments(args);
143-
} catch (error) {
144-
console.error(`invalid argument: ${error}`);
145-
process.exit(1);
146-
}
147-
148-
let failed = false;
149-
let files;
150-
if (opts["files"].length === 0) {
151-
files = fs.readdirSync(__dirname);
152-
} else {
153-
files = opts["files"];
154-
}
155-
files = files.filter(file => path.extname(file) === ".goml");
156-
if (files.length === 0) {
157-
console.error("No test selected");
158-
process.exit(2);
159-
}
160-
files.sort();
161-
162-
if (!headless) {
163-
opts["jobs"] = 1;
164-
console.log("`--no-headless` option is active, disabling concurrency for running tests.");
165-
}
166-
let jobs = opts["jobs"];
167-
168-
if (opts["jobs"] < 1) {
169-
jobs = files.length;
170-
process.setMaxListeners(files.length + 1);
171-
} else if (headless) {
172-
process.setMaxListeners(opts["jobs"] + 1);
173-
}
174-
console.log(`Running ${files.length} docs.rs GUI (${jobs} concurrently) ...`);
175-
176-
const tests_queue = [];
177-
const results = {
178-
successful: [],
179-
failed: [],
180-
errored: [],
181-
};
182-
const status_bar = char_printer(files.length);
183-
for (let i = 0; i < files.length; ++i) {
184-
const file_name = files[i];
185-
const testPath = path.join(__dirname, file_name);
186-
const callback = runTest(testPath, {"options": options})
187-
.then(out => {
188-
const [output, nb_failures] = out;
189-
results[nb_failures === 0 ? "successful" : "failed"].push({
190-
file_name: testPath,
191-
output: output,
192-
});
193-
if (nb_failures > 0) {
194-
status_bar.erroneous();
195-
failed = true;
196-
} else {
197-
status_bar.successful();
198-
}
199-
})
200-
.catch(err => {
201-
results.errored.push({
202-
file_name: testPath + file_name,
203-
output: err,
204-
});
205-
status_bar.erroneous();
206-
failed = true;
207-
})
208-
.finally(() => {
209-
// We now remove the promise from the tests_queue.
210-
tests_queue.splice(tests_queue.indexOf(callback), 1);
211-
});
212-
tests_queue.push(callback);
213-
if (opts["jobs"] > 0 && tests_queue.length >= opts["jobs"]) {
214-
await Promise.race(tests_queue);
215-
}
216-
}
217-
if (tests_queue.length > 0) {
218-
await Promise.all(tests_queue);
219-
}
220-
status_bar.finish();
221-
222-
if (debug) {
223-
results.successful.sort(by_filename);
224-
results.successful.forEach(r => {
225-
console.log(r.output);
226-
});
227-
}
228-
229-
if (results.failed.length > 0) {
230-
console.log("");
231-
results.failed.sort(by_filename);
232-
results.failed.forEach(r => {
233-
console.log(r.file_name, r.output);
234-
});
235-
}
236-
if (results.errored.length > 0) {
237-
console.log(os.EOL);
238-
// print run errors on the bottom so developers see them better
239-
results.errored.sort(by_filename);
240-
results.errored.forEach(r => {
241-
console.error(r.file_name, r.output);
242-
});
243-
}
244-
245-
if (failed) {
246-
process.exit(1);
247-
}
33+
});
24834
}
24935

25036
main(process.argv);

0 commit comments

Comments
 (0)