@brillout/test-e2e 0.4.12 → 0.4.14
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/dist/Logs.d.ts +7 -5
- package/dist/Logs.js +21 -16
- package/dist/findTestFiles.js +2 -2
- package/dist/parallel-ci.d.ts +4 -0
- package/dist/{github-action.js → parallel-ci.js} +8 -8
- package/dist/runAll.js +10 -8
- package/dist/setup.js +9 -27
- package/dist/utils/assert.js +1 -1
- package/package.json +1 -1
- package/dist/github-action.d.ts +0 -4
package/dist/Logs.d.ts
CHANGED
|
@@ -2,9 +2,9 @@ export { expectError };
|
|
|
2
2
|
export declare const Logs: {
|
|
3
3
|
add: typeof add;
|
|
4
4
|
flushLogs: typeof flushLogs;
|
|
5
|
-
|
|
5
|
+
logErrorsAndWarnings: typeof logErrorsAndWarnings;
|
|
6
6
|
clearLogs: typeof clearLogs;
|
|
7
|
-
|
|
7
|
+
hasFailLogs: typeof hasFailLogs;
|
|
8
8
|
logEagerly: boolean;
|
|
9
9
|
};
|
|
10
10
|
declare type LogSource = 'stdout' | 'stderr' | 'Browser Error' | 'Browser Warning' | 'Browser Log' | 'Playwright' | 'run()' | 'run() failure' | 'test()' | 'Connection Error';
|
|
@@ -13,13 +13,15 @@ declare type LogEntry = {
|
|
|
13
13
|
logText: string;
|
|
14
14
|
logTimestamp: string;
|
|
15
15
|
isNotFailure: boolean;
|
|
16
|
+
loggedAfterExit: boolean;
|
|
16
17
|
};
|
|
17
|
-
declare function
|
|
18
|
+
declare function hasFailLogs(failOnWarning: boolean): boolean;
|
|
18
19
|
declare function clearLogs(): void;
|
|
19
|
-
declare function
|
|
20
|
+
declare function logErrorsAndWarnings(): void;
|
|
20
21
|
declare function flushLogs(): void;
|
|
21
|
-
declare function add({ logSource, logText }: {
|
|
22
|
+
declare function add({ logSource, logText, loggedAfterExit, }: {
|
|
22
23
|
logSource: LogSource;
|
|
23
24
|
logText: string;
|
|
25
|
+
loggedAfterExit?: boolean;
|
|
24
26
|
}): void;
|
|
25
27
|
declare function expectError(logFilter: (browserLog: LogEntry) => boolean): void;
|
package/dist/Logs.js
CHANGED
|
@@ -7,9 +7,9 @@ exports.Logs = exports.expectError = void 0;
|
|
|
7
7
|
exports.Logs = {
|
|
8
8
|
add,
|
|
9
9
|
flushLogs,
|
|
10
|
-
|
|
10
|
+
logErrorsAndWarnings,
|
|
11
11
|
clearLogs,
|
|
12
|
-
|
|
12
|
+
hasFailLogs,
|
|
13
13
|
logEagerly: false,
|
|
14
14
|
};
|
|
15
15
|
const utils_1 = require("./utils");
|
|
@@ -18,19 +18,23 @@ const getCurrentTest_1 = require("./getCurrentTest");
|
|
|
18
18
|
const getConfig_1 = require("./getConfig");
|
|
19
19
|
const logSection_1 = require("./logSection");
|
|
20
20
|
let logEntries = [];
|
|
21
|
-
function
|
|
22
|
-
const
|
|
23
|
-
return
|
|
21
|
+
function hasFailLogs(failOnWarning) {
|
|
22
|
+
const failLogs = getErrorLogs(failOnWarning);
|
|
23
|
+
return failLogs.length > 0;
|
|
24
24
|
}
|
|
25
|
-
function getErrorLogs(
|
|
26
|
-
const errorLogs = logEntries.filter(({ logSource, isNotFailure }) => {
|
|
25
|
+
function getErrorLogs(includeWarnings) {
|
|
26
|
+
const errorLogs = logEntries.filter(({ logSource, isNotFailure, loggedAfterExit }) => {
|
|
27
27
|
if (isNotFailure) {
|
|
28
|
-
return;
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
// taskkill makes process exit with exit code `1` which makes npm emit logs on stderr
|
|
31
|
+
if (loggedAfterExit && (0, utils_1.isWindows)() && logSource === 'stderr') {
|
|
32
|
+
return false;
|
|
29
33
|
}
|
|
30
34
|
if (logSource === 'run() failure') {
|
|
31
35
|
return true;
|
|
32
36
|
}
|
|
33
|
-
if (
|
|
37
|
+
if (includeWarnings && (logSource === 'Browser Warning' || logSource === 'stderr')) {
|
|
34
38
|
return true;
|
|
35
39
|
}
|
|
36
40
|
if (logSource === 'Browser Error') {
|
|
@@ -43,19 +47,19 @@ function getErrorLogs(failOnWarning) {
|
|
|
43
47
|
function clearLogs() {
|
|
44
48
|
logEntries = [];
|
|
45
49
|
}
|
|
46
|
-
function
|
|
47
|
-
|
|
50
|
+
function logErrorsAndWarnings() {
|
|
51
|
+
const errorAndWarningLogs = getErrorLogs(true);
|
|
52
|
+
if (errorAndWarningLogs.length === 0)
|
|
48
53
|
return;
|
|
49
|
-
(0, logSection_1.logSection)(
|
|
50
|
-
|
|
51
|
-
errorLogs.forEach((logEntry) => printLog(logEntry));
|
|
54
|
+
(0, logSection_1.logSection)('ERROR & WARNING LOGS');
|
|
55
|
+
errorAndWarningLogs.forEach((logEntry) => printLog(logEntry));
|
|
52
56
|
}
|
|
53
57
|
function flushLogs() {
|
|
54
58
|
(0, logSection_1.logSection)('ALL LOGS');
|
|
55
|
-
logEntries.forEach((logEntry) => printLog(logEntry));
|
|
59
|
+
logEntries.filter((logEntry) => !logEntry.loggedAfterExit).forEach((logEntry) => printLog(logEntry));
|
|
56
60
|
logEntries = [];
|
|
57
61
|
}
|
|
58
|
-
function add({ logSource, logText }) {
|
|
62
|
+
function add({ logSource, logText, loggedAfterExit = false, }) {
|
|
59
63
|
const logTimestamp = getTimestamp();
|
|
60
64
|
const isNotFailure = (() => {
|
|
61
65
|
const config = (0, getConfig_1.getConfig)();
|
|
@@ -72,6 +76,7 @@ function add({ logSource, logText }) {
|
|
|
72
76
|
logText,
|
|
73
77
|
logTimestamp,
|
|
74
78
|
isNotFailure,
|
|
79
|
+
loggedAfterExit,
|
|
75
80
|
};
|
|
76
81
|
logEntries.push(logEntry);
|
|
77
82
|
if (exports.Logs.logEagerly) {
|
package/dist/findTestFiles.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.findTestFiles = void 0;
|
|
4
4
|
const utils_1 = require("./utils");
|
|
5
|
-
const
|
|
5
|
+
const parallel_ci_1 = require("./parallel-ci");
|
|
6
6
|
// Unit tests `**/*.spec.*` are handled by Vitest
|
|
7
7
|
const testFilenamePattern = '**/*.test.ts';
|
|
8
8
|
async function findTestFiles(findFilter) {
|
|
9
9
|
{
|
|
10
|
-
const testFiles = (0,
|
|
10
|
+
const testFiles = (0, parallel_ci_1.getTestFilesForCurrentJob)();
|
|
11
11
|
if (testFiles)
|
|
12
12
|
return testFiles;
|
|
13
13
|
}
|
|
@@ -3,21 +3,21 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.getTestFilesForCurrentJob = exports.abortIfParallelCI = void 0;
|
|
7
7
|
const utils_1 = require("./utils");
|
|
8
8
|
const fs_1 = __importDefault(require("fs"));
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
10
|
const cwd = process.cwd();
|
|
11
|
-
function
|
|
12
|
-
if (
|
|
11
|
+
function abortIfParallelCI() {
|
|
12
|
+
if (isParallelCI()) {
|
|
13
13
|
process.exit(1);
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
|
-
exports.
|
|
17
|
-
function
|
|
18
|
-
return
|
|
16
|
+
exports.abortIfParallelCI = abortIfParallelCI;
|
|
17
|
+
function isParallelCI() {
|
|
18
|
+
return getTestFilesForCurrentJob() !== null;
|
|
19
19
|
}
|
|
20
|
-
function
|
|
20
|
+
function getTestFilesForCurrentJob() {
|
|
21
21
|
if (!('TEST_FILES' in process.env))
|
|
22
22
|
return null;
|
|
23
23
|
(0, utils_1.assert)(process.env.TEST_FILES);
|
|
@@ -27,4 +27,4 @@ function getTestFiles() {
|
|
|
27
27
|
});
|
|
28
28
|
return testFiles;
|
|
29
29
|
}
|
|
30
|
-
exports.
|
|
30
|
+
exports.getTestFilesForCurrentJob = getTestFilesForCurrentJob;
|
package/dist/runAll.js
CHANGED
|
@@ -5,7 +5,7 @@ const getCurrentTest_1 = require("./getCurrentTest");
|
|
|
5
5
|
const Logs_1 = require("./Logs");
|
|
6
6
|
const utils_1 = require("./utils");
|
|
7
7
|
const utils_2 = require("./utils");
|
|
8
|
-
const
|
|
8
|
+
const parallel_ci_1 = require("./parallel-ci");
|
|
9
9
|
const getCurrentTest_2 = require("./getCurrentTest");
|
|
10
10
|
const getBrowser_1 = require("./getBrowser");
|
|
11
11
|
const buildTs_1 = require("./buildTs");
|
|
@@ -45,6 +45,7 @@ exports.runAll = runAll;
|
|
|
45
45
|
async function buildAndTest(testFile, browser, isSecondAttempt) {
|
|
46
46
|
(0, utils_1.assert)(testFile.endsWith('.ts'));
|
|
47
47
|
const testFileJs = testFile.replace('.ts', '.mjs');
|
|
48
|
+
(0, utils_1.assert)(testFileJs.endsWith('.mjs'));
|
|
48
49
|
const cleanBuild = await (0, buildTs_1.buildTs)(testFile, testFileJs);
|
|
49
50
|
(0, getCurrentTest_2.setCurrentTest)(testFile);
|
|
50
51
|
try {
|
|
@@ -56,7 +57,6 @@ async function buildAndTest(testFile, browser, isSecondAttempt) {
|
|
|
56
57
|
const { success, clean } = await runTests(browser, isSecondAttempt);
|
|
57
58
|
await clean();
|
|
58
59
|
(0, getCurrentTest_2.setCurrentTest)(null);
|
|
59
|
-
(0, utils_1.assert)(testFileJs.endsWith('.mjs'));
|
|
60
60
|
return success;
|
|
61
61
|
}
|
|
62
62
|
async function runTests(browser, isSecondAttempt) {
|
|
@@ -81,13 +81,15 @@ async function runTests(browser, isSecondAttempt) {
|
|
|
81
81
|
(0, utils_1.assert)(testInfo.afterEach);
|
|
82
82
|
// Set when user calls `test()`
|
|
83
83
|
(0, utils_1.assert)(testInfo.tests);
|
|
84
|
-
const
|
|
84
|
+
const { isFlaky } = testInfo.runInfo;
|
|
85
|
+
const isFinalAttempt = isSecondAttempt || !isFlaky;
|
|
85
86
|
const clean = async () => {
|
|
86
87
|
await testInfo.terminateServer?.();
|
|
87
88
|
await page.close();
|
|
88
89
|
};
|
|
89
90
|
const failure = () => {
|
|
90
|
-
|
|
91
|
+
if (!isFlaky)
|
|
92
|
+
(0, parallel_ci_1.abortIfParallelCI)();
|
|
91
93
|
return { success: false, clean };
|
|
92
94
|
};
|
|
93
95
|
try {
|
|
@@ -116,7 +118,7 @@ async function runTests(browser, isSecondAttempt) {
|
|
|
116
118
|
testInfo.afterEach(!!err);
|
|
117
119
|
{
|
|
118
120
|
const failOnWarning = !testInfo.runInfo.doNotFailOnWarning;
|
|
119
|
-
const hasErrorLog = Logs_1.Logs.
|
|
121
|
+
const hasErrorLog = Logs_1.Logs.hasFailLogs(failOnWarning);
|
|
120
122
|
const isFailure = err || hasErrorLog;
|
|
121
123
|
if (isFailure) {
|
|
122
124
|
if (err) {
|
|
@@ -129,7 +131,7 @@ async function runTests(browser, isSecondAttempt) {
|
|
|
129
131
|
else {
|
|
130
132
|
(0, utils_1.assert)(false);
|
|
131
133
|
}
|
|
132
|
-
Logs_1.Logs.
|
|
134
|
+
Logs_1.Logs.logErrorsAndWarnings();
|
|
133
135
|
Logs_1.Logs.flushLogs();
|
|
134
136
|
return failure();
|
|
135
137
|
}
|
|
@@ -139,11 +141,11 @@ async function runTests(browser, isSecondAttempt) {
|
|
|
139
141
|
// Check whether stderr emitted during testInfo.terminateServer()
|
|
140
142
|
{
|
|
141
143
|
const failOnWarning = true;
|
|
142
|
-
if (Logs_1.Logs.
|
|
144
|
+
if (Logs_1.Logs.hasFailLogs(failOnWarning) &&
|
|
143
145
|
// See comments about taskkill in src/setup.ts
|
|
144
146
|
!(0, utils_1.isWindows)()) {
|
|
145
147
|
(0, logTestStatus_1.logFail)(`${getErrorType(failOnWarning)} occurred during server termination`, isFinalAttempt);
|
|
146
|
-
Logs_1.Logs.
|
|
148
|
+
Logs_1.Logs.logErrorsAndWarnings();
|
|
147
149
|
Logs_1.Logs.flushLogs();
|
|
148
150
|
return failure();
|
|
149
151
|
}
|
package/dist/setup.js
CHANGED
|
@@ -256,11 +256,10 @@ function stopProcess({ proc, cwd, cmd, force, }) {
|
|
|
256
256
|
(0, child_process_1.spawn)('taskkill', ['/pid', String(proc.pid), '/f', '/t'], {
|
|
257
257
|
stdio: [
|
|
258
258
|
'ignore',
|
|
259
|
-
// Ignore
|
|
259
|
+
// Ignore following log to avoid polluting non-error logs. (Setting 'inherit' instead of 'ignore' attaches stdout to the root process and not to `proc` which is why the stdout of taskkill isn't intercepted by `proc.stdout.on('data', () => /* ... */)`.)
|
|
260
260
|
// ```
|
|
261
261
|
// SUCCESS: The process with PID 6932 (child process of PID 2744) has been terminated.
|
|
262
262
|
// ```
|
|
263
|
-
// (Setting 'inherit' instead of 'ignore' attaches stdout to the root process and not to `proc` which is why the stdout of taskkill isn't intercepted by `proc.stdout.on('data', () => /* ... */)`.
|
|
264
263
|
'ignore',
|
|
265
264
|
// Ignoring stderr doesn't solve the problem that taskkill makes the process exit with code 1
|
|
266
265
|
'inherit', // stderr
|
|
@@ -323,14 +322,8 @@ function execRunScript({ onStdout, onFailure, onExit, }) {
|
|
|
323
322
|
Logs_1.Logs.add({
|
|
324
323
|
logSource: 'stdout',
|
|
325
324
|
logText: data,
|
|
325
|
+
loggedAfterExit: procExited,
|
|
326
326
|
});
|
|
327
|
-
/* These assertions sometimes fail, see comments in assertNotExited()
|
|
328
|
-
assertNotExited(data)
|
|
329
|
-
assert(getRunInfo().cmd === cmd)
|
|
330
|
-
/*/
|
|
331
|
-
if (procExited)
|
|
332
|
-
return undefined;
|
|
333
|
-
//*/
|
|
334
327
|
onStdout?.(data);
|
|
335
328
|
});
|
|
336
329
|
proc.stderr.on('data', async (chunk) => {
|
|
@@ -338,14 +331,8 @@ function execRunScript({ onStdout, onFailure, onExit, }) {
|
|
|
338
331
|
Logs_1.Logs.add({
|
|
339
332
|
logSource: 'stderr',
|
|
340
333
|
logText: data,
|
|
334
|
+
loggedAfterExit: procExited,
|
|
341
335
|
});
|
|
342
|
-
/* These assertions sometimes fail, see comments in assertNotExited()
|
|
343
|
-
assertNotExited(data)
|
|
344
|
-
assert(getRunInfo().cmd === cmd)
|
|
345
|
-
/*/
|
|
346
|
-
if (procExited)
|
|
347
|
-
return undefined;
|
|
348
|
-
//*/
|
|
349
336
|
if (data.includes('EADDRINUSE')) {
|
|
350
337
|
await exitAndFail(new Error('Port conflict? Port already in use EADDRINUSE.'));
|
|
351
338
|
}
|
|
@@ -375,15 +362,6 @@ function execRunScript({ onStdout, onFailure, onExit, }) {
|
|
|
375
362
|
exitPromiseResolve();
|
|
376
363
|
});
|
|
377
364
|
return { terminate, processHasExited };
|
|
378
|
-
/* Node.js seems to occasionally emit 'data' events after having the emitted 'exit' event, for example:
|
|
379
|
-
* - `{"data":"[0] npm run serve:cdn exited with code SIGTERM\n","dataLength":48}`.
|
|
380
|
-
function assertNotExited(data: string) {
|
|
381
|
-
if (!procExited) return
|
|
382
|
-
// Sometimes, a single white space is emitted after 'exit' has been emitted.
|
|
383
|
-
if (data.trim().length === 0) return
|
|
384
|
-
assert(false, { data, dataLength: data.length })
|
|
385
|
-
}
|
|
386
|
-
*/
|
|
387
365
|
function processHasExited() {
|
|
388
366
|
return procExited;
|
|
389
367
|
}
|
|
@@ -391,8 +369,12 @@ function execRunScript({ onStdout, onFailure, onExit, }) {
|
|
|
391
369
|
let resolve;
|
|
392
370
|
let reject;
|
|
393
371
|
const promise = new Promise((_resolve, _reject) => {
|
|
394
|
-
resolve =
|
|
395
|
-
|
|
372
|
+
resolve = () => {
|
|
373
|
+
_resolve();
|
|
374
|
+
};
|
|
375
|
+
reject = () => {
|
|
376
|
+
_reject();
|
|
377
|
+
};
|
|
396
378
|
});
|
|
397
379
|
const timeout = setTimeout(() => {
|
|
398
380
|
const errMsg = 'Process termination timeout. Cmd: ' + cmd;
|
package/dist/utils/assert.js
CHANGED
|
@@ -34,7 +34,7 @@ function assert(condition, debugInfo) {
|
|
|
34
34
|
(0, logTestStatus_1.logFail)('a bug occurred in @brillout/test-e2e', true);
|
|
35
35
|
(0, logError_1.logError)(internalError, 'BUG');
|
|
36
36
|
logDebugInfo();
|
|
37
|
-
Logs_1.Logs.
|
|
37
|
+
Logs_1.Logs.logErrorsAndWarnings();
|
|
38
38
|
Logs_1.Logs.flushLogs();
|
|
39
39
|
throw new Error('Bug. See messages above.');
|
|
40
40
|
}
|
package/package.json
CHANGED
package/dist/github-action.d.ts
DELETED