@w-lfpup/jackrabbit 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/browsers.json +55 -0
- package/.github/workflows/browsers.macos.json +51 -0
- package/.github/workflows/browsers.windows.json +19 -0
- package/.github/workflows/tests.yml +13 -0
- package/README.md +41 -1
- package/browser/dist/logger.js +43 -0
- package/browser/dist/mod.js +25 -0
- package/browser/dist/queue.js +27 -0
- package/browser/dist/runner.js +20 -0
- package/{cli → browser}/package.json +1 -1
- package/browser/src/logger.ts +57 -0
- package/browser/src/mod.ts +30 -0
- package/browser/src/runner.ts +22 -0
- package/browser/tsconfig.json +11 -0
- package/browser/tsconfig.tsbuildinfo +1 -0
- package/browsers.json +38 -0
- package/core/dist/jackrabbit_types.d.ts +61 -27
- package/core/dist/mod.d.ts +2 -2
- package/core/dist/mod.js +1 -1
- package/core/dist/run_steps.d.ts +2 -2
- package/core/dist/run_steps.js +83 -67
- package/core/src/jackrabbit_types.ts +72 -28
- package/core/src/mod.ts +2 -8
- package/core/src/run_steps.ts +111 -80
- package/examples/hello_world/goodbye_world.ts +1 -1
- package/examples/hello_world/hello_world.ts +1 -1
- package/nodejs/dist/logger.js +164 -0
- package/nodejs/dist/mod.js +33 -0
- package/nodejs/dist/results.js +145 -0
- package/nodejs/dist/results_str.js +147 -0
- package/nodejs/dist/runner.js +17 -0
- package/nodejs/src/logger.ts +200 -0
- package/nodejs/src/mod.ts +39 -0
- package/nodejs/src/results.ts +239 -0
- package/{nodejs_cli → nodejs}/tsconfig.json +2 -1
- package/nodejs/tsconfig.tsbuildinfo +1 -0
- package/package.json +6 -4
- package/tests/dist/mod.d.ts +14 -3
- package/tests/dist/mod.js +33 -15
- package/tests/dist/test_error.test.d.ts +9 -0
- package/tests/dist/test_error.test.js +25 -0
- package/tests/dist/test_errors.test.d.ts +9 -0
- package/tests/dist/test_errors.test.js +27 -0
- package/tests/dist/test_fail.test.js +0 -2
- package/tests/dist/test_logger.d.ts +3 -2
- package/tests/dist/test_logger.js +5 -1
- package/tests/dist/test_pass.test.js +0 -2
- package/tests/src/mod.ts +31 -15
- package/tests/src/test_error.test.ts +32 -0
- package/tests/src/test_logger.ts +6 -1
- package/tests/tsconfig.tsbuildinfo +1 -1
- package/tsconfig.json +3 -2
- package/webdriver/dist/config.js +56 -0
- package/webdriver/dist/eventbus.js +18 -0
- package/webdriver/dist/listeners.js +21 -0
- package/webdriver/dist/logger.js +200 -0
- package/webdriver/dist/mod.js +35 -0
- package/webdriver/dist/results.js +190 -0
- package/webdriver/dist/results_str.js +167 -0
- package/webdriver/dist/routes.js +162 -0
- package/webdriver/dist/routes2.js +163 -0
- package/webdriver/dist/test_hangar.js +20 -0
- package/webdriver/dist/webdriver.js +272 -0
- package/webdriver/package.json +8 -0
- package/webdriver/src/config.ts +89 -0
- package/webdriver/src/eventbus.ts +104 -0
- package/webdriver/src/logger.ts +247 -0
- package/webdriver/src/mod.ts +45 -0
- package/webdriver/src/results.ts +311 -0
- package/webdriver/src/routes.ts +198 -0
- package/webdriver/src/test_hangar.ts +25 -0
- package/webdriver/src/webdriver.ts +373 -0
- package/{cli → webdriver}/tsconfig.json +1 -0
- package/webdriver/tsconfig.tsbuildinfo +1 -0
- package/cli/dist/cli.d.ts +0 -3
- package/cli/dist/cli.js +0 -8
- package/cli/dist/cli_types.d.ts +0 -7
- package/cli/dist/cli_types.js +0 -1
- package/cli/dist/config.d.ts +0 -5
- package/cli/dist/config.js +0 -6
- package/cli/dist/importer.d.ts +0 -7
- package/cli/dist/importer.js +0 -16
- package/cli/dist/logger.d.ts +0 -7
- package/cli/dist/logger.js +0 -88
- package/cli/dist/mod.d.ts +0 -6
- package/cli/dist/mod.js +0 -4
- package/cli/src/cli.ts +0 -17
- package/cli/src/cli_types.ts +0 -9
- package/cli/src/config.ts +0 -9
- package/cli/src/importer.ts +0 -25
- package/cli/src/logger.ts +0 -126
- package/cli/src/mod.ts +0 -7
- package/cli/tsconfig.tsbuildinfo +0 -1
- package/nodejs_cli/dist/mod.d.ts +0 -2
- package/nodejs_cli/dist/mod.js +0 -20
- package/nodejs_cli/src/mod.ts +0 -25
- package/nodejs_cli/tsconfig.tsbuildinfo +0 -1
- /package/{nodejs_cli → nodejs}/package.json +0 -0
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
import type { ChildProcess } from "child_process";
|
|
2
|
+
import type { ConfigInterface, WebdriverParams } from "./config.js";
|
|
3
|
+
import type { EventBus } from "./eventbus.js";
|
|
4
|
+
|
|
5
|
+
import { exec } from "child_process";
|
|
6
|
+
|
|
7
|
+
let headers = new Headers([["Content-Type", "application/json"]]);
|
|
8
|
+
|
|
9
|
+
export class WebDrivers {
|
|
10
|
+
#config: ConfigInterface;
|
|
11
|
+
#eventbus: EventBus;
|
|
12
|
+
#webdrivers: WebdriverSession[] = [];
|
|
13
|
+
#currentIndex = 0;
|
|
14
|
+
|
|
15
|
+
constructor(config: ConfigInterface, eventbus: EventBus) {
|
|
16
|
+
this.#eventbus = eventbus;
|
|
17
|
+
this.#config = config;
|
|
18
|
+
|
|
19
|
+
for (const params of config.webdrivers) {
|
|
20
|
+
this.#webdrivers.push(
|
|
21
|
+
new WebdriverSession(params, config.hostAndPort, eventbus),
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
run() {
|
|
27
|
+
this.#eventbus.addListener("session_closed", (action) => {
|
|
28
|
+
if (action.id !== this.#config.webdrivers[this.#currentIndex]?.jrId)
|
|
29
|
+
return;
|
|
30
|
+
|
|
31
|
+
this.#currentIndex += 1;
|
|
32
|
+
let webdriver = this.#webdrivers[this.#currentIndex];
|
|
33
|
+
webdriver
|
|
34
|
+
? webdriver.run()
|
|
35
|
+
: this.#eventbus.dispatchAction({
|
|
36
|
+
type: "end",
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
let webdriver = this.#webdrivers[this.#currentIndex];
|
|
41
|
+
webdriver
|
|
42
|
+
? webdriver.run()
|
|
43
|
+
: this.#eventbus.dispatchAction({
|
|
44
|
+
type: "end",
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
runAll() {
|
|
49
|
+
this.#eventbus.addListener("session_closed", (action) => {
|
|
50
|
+
let { id } = action;
|
|
51
|
+
let [indexStr] = id.split(":");
|
|
52
|
+
let index = parseInt(indexStr);
|
|
53
|
+
if (this.#webdrivers[index]) {
|
|
54
|
+
if (id === this.#config.webdrivers[index]?.jrId)
|
|
55
|
+
this.#currentIndex += 1;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (this.#currentIndex === this.#webdrivers.length) {
|
|
59
|
+
this.#eventbus.dispatchAction({
|
|
60
|
+
type: "end",
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
for (let webdriver of this.#webdrivers) {
|
|
66
|
+
webdriver.run();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
class WebdriverSession {
|
|
72
|
+
#params: WebdriverParams;
|
|
73
|
+
#hostAndPort: URL;
|
|
74
|
+
#eventbus: EventBus;
|
|
75
|
+
#process: ChildProcess | undefined;
|
|
76
|
+
#signal: AbortSignal | undefined;
|
|
77
|
+
#abortController: AbortController;
|
|
78
|
+
#sessionId: string | undefined;
|
|
79
|
+
|
|
80
|
+
constructor(params: WebdriverParams, hostAndPort: URL, eventbus: EventBus) {
|
|
81
|
+
this.#params = params;
|
|
82
|
+
this.#hostAndPort = hostAndPort;
|
|
83
|
+
this.#eventbus = eventbus;
|
|
84
|
+
this.#abortController = new AbortController();
|
|
85
|
+
|
|
86
|
+
this.#eventbus.addListener("run_complete", (action) => {
|
|
87
|
+
if (action.id === this.#params.jrId) this.#down();
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async run() {
|
|
92
|
+
if (this.#process) return;
|
|
93
|
+
|
|
94
|
+
let { jrId } = this.#params;
|
|
95
|
+
|
|
96
|
+
this.#eventbus.dispatchAction({
|
|
97
|
+
id: jrId,
|
|
98
|
+
type: "session_start",
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
this.#signal = setupSignal(
|
|
102
|
+
this.#params,
|
|
103
|
+
this.#eventbus,
|
|
104
|
+
this.#abortController.signal,
|
|
105
|
+
);
|
|
106
|
+
this.#process = setupProcess(
|
|
107
|
+
this.#params,
|
|
108
|
+
this.#eventbus,
|
|
109
|
+
this.#abortController.signal,
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
try {
|
|
113
|
+
await untilWebdriverReady(this.#params, this.#signal);
|
|
114
|
+
this.#sessionId = await getSession(this.#params, this.#signal);
|
|
115
|
+
await goToPing(
|
|
116
|
+
this.#params,
|
|
117
|
+
this.#signal,
|
|
118
|
+
this.#sessionId,
|
|
119
|
+
this.#hostAndPort,
|
|
120
|
+
);
|
|
121
|
+
await setCookie(this.#params, this.#signal, this.#sessionId);
|
|
122
|
+
await goToTestPage(
|
|
123
|
+
this.#params,
|
|
124
|
+
this.#signal,
|
|
125
|
+
this.#sessionId,
|
|
126
|
+
this.#hostAndPort,
|
|
127
|
+
);
|
|
128
|
+
} catch (e) {
|
|
129
|
+
let errOutput;
|
|
130
|
+
if (e instanceof Error) {
|
|
131
|
+
errOutput = e.name + "\n" + e.message + (e.cause ? "\n" + e.cause : "");
|
|
132
|
+
}
|
|
133
|
+
if (!errOutput) errOutput = e?.toString();
|
|
134
|
+
|
|
135
|
+
this.#eventbus.dispatchAction({
|
|
136
|
+
type: "session_error",
|
|
137
|
+
id: this.#params.jrId,
|
|
138
|
+
error: errOutput ?? "Unknown error creating browser session",
|
|
139
|
+
});
|
|
140
|
+
this.#abortController.abort();
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
async #down() {
|
|
145
|
+
if (!this.#process) return;
|
|
146
|
+
await deleteSession(
|
|
147
|
+
this.#params,
|
|
148
|
+
this.#signal,
|
|
149
|
+
this.#eventbus,
|
|
150
|
+
this.#sessionId,
|
|
151
|
+
);
|
|
152
|
+
|
|
153
|
+
this.#process.kill();
|
|
154
|
+
this.#process = undefined;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function setupSignal(
|
|
159
|
+
params: WebdriverParams,
|
|
160
|
+
eventbus: EventBus,
|
|
161
|
+
externalSignal: AbortSignal,
|
|
162
|
+
): AbortSignal {
|
|
163
|
+
let { jrId, timeoutMs } = params;
|
|
164
|
+
|
|
165
|
+
let signal = AbortSignal.any([
|
|
166
|
+
externalSignal,
|
|
167
|
+
AbortSignal.timeout(timeoutMs),
|
|
168
|
+
]);
|
|
169
|
+
signal.addEventListener("abort", function () {
|
|
170
|
+
eventbus.dispatchAction({
|
|
171
|
+
type: "session_closed",
|
|
172
|
+
id: jrId,
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
return signal;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function setupProcess(
|
|
180
|
+
params: WebdriverParams,
|
|
181
|
+
eventbus: EventBus,
|
|
182
|
+
externalSignal: AbortSignal,
|
|
183
|
+
): ChildProcess {
|
|
184
|
+
let { command, jrId } = params;
|
|
185
|
+
|
|
186
|
+
let process = exec(
|
|
187
|
+
command,
|
|
188
|
+
{ signal: externalSignal },
|
|
189
|
+
(error, _stdout, stderr) => {
|
|
190
|
+
if (stderr) {
|
|
191
|
+
eventbus.dispatchAction({
|
|
192
|
+
id: jrId,
|
|
193
|
+
type: "stderr",
|
|
194
|
+
output: stderr,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
);
|
|
199
|
+
process.addListener("error", function (error) {
|
|
200
|
+
eventbus.dispatchAction({
|
|
201
|
+
id: jrId,
|
|
202
|
+
type: "session_error",
|
|
203
|
+
error: error.toString(),
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
process.addListener("exit", function (statusCode) {
|
|
207
|
+
if (statusCode) {
|
|
208
|
+
eventbus.dispatchAction({
|
|
209
|
+
type: "session_error",
|
|
210
|
+
id: jrId,
|
|
211
|
+
error: `Process returned status code: ${statusCode}`,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
eventbus.dispatchAction({
|
|
215
|
+
type: "session_closed",
|
|
216
|
+
id: jrId,
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
return process;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
async function untilWebdriverReady(
|
|
224
|
+
params: WebdriverParams,
|
|
225
|
+
signal: AbortSignal | undefined,
|
|
226
|
+
): Promise<void> {
|
|
227
|
+
let { url } = params;
|
|
228
|
+
|
|
229
|
+
while (signal && !signal.aborted) {
|
|
230
|
+
try {
|
|
231
|
+
let res = await fetch(new URL("/status", url), {
|
|
232
|
+
method: "GET",
|
|
233
|
+
headers,
|
|
234
|
+
body: null,
|
|
235
|
+
signal,
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
if (200 === res.status) {
|
|
239
|
+
let json = await res.json();
|
|
240
|
+
let { ready } = json?.value;
|
|
241
|
+
if (typeof ready === "boolean" && ready) return;
|
|
242
|
+
}
|
|
243
|
+
} catch {}
|
|
244
|
+
|
|
245
|
+
await sleep(30);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
throw new Error("Webdriver was never ready.");
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
async function getSession(params: WebdriverParams, signal: AbortSignal) {
|
|
252
|
+
let { url, capabilities } = params;
|
|
253
|
+
|
|
254
|
+
let res = await fetch(new URL("/session", url), {
|
|
255
|
+
method: "POST",
|
|
256
|
+
headers,
|
|
257
|
+
body: JSON.stringify({ capabilities: capabilities ?? {} }),
|
|
258
|
+
signal,
|
|
259
|
+
});
|
|
260
|
+
if (200 !== res.status) {
|
|
261
|
+
let cause = await res.text();
|
|
262
|
+
throw new Error("Failed to create a session", { cause });
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
let json = await res.json();
|
|
266
|
+
let { sessionId } = json?.value;
|
|
267
|
+
if (typeof sessionId !== "string") throw new Error("session is not a string");
|
|
268
|
+
|
|
269
|
+
return sessionId;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
async function goToPing(
|
|
273
|
+
params: WebdriverParams,
|
|
274
|
+
signal: AbortSignal,
|
|
275
|
+
sessionId: string,
|
|
276
|
+
hostAndPort: URL,
|
|
277
|
+
) {
|
|
278
|
+
let { url } = params;
|
|
279
|
+
|
|
280
|
+
let pingUrl = new URL("/ping", hostAndPort);
|
|
281
|
+
let getCookie = await fetch(new URL(`/session/${sessionId}/url`, url), {
|
|
282
|
+
method: "POST",
|
|
283
|
+
headers,
|
|
284
|
+
body: JSON.stringify({ url: pingUrl }),
|
|
285
|
+
signal,
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
if (200 !== getCookie.status) {
|
|
289
|
+
let cause = await getCookie.json();
|
|
290
|
+
throw new Error("go-to-cookie request failed", { cause });
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
async function setCookie(
|
|
295
|
+
params: WebdriverParams,
|
|
296
|
+
signal: AbortSignal,
|
|
297
|
+
sessionId: string,
|
|
298
|
+
) {
|
|
299
|
+
let { url, jrId } = params;
|
|
300
|
+
|
|
301
|
+
let cookieReq = await fetch(new URL(`/session/${sessionId}/cookie`, url), {
|
|
302
|
+
method: "POST",
|
|
303
|
+
headers,
|
|
304
|
+
body: JSON.stringify({
|
|
305
|
+
cookie: {
|
|
306
|
+
name: "jackrabbit",
|
|
307
|
+
value: jrId,
|
|
308
|
+
// domain: this.#hostAndPort (issues in firefox)
|
|
309
|
+
path: "/",
|
|
310
|
+
httpOnly: true,
|
|
311
|
+
},
|
|
312
|
+
}),
|
|
313
|
+
signal,
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
if (200 !== cookieReq.status) {
|
|
317
|
+
let cause = await cookieReq.json();
|
|
318
|
+
throw new Error("set-cookie request failed", { cause });
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
async function goToTestPage(
|
|
323
|
+
params: WebdriverParams,
|
|
324
|
+
signal: AbortSignal,
|
|
325
|
+
sessionId: string,
|
|
326
|
+
hostAndPort: URL,
|
|
327
|
+
) {
|
|
328
|
+
let { url } = params;
|
|
329
|
+
|
|
330
|
+
let goToUrlRes = await fetch(new URL(`/session/${sessionId}/url`, url), {
|
|
331
|
+
method: "POST",
|
|
332
|
+
headers,
|
|
333
|
+
body: JSON.stringify({ url: hostAndPort }),
|
|
334
|
+
signal,
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
if (200 !== goToUrlRes.status) throw new Error("go-to-url request failed");
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
async function deleteSession(
|
|
341
|
+
params: WebdriverParams,
|
|
342
|
+
signal: AbortSignal | undefined,
|
|
343
|
+
eventbus: EventBus,
|
|
344
|
+
sessionId: string | undefined,
|
|
345
|
+
) {
|
|
346
|
+
let { url } = params;
|
|
347
|
+
try {
|
|
348
|
+
let delReqest = await fetch(new URL(`/session/${sessionId}`, url), {
|
|
349
|
+
method: "DELETE",
|
|
350
|
+
headers,
|
|
351
|
+
body: null,
|
|
352
|
+
signal: signal,
|
|
353
|
+
});
|
|
354
|
+
if (200 !== delReqest.status) {
|
|
355
|
+
let cause = await delReqest.json();
|
|
356
|
+
throw new Error("delete-cookie request failed", { cause });
|
|
357
|
+
}
|
|
358
|
+
} catch (e) {
|
|
359
|
+
eventbus.dispatchAction({
|
|
360
|
+
type: "session_error",
|
|
361
|
+
id: params.jrId,
|
|
362
|
+
error: e?.toString() ?? "failed to delete browser session error",
|
|
363
|
+
});
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
function sleep(timeMs: number): Promise<void> {
|
|
368
|
+
return new Promise(function (resolve) {
|
|
369
|
+
setTimeout(function () {
|
|
370
|
+
resolve();
|
|
371
|
+
}, timeMs);
|
|
372
|
+
});
|
|
373
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"root":["./src/config.ts","./src/eventbus.ts","./src/logger.ts","./src/mod.ts","./src/results.ts","./src/routes.ts","./src/test_hangar.ts","./src/webdriver.ts"],"version":"5.9.3"}
|
package/cli/dist/cli.d.ts
DELETED
package/cli/dist/cli.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { startRun } from "../../core/dist/mod.js";
|
|
2
|
-
import { Logger } from "./logger.js";
|
|
3
|
-
export async function run(config, importer, logger = new Logger()) {
|
|
4
|
-
for (const file of config.files) {
|
|
5
|
-
const testModules = await importer.load(file);
|
|
6
|
-
await startRun(logger, testModules);
|
|
7
|
-
}
|
|
8
|
-
}
|
package/cli/dist/cli_types.d.ts
DELETED
package/cli/dist/cli_types.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/cli/dist/config.d.ts
DELETED
package/cli/dist/config.js
DELETED
package/cli/dist/importer.d.ts
DELETED
package/cli/dist/importer.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export class Importer {
|
|
2
|
-
#cwd;
|
|
3
|
-
constructor(cwd) {
|
|
4
|
-
this.#cwd = cwd;
|
|
5
|
-
}
|
|
6
|
-
async load(uri) {
|
|
7
|
-
let uri_updated = uri;
|
|
8
|
-
let absolute = uri.startsWith("/");
|
|
9
|
-
if (!absolute) {
|
|
10
|
-
uri_updated = this.#cwd + "/" + uri;
|
|
11
|
-
}
|
|
12
|
-
const { testModules } = await import(uri_updated);
|
|
13
|
-
// verify here
|
|
14
|
-
return testModules;
|
|
15
|
-
}
|
|
16
|
-
}
|
package/cli/dist/logger.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { LoggerAction, LoggerInterface, TestModule } from "../../core/dist/mod.js";
|
|
2
|
-
export declare class Logger implements LoggerInterface {
|
|
3
|
-
#private;
|
|
4
|
-
get failed(): boolean;
|
|
5
|
-
get cancelled(): boolean;
|
|
6
|
-
log(testModules: TestModule[], action: LoggerAction): void;
|
|
7
|
-
}
|
package/cli/dist/logger.js
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
export class Logger {
|
|
2
|
-
#assertions = new Map();
|
|
3
|
-
#data = {
|
|
4
|
-
cancelled: false,
|
|
5
|
-
failed: false,
|
|
6
|
-
startTime: -1,
|
|
7
|
-
testTime: 0,
|
|
8
|
-
};
|
|
9
|
-
get failed() {
|
|
10
|
-
return this.#data.failed;
|
|
11
|
-
}
|
|
12
|
-
get cancelled() {
|
|
13
|
-
return this.#data.cancelled;
|
|
14
|
-
}
|
|
15
|
-
log(testModules, action) {
|
|
16
|
-
if ("start_run" === action.type) {
|
|
17
|
-
this.#data.startTime = action.time;
|
|
18
|
-
}
|
|
19
|
-
if ("cancel_run" === action.type) {
|
|
20
|
-
this.#data.cancelled = true;
|
|
21
|
-
logAssertions(testModules, this.#assertions);
|
|
22
|
-
logResults(this.#data, action.time);
|
|
23
|
-
}
|
|
24
|
-
// add to fails
|
|
25
|
-
if ("end_test" === action.type && action?.assertions) {
|
|
26
|
-
if (Array.isArray(action.assertions) && action.assertions.length === 0)
|
|
27
|
-
return;
|
|
28
|
-
this.#data.testTime += action.endTime - action.startTime;
|
|
29
|
-
this.#data.failed = true;
|
|
30
|
-
let assertions = this.#assertions.get(action.moduleId);
|
|
31
|
-
if (assertions) {
|
|
32
|
-
assertions.set(action.testId, action);
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
this.#assertions.set(action.moduleId, new Map([[action.testId, action]]));
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
if ("end_run" === action.type) {
|
|
39
|
-
logAssertions(testModules, this.#assertions);
|
|
40
|
-
logResults(this.#data, action.time);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
function logAssertions(testModules, fails) {
|
|
45
|
-
for (let [moduleID, module] of testModules.entries()) {
|
|
46
|
-
let failedTests = fails.get(moduleID);
|
|
47
|
-
if (undefined === failedTests)
|
|
48
|
-
continue;
|
|
49
|
-
const { tests, options } = module;
|
|
50
|
-
console.log(`${options?.title ?? `module index: ${moduleID}`}`);
|
|
51
|
-
let numFailedTests = fails.get(moduleID)?.size ?? 0;
|
|
52
|
-
console.log(`${numFailedTests}/${tests.length} tests failed`);
|
|
53
|
-
for (let [index, test] of tests.entries()) {
|
|
54
|
-
let action = failedTests.get(index);
|
|
55
|
-
if (!action || action.type !== "end_test")
|
|
56
|
-
continue;
|
|
57
|
-
console.log(`\t${test.name}\n\t\t${action.assertions}`);
|
|
58
|
-
}
|
|
59
|
-
console.log("\n");
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
function logResults(data, time) {
|
|
63
|
-
let status_with_color = data.failed
|
|
64
|
-
? yellow("\u{2717} failed")
|
|
65
|
-
: blue("\u{2714} passed");
|
|
66
|
-
if (data.cancelled) {
|
|
67
|
-
status_with_color = gray("\u{2717} cancelled");
|
|
68
|
-
}
|
|
69
|
-
const overhead = time - data.startTime;
|
|
70
|
-
console.log(`Results:
|
|
71
|
-
${status_with_color}
|
|
72
|
-
duration: ${data.testTime.toFixed(4)} mS
|
|
73
|
-
overhead: ${overhead.toFixed(4)} mS`);
|
|
74
|
-
}
|
|
75
|
-
// 39 - default foreground color
|
|
76
|
-
// 49 - default background color
|
|
77
|
-
function blue(text) {
|
|
78
|
-
return `\x1b[44m\x1b[97m${text}\x1b[0m`;
|
|
79
|
-
}
|
|
80
|
-
function yellow(text) {
|
|
81
|
-
return `\x1b[43m\x1b[97m${text}\x1b[0m`;
|
|
82
|
-
}
|
|
83
|
-
function gray(text) {
|
|
84
|
-
return `\x1b[100m\x1b[97m${text}\x1b[0m`;
|
|
85
|
-
}
|
|
86
|
-
function logTestModule(moduleID, title) {
|
|
87
|
-
console.log(`module: ${title ?? `module index: ${moduleID}`}`);
|
|
88
|
-
}
|
package/cli/dist/mod.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export type { ConfigInterface } from "./cli_types.ts";
|
|
2
|
-
export type { ImporterInterface } from "./cli_types.ts";
|
|
3
|
-
export { Config } from "./config.js";
|
|
4
|
-
export { Importer } from "./importer.js";
|
|
5
|
-
export { Logger } from "./logger.js";
|
|
6
|
-
export { run } from "./cli.js";
|
package/cli/dist/mod.js
DELETED
package/cli/src/cli.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { ConfigInterface, ImporterInterface } from "./cli_types.ts";
|
|
2
|
-
import type { LoggerInterface } from "../../core/dist/mod.ts";
|
|
3
|
-
|
|
4
|
-
import { startRun } from "../../core/dist/mod.js";
|
|
5
|
-
import { Logger } from "./logger.js";
|
|
6
|
-
|
|
7
|
-
export async function run(
|
|
8
|
-
config: ConfigInterface,
|
|
9
|
-
importer: ImporterInterface,
|
|
10
|
-
logger: LoggerInterface = new Logger(),
|
|
11
|
-
) {
|
|
12
|
-
for (const file of config.files) {
|
|
13
|
-
const testModules = await importer.load(file);
|
|
14
|
-
|
|
15
|
-
await startRun(logger, testModules);
|
|
16
|
-
}
|
|
17
|
-
}
|
package/cli/src/cli_types.ts
DELETED
package/cli/src/config.ts
DELETED
package/cli/src/importer.ts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import type { TestModule } from "../../core/dist/mod.ts";
|
|
2
|
-
import type { ImporterInterface } from "./cli_types.ts";
|
|
3
|
-
|
|
4
|
-
export class Importer implements ImporterInterface {
|
|
5
|
-
#cwd: string;
|
|
6
|
-
|
|
7
|
-
constructor(cwd: string) {
|
|
8
|
-
this.#cwd = cwd;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
async load(uri: string): Promise<TestModule[]> {
|
|
12
|
-
let uri_updated = uri;
|
|
13
|
-
|
|
14
|
-
let absolute = uri.startsWith("/");
|
|
15
|
-
if (!absolute) {
|
|
16
|
-
uri_updated = this.#cwd + "/" + uri;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const { testModules } = await import(uri_updated);
|
|
20
|
-
|
|
21
|
-
// verify here
|
|
22
|
-
|
|
23
|
-
return testModules;
|
|
24
|
-
}
|
|
25
|
-
}
|