@brillout/test-e2e 0.1.20 → 0.1.22

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 CHANGED
@@ -1,9 +1,9 @@
1
1
  export { expectError };
2
2
  export declare const Logs: {
3
3
  add: typeof add;
4
- flush: typeof flush;
5
- clear: typeof clear;
6
- hasError: typeof hasError;
4
+ flushLogs: typeof flushLogs;
5
+ clearLogs: typeof clearLogs;
6
+ hasErrorLogs: typeof hasErrorLogs;
7
7
  flushEagerly: boolean;
8
8
  };
9
9
  declare type LogSource = 'stdout' | 'stderr' | 'Browser Error' | 'Browser Warning' | 'Browser Log' | 'Playwright' | 'run()' | 'run() failure' | 'test()' | 'Connection Error';
@@ -13,9 +13,9 @@ declare type LogEntry = {
13
13
  logTimestamp: string;
14
14
  isNotFailure: boolean;
15
15
  };
16
- declare function hasError(onlyFailOnBrowserError: boolean): boolean;
17
- declare function clear(): void;
18
- declare function flush(): void;
16
+ declare function hasErrorLogs(onlyFailOnBrowserError?: boolean): boolean;
17
+ declare function clearLogs(): void;
18
+ declare function flushLogs(): void;
19
19
  declare function add({ logSource, logText }: {
20
20
  logSource: LogSource;
21
21
  logText: string;
package/dist/Logs.js CHANGED
@@ -6,9 +6,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.Logs = exports.expectError = void 0;
7
7
  exports.Logs = {
8
8
  add,
9
- flush,
10
- clear,
11
- hasError,
9
+ flushLogs,
10
+ clearLogs,
11
+ hasErrorLogs,
12
12
  flushEagerly: false,
13
13
  };
14
14
  const utils_1 = require("./utils");
@@ -16,8 +16,7 @@ const picocolors_1 = __importDefault(require("picocolors"));
16
16
  const getCurrentTest_1 = require("./getCurrentTest");
17
17
  const getConfig_1 = require("./getConfig");
18
18
  let logEntries = [];
19
- let logEntriesNotPrinted = [];
20
- function hasError(onlyFailOnBrowserError) {
19
+ function hasErrorLogs(onlyFailOnBrowserError = false) {
21
20
  const logErrors = logEntries.filter(({ logSource, isNotFailure }) => {
22
21
  if (isNotFailure) {
23
22
  return;
@@ -35,13 +34,12 @@ function hasError(onlyFailOnBrowserError) {
35
34
  });
36
35
  return logErrors.length > 0;
37
36
  }
38
- function clear() {
37
+ function clearLogs() {
39
38
  logEntries = [];
40
- logEntriesNotPrinted = [];
41
39
  }
42
- function flush() {
43
- logEntriesNotPrinted.forEach((logEntry) => printLog(logEntry));
44
- logEntriesNotPrinted = [];
40
+ function flushLogs() {
41
+ logEntries.forEach((logEntry) => printLog(logEntry));
42
+ logEntries = [];
45
43
  }
46
44
  function add({ logSource, logText }) {
47
45
  const logTimestamp = getTimestamp();
@@ -61,10 +59,9 @@ function add({ logSource, logText }) {
61
59
  logTimestamp,
62
60
  isNotFailure,
63
61
  };
64
- logEntriesNotPrinted.push(logEntry);
65
62
  logEntries.push(logEntry);
66
63
  if (exports.Logs.flushEagerly) {
67
- flush();
64
+ flushLogs();
68
65
  }
69
66
  }
70
67
  function expectError(logFilter) {
package/dist/runTests.js CHANGED
@@ -5,6 +5,7 @@ const getCurrentTest_1 = require("./getCurrentTest");
5
5
  const Logs_1 = require("./Logs");
6
6
  const utils_1 = require("./utils");
7
7
  const picocolors_1 = require("picocolors");
8
+ const logsContainError_errMsg = 'The browser/server threw/logged one or more error/warning, see logs below.';
8
9
  async function runTests(browser) {
9
10
  const testInfo = (0, getCurrentTest_1.getCurrentTest)();
10
11
  if (utils_1.isTTY) {
@@ -34,7 +35,7 @@ async function runTests(browser) {
34
35
  catch (err) {
35
36
  logTestsResult(false);
36
37
  console.log(err);
37
- Logs_1.Logs.flush();
38
+ Logs_1.Logs.flushLogs();
38
39
  process.exit(1);
39
40
  }
40
41
  for (const { testDesc, testFn } of testInfo.tests) {
@@ -52,7 +53,7 @@ async function runTests(browser) {
52
53
  }
53
54
  done(!!err);
54
55
  testInfo.afterEach(!!err);
55
- const hasErrorLog = Logs_1.Logs.hasError(testInfo.runInfo.onlyFailOnBrowserError);
56
+ const hasErrorLog = Logs_1.Logs.hasErrorLogs(testInfo.runInfo.onlyFailOnBrowserError);
56
57
  const isFailure = err || hasErrorLog;
57
58
  if (isFailure) {
58
59
  logTestsResult(false);
@@ -60,17 +61,29 @@ async function runTests(browser) {
60
61
  console.error(err);
61
62
  }
62
63
  if (hasErrorLog) {
63
- console.log(new Error('The browser/server threw/logged one or more error/warning, see logs below.'));
64
+ console.log(new Error(logsContainError_errMsg));
64
65
  }
65
- Logs_1.Logs.flush();
66
+ Logs_1.Logs.flushLogs();
66
67
  process.exit(1);
67
68
  }
68
69
  else {
69
- Logs_1.Logs.clear();
70
+ Logs_1.Logs.clearLogs();
70
71
  }
71
72
  }
72
73
  await testInfo.terminateServer();
73
74
  await page.close();
75
+ // Handle case that an error occured during `terminateServer()`
76
+ if (Logs_1.Logs.hasErrorLogs()) {
77
+ if ((0, utils_1.isWindows)()) {
78
+ // On Windows, the sever sometimes terminates with an exit code of `1`. I don't know why.
79
+ Logs_1.Logs.clearLogs();
80
+ }
81
+ else {
82
+ console.log(new Error(logsContainError_errMsg));
83
+ Logs_1.Logs.flushLogs();
84
+ process.exit(1);
85
+ }
86
+ }
74
87
  logTestsResult(true);
75
88
  }
76
89
  exports.runTests = runTests;
@@ -110,7 +123,7 @@ function logTestsResult(success) {
110
123
  return;
111
124
  }
112
125
  if (testInfo.skipped) {
113
- console.log(`${skipStyle('SKIP')} ${testInfo.testFile} (${testInfo.skipped})`);
126
+ console.log(`${skipStyle('WARN')} ${testInfo.testFile} (${testInfo.skipped})`);
114
127
  }
115
128
  else {
116
129
  console.log(`${failStyle('FAIL')} ${testInfo.testFile}`);
package/dist/setup.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { sleep } from './utils';
1
+ import { sleep, isWindows, isLinux, isGithubAction, isMac } from './utils';
2
2
  import fetch_ from 'node-fetch';
3
3
  export { partRegex } from '@brillout/part-regex';
4
4
  export { autoRetry };
@@ -31,7 +31,3 @@ declare function autoRetry(test: () => void | Promise<void>, { timeout }?: {
31
31
  declare function fetchHtml(pathname: string): Promise<string>;
32
32
  declare function fetch(...args: Parameters<typeof fetch_>): Promise<import("node-fetch").Response>;
33
33
  declare function isMinNodeVersion(minNodeVersion: 14): boolean;
34
- declare function isWindows(): boolean;
35
- declare function isLinux(): boolean;
36
- declare function isMac(): boolean;
37
- declare function isGithubAction(): boolean;
package/dist/setup.js CHANGED
@@ -8,6 +8,10 @@ const child_process_1 = require("child_process");
8
8
  const path_1 = require("path");
9
9
  const utils_1 = require("./utils");
10
10
  Object.defineProperty(exports, "sleep", { enumerable: true, get: function () { return utils_1.sleep; } });
11
+ Object.defineProperty(exports, "isWindows", { enumerable: true, get: function () { return utils_1.isWindows; } });
12
+ Object.defineProperty(exports, "isLinux", { enumerable: true, get: function () { return utils_1.isLinux; } });
13
+ Object.defineProperty(exports, "isGithubAction", { enumerable: true, get: function () { return utils_1.isGithubAction; } });
14
+ Object.defineProperty(exports, "isMac", { enumerable: true, get: function () { return utils_1.isMac; } });
11
15
  const node_fetch_1 = __importDefault(require("node-fetch"));
12
16
  const utils_2 = require("./utils");
13
17
  const Logs_1 = require("./Logs");
@@ -25,9 +29,9 @@ exports.urlBaseChange = urlBaseChange;
25
29
  var editFile_2 = require("./editFile");
26
30
  Object.defineProperty(exports, "editFile", { enumerable: true, get: function () { return editFile_2.editFile; } });
27
31
  Object.defineProperty(exports, "editFileRevert", { enumerable: true, get: function () { return editFile_2.editFileRevert; } });
28
- const TIMEOUT_NPM_SCRIPT = 30 * 1000 * (!isGithubAction() ? 1 : isLinux() ? 1 : isWindows() ? 5 : 4);
29
- const TIMEOUT_TEST_FUNCTION = 60 * 1000 * (!isGithubAction() ? 1 : isWindows() ? 5 : 3);
30
- const TIMEOUT_PROCESS_TERMINATION = 10 * 1000 * (!isGithubAction() ? 1 : isLinux() ? 1 : 4);
32
+ const TIMEOUT_NPM_SCRIPT = 2 * 60 * 1000;
33
+ const TIMEOUT_TEST_FUNCTION = 60 * 1000 * (!(0, utils_1.isGithubAction)() ? 1 : (0, utils_1.isWindows)() ? 5 : 3);
34
+ const TIMEOUT_PROCESS_TERMINATION = 10 * 1000 * (!(0, utils_1.isGithubAction)() ? 1 : (0, utils_1.isLinux)() ? 1 : 4);
31
35
  const TIMEOUT_AUTORETRY = TIMEOUT_TEST_FUNCTION / 2;
32
36
  const TIMEOUT_PLAYWRIGHT = TIMEOUT_TEST_FUNCTION / 2;
33
37
  function skip(reason) {
@@ -79,6 +83,10 @@ additionalTimeout = 0, serverIsReadyMessage, serverIsReadyDelay = 1000, inspect
79
83
  }
80
84
  };
81
85
  testInfo.terminateServer = async () => {
86
+ Logs_1.Logs.add({
87
+ logSource: 'run()',
88
+ logText: 'Terminate server.',
89
+ });
82
90
  page_1.page.off('console', onConsole);
83
91
  page_1.page.off('pageerror', onPageError);
84
92
  // `runProcess` is `undefined` if `start()` failed.
@@ -137,7 +145,7 @@ async function start() {
137
145
  (0, utils_2.assert)(getRunInfo().cmd === cmd);
138
146
  Logs_1.Logs.add({
139
147
  logSource: 'run()',
140
- logText: 'server is ready',
148
+ logText: 'Server is ready.',
141
149
  });
142
150
  hasSuccessfullyStarted = true;
143
151
  clearTimeout(serverStartTimeout);
@@ -169,7 +177,7 @@ async function start() {
169
177
  rejectServerStart(new Error(errMsg));
170
178
  }, timeoutTotal);
171
179
  // Kill any process that listens to port `3000`
172
- if (!process.env.CI && isLinux()) {
180
+ if (!process.env.CI && (0, utils_1.isLinux)()) {
173
181
  await (0, utils_1.runCommand)('fuser -k 3000/tcp', { swallowError: true, timeout: 10 * 1000 });
174
182
  }
175
183
  const { terminate, processHasExited } = execRunScript({
@@ -212,7 +220,7 @@ function stopProcess({ proc, cwd, cmd, signal, }) {
212
220
  reject = _reject;
213
221
  });
214
222
  const onProcessClose = (code) => {
215
- if (code === 0 || code === null || (code === 1 && isWindows())) {
223
+ if (code === 0 || code === null || (code === 1 && (0, utils_1.isWindows)())) {
216
224
  resolve();
217
225
  }
218
226
  else {
@@ -221,7 +229,7 @@ function stopProcess({ proc, cwd, cmd, signal, }) {
221
229
  };
222
230
  proc.on('close', onProcessClose);
223
231
  proc.on('exit', onProcessClose);
224
- if (isWindows()) {
232
+ if ((0, utils_1.isWindows)()) {
225
233
  // - https://github.com/nodejs/node/issues/3617#issuecomment-377731194
226
234
  // - https://stackoverflow.com/questions/23706055/why-can-i-not-kill-my-child-process-in-nodejs-on-windows/28163919#28163919
227
235
  (0, child_process_1.spawn)('taskkill', ['/pid', String(proc.pid), '/f', '/t'], {
@@ -264,7 +272,7 @@ function execRunScript({ onStdout, onFailure, onExit, }) {
264
272
  const { cwd, cmd } = getRunInfo();
265
273
  let [command, ...args] = cmd.split(' ');
266
274
  let detached = true;
267
- if (isWindows()) {
275
+ if ((0, utils_1.isWindows)()) {
268
276
  detached = false;
269
277
  if (command === 'npm' || command === 'pnpm') {
270
278
  command = command + '.cmd';
@@ -309,11 +317,13 @@ function execRunScript({ onStdout, onFailure, onExit, }) {
309
317
  await exitAndFail(new Error('Port conflict? Port already in use EADDRINUSE.'));
310
318
  }
311
319
  });
320
+ let exitPromiseResolve;
321
+ const exitPromise = new Promise((r) => (exitPromiseResolve = r));
312
322
  proc.on('exit', (code) => {
313
323
  procExited = true;
314
324
  (0, utils_2.assert)(getRunInfo().cmd === cmd);
315
325
  const exitIsPossible = onExit();
316
- const isSuccessCode = [0, null].includes(code) || (isWindows() && code === 1);
326
+ const isSuccessCode = [0, null].includes(code) || ((0, utils_1.isWindows)() && code === 1);
317
327
  const isExpected = isSuccessCode && exitIsPossible;
318
328
  if (!isExpected) {
319
329
  const errMsg = `Unexpected premature process termination, exit code: ${code}`;
@@ -329,6 +339,7 @@ function execRunScript({ onStdout, onFailure, onExit, }) {
329
339
  logSource: 'run()',
330
340
  });
331
341
  }
342
+ exitPromiseResolve();
332
343
  });
333
344
  return { terminate, processHasExited };
334
345
  function processHasExited() {
@@ -365,6 +376,7 @@ function execRunScript({ onStdout, onFailure, onExit, }) {
365
376
  });
366
377
  }
367
378
  clearTimeout(timeout);
379
+ await exitPromise;
368
380
  resolve();
369
381
  return promise;
370
382
  }
@@ -436,26 +448,6 @@ function isMinNodeVersion(minNodeVersion) {
436
448
  return major >= minNodeVersion;
437
449
  }
438
450
  exports.isMinNodeVersion = isMinNodeVersion;
439
- function isWindows() {
440
- return process.platform === 'win32';
441
- }
442
- exports.isWindows = isWindows;
443
- function isLinux() {
444
- return process.platform === 'linux';
445
- }
446
- exports.isLinux = isLinux;
447
- function isMac() {
448
- if (process.platform === 'darwin') {
449
- return true;
450
- }
451
- (0, utils_2.assert)(isLinux() || isWindows());
452
- return false;
453
- }
454
- exports.isMac = isMac;
455
- function isGithubAction() {
456
- return !!process.env.CI;
457
- }
458
- exports.isGithubAction = isGithubAction;
459
451
  function getCwd() {
460
452
  const { testFile } = (0, getCurrentTest_1.getCurrentTest)();
461
453
  const cwd = (0, path_1.dirname)(testFile);
@@ -9,3 +9,4 @@ export * from './cliConfig';
9
9
  export * from './fsWindowsBugWorkaround';
10
10
  export * from './isObject';
11
11
  export * from './isCallable';
12
+ export * from './platform';
@@ -25,3 +25,4 @@ __exportStar(require("./cliConfig"), exports);
25
25
  __exportStar(require("./fsWindowsBugWorkaround"), exports);
26
26
  __exportStar(require("./isObject"), exports);
27
27
  __exportStar(require("./isCallable"), exports);
28
+ __exportStar(require("./platform"), exports);
@@ -0,0 +1,8 @@
1
+ export { isGithubAction };
2
+ export { isLinux };
3
+ export { isWindows };
4
+ export { isMac };
5
+ declare function isWindows(): boolean;
6
+ declare function isLinux(): boolean;
7
+ declare function isMac(): boolean;
8
+ declare function isGithubAction(): boolean;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isMac = exports.isWindows = exports.isLinux = exports.isGithubAction = void 0;
4
+ const assert_1 = require("./assert");
5
+ function isWindows() {
6
+ return process.platform === 'win32';
7
+ }
8
+ exports.isWindows = isWindows;
9
+ function isLinux() {
10
+ return process.platform === 'linux';
11
+ }
12
+ exports.isLinux = isLinux;
13
+ function isMac() {
14
+ if (process.platform === 'darwin') {
15
+ return true;
16
+ }
17
+ (0, assert_1.assert)(isLinux() || isWindows());
18
+ return false;
19
+ }
20
+ exports.isMac = isMac;
21
+ function isGithubAction() {
22
+ return !!process.env.CI;
23
+ }
24
+ exports.isGithubAction = isGithubAction;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brillout/test-e2e",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "bin": "./bin.js",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {