-
Notifications
You must be signed in to change notification settings - Fork 76
/
Copy pathTestAutomation.ts
108 lines (99 loc) · 3.6 KB
/
TestAutomation.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
import { DynamicExecutor } from "@nestia/e2e";
import chalk from "chalk";
import { MyConfiguration } from "../src/MyConfiguration";
import api from "../src/api";
import { MySetupWizard } from "../src/setup/MySetupWizard";
import { ArgumentParser } from "./internal/ArgumentParser";
import { StopWatch } from "./internal/StopWatch";
export namespace TestAutomation {
export interface IProps<T> {
open(options: IOptions): Promise<T>;
close(backend: T): Promise<void>;
}
export interface IOptions {
reset: boolean;
simultaneous: number;
include?: string[];
exclude?: string[];
trace: boolean;
}
export const execute = async <T>(props: IProps<T>): Promise<void> => {
// CONFIGURE
const options: IOptions = await getOptions();
if (options.reset) {
await StopWatch.trace("Reset DB")(MySetupWizard.schema);
await StopWatch.trace("Seed Data")(MySetupWizard.seed);
}
// DO TEST
const backend: T = await props.open(options);
const connection: api.IConnection = {
host: `http://127.0.0.1:${MyConfiguration.API_PORT()}`,
};
const report: DynamicExecutor.IReport = await DynamicExecutor.validate({
prefix: "test",
location: __dirname + "/features",
parameters: () => [
{
host: connection.host,
encryption: connection.encryption,
},
],
filter: (func) =>
(!options.include?.length ||
(options.include ?? []).some((str) => func.includes(str))) &&
(!options.exclude?.length ||
(options.exclude ?? []).every((str) => !func.includes(str))),
onComplete: (exec) => {
const trace = (str: string) =>
console.log(` - ${chalk.green(exec.name)}: ${str}`);
if (exec.error === null) {
const elapsed: number =
new Date(exec.completed_at).getTime() -
new Date(exec.started_at).getTime();
trace(`${chalk.yellow(elapsed.toLocaleString())} ms`);
} else trace(chalk.red(exec.error.name));
},
});
// TERMINATE
await props.close(backend);
const exceptions: Error[] = report.executions
.filter((exec) => exec.error !== null)
.map((exec) => exec.error!);
if (exceptions.length === 0) {
console.log("Success");
console.log("Elapsed time", report.time.toLocaleString(), `ms`);
} else {
if (options.trace !== false)
for (const exp of exceptions) console.log(exp);
console.log("Failed");
console.log("Elapsed time", report.time.toLocaleString(), `ms`);
process.exit(-1);
}
};
}
const getOptions = () =>
ArgumentParser.parse<TestAutomation.IOptions>(
async (command, prompt, action) => {
command.option("--reset <true|false>", "reset local DB or not");
command.option(
"--simultaneous <number>",
"number of simultaneous requests to make",
);
command.option("--include <string...>", "include feature files");
command.option("--exclude <string...>", "exclude feature files");
command.option("--trace <boolean>", "trace detailed errors");
return action(async (options) => {
if (typeof options.reset === "string")
options.reset = options.reset === "true";
options.reset ??= await prompt.boolean("reset")("Reset local DB");
options.simultaneous = Number(
options.simultaneous ??
(await prompt.number("simultaneous")(
"Number of simultaneous requests to make",
)),
);
options.trace = options.trace !== ("false" as any);
return options as TestAutomation.IOptions;
});
},
);