@brillout/test-e2e 0.5.8 → 0.5.10

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,4 +1,4 @@
1
- export { expectError };
1
+ export { expectLog };
2
2
  export declare const Logs: {
3
3
  add: typeof add;
4
4
  flushLogs: typeof flushLogs;
@@ -25,4 +25,4 @@ declare function add({ logSource, logText, loggedAfterExit, }: {
25
25
  logText: string;
26
26
  loggedAfterExit?: boolean;
27
27
  }): void;
28
- declare function expectError(logFilter: (browserLog: LogEntry) => boolean): void;
28
+ declare function expectLog(logText: string, logFilter?: (logEntry: LogEntry) => boolean): void;
package/dist/Logs.js CHANGED
@@ -3,7 +3,7 @@ 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.Logs = exports.expectError = void 0;
6
+ exports.Logs = exports.expectLog = void 0;
7
7
  exports.Logs = {
8
8
  add,
9
9
  flushLogs,
@@ -17,6 +17,7 @@ const picocolors_1 = __importDefault(require("picocolors"));
17
17
  const getCurrentTest_1 = require("./getCurrentTest");
18
18
  const logSection_1 = require("./logSection");
19
19
  const isTolerateError_1 = require("./Logs/isTolerateError");
20
+ const strip_ansi_1 = __importDefault(require("strip-ansi"));
20
21
  let logEntries = [];
21
22
  function hasFailLogs(failOnWarning) {
22
23
  const failLogs = getErrorLogs(failOnWarning);
@@ -74,18 +75,25 @@ function add({ logSource, logText, loggedAfterExit = false, }) {
74
75
  printLog(logEntry);
75
76
  }
76
77
  }
77
- function expectError(logFilter) {
78
- const logFounds = logEntries.filter((logEntry) => {
79
- if (logFilter(logEntry)) {
78
+ function expectLog(logText, logFilter) {
79
+ const logsFound = logEntries.filter((logEntry) => {
80
+ if ((0, strip_ansi_1.default)(logEntry.logText).includes(logText)) {
80
81
  logEntry.isNotFailure = true;
81
82
  return true;
82
83
  }
83
84
  return false;
84
85
  });
85
- //expect(logFounds.length).not.toBe(0)
86
- (0, utils_1.assert)(logFounds.length > 0);
86
+ const logsFoundWithFilter = logsFound.filter((logEntry) => logFilter?.(logEntry));
87
+ if (logsFoundWithFilter.length === 0) {
88
+ if (logsFound.length === 0) {
89
+ throw new Error(`The following log was expected but wasn't logged: "${logText}"`);
90
+ }
91
+ else {
92
+ throw new Error(`The following log was logged as expected, but it didn't match the logFilter() you provided`);
93
+ }
94
+ }
87
95
  }
88
- exports.expectError = expectError;
96
+ exports.expectLog = expectLog;
89
97
  function getTimestamp() {
90
98
  const now = new Date();
91
99
  const time = now.toTimeString().split(' ')[0];
@@ -0,0 +1,5 @@
1
+ export declare const TIMEOUT_NPM_SCRIPT: number;
2
+ export declare const TIMEOUT_TEST_FUNCTION: number;
3
+ export declare const TIMEOUT_PROCESS_TERMINATION: number;
4
+ export declare const TIMEOUT_AUTORETRY: number;
5
+ export declare const TIMEOUT_PLAYWRIGHT: number;
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TIMEOUT_PLAYWRIGHT = exports.TIMEOUT_AUTORETRY = exports.TIMEOUT_PROCESS_TERMINATION = exports.TIMEOUT_TEST_FUNCTION = exports.TIMEOUT_NPM_SCRIPT = void 0;
4
+ const platform_1 = require("./utils/platform");
5
+ exports.TIMEOUT_NPM_SCRIPT = 2 * 60 * 1000 * (!(0, platform_1.isCI)() ? 1 : (0, platform_1.isWindows)() ? 2 : 1);
6
+ exports.TIMEOUT_TEST_FUNCTION = 60 * 1000 * (!(0, platform_1.isCI)() ? 1 : (0, platform_1.isWindows)() ? 5 : 3);
7
+ exports.TIMEOUT_PROCESS_TERMINATION = 10 * 1000 * (!(0, platform_1.isCI)() ? 1 : (0, platform_1.isWindows)() ? 3 : !(0, platform_1.isLinux)() ? 3 : 1);
8
+ exports.TIMEOUT_AUTORETRY = exports.TIMEOUT_TEST_FUNCTION / 2;
9
+ exports.TIMEOUT_PLAYWRIGHT = exports.TIMEOUT_TEST_FUNCTION / 2;
@@ -0,0 +1,4 @@
1
+ export { autoRetry };
2
+ declare function autoRetry(test: () => void | Promise<void>, { timeout }?: {
3
+ timeout?: number;
4
+ }): Promise<void>;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.autoRetry = void 0;
4
+ const TIMEOUTS_1 = require("./TIMEOUTS");
5
+ const utils_1 = require("./utils");
6
+ async function autoRetry(test, { timeout = TIMEOUTS_1.TIMEOUT_AUTORETRY } = {}) {
7
+ const period = 100;
8
+ const numberOfTries = timeout / period;
9
+ let i = 0;
10
+ while (true) {
11
+ try {
12
+ await test();
13
+ return;
14
+ }
15
+ catch (err) {
16
+ i = i + 1;
17
+ if (i > numberOfTries) {
18
+ throw err;
19
+ }
20
+ }
21
+ await (0, utils_1.sleep)(period);
22
+ }
23
+ }
24
+ exports.autoRetry = autoRetry;
package/dist/buildTs.js CHANGED
@@ -17,7 +17,7 @@ async function buildTs(entry, outfile) {
17
17
  outfile,
18
18
  logLevel: 'warning',
19
19
  format: 'esm',
20
- target: 'es2020',
20
+ target: 'es2022',
21
21
  bundle: true,
22
22
  packages: 'external',
23
23
  minify: false,
package/dist/cli.js CHANGED
@@ -30,6 +30,7 @@ function initUserExitHandler() {
30
30
  Logs_1.Logs.flushLogs();
31
31
  });
32
32
  }
33
+ // Much simpler alternative: https://github.com/brillout/vite-plugin-ssr/blob/77b1b0e8b6c1ed4efe3e3039f7c0b23a00651663/vite-plugin-ssr/node/plugin/plugins/importUserCode/v1-design/transpileAndLoadFile.ts#L200-L208
33
34
  function initSourceMap() {
34
35
  source_map_support_1.default.install({
35
36
  retrieveSourceMap: function (source) {
@@ -0,0 +1,5 @@
1
+ export { fetch };
2
+ export { fetchHtml };
3
+ import fetch_ from 'node-fetch';
4
+ declare function fetchHtml(pathname: string): Promise<string>;
5
+ declare function fetch(...args: Parameters<typeof fetch_>): Promise<import("node-fetch").Response>;
package/dist/fetch.js ADDED
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.fetchHtml = exports.fetch = void 0;
7
+ const getCurrentTest_1 = require("./getCurrentTest");
8
+ const node_fetch_1 = __importDefault(require("node-fetch"));
9
+ const Logs_1 = require("./Logs");
10
+ async function fetchHtml(pathname) {
11
+ const response = await fetch((0, getCurrentTest_1.getServerUrl)() + pathname);
12
+ const html = await response.text();
13
+ return html;
14
+ }
15
+ exports.fetchHtml = fetchHtml;
16
+ async function fetch(...args) {
17
+ try {
18
+ return await (0, node_fetch_1.default)(...args);
19
+ }
20
+ catch (err) {
21
+ Logs_1.Logs.add({
22
+ logSource: 'Connection Error',
23
+ logText: `Couldn't connect to \`${args[0]}\`. Args: \`${JSON.stringify(args.slice(1))}\`. Err: \`${
24
+ // @ts-ignore
25
+ err.message}\``,
26
+ });
27
+ throw new Error("Couldn't connect to server. See `Connection Error` log for more details.");
28
+ }
29
+ }
30
+ exports.fetch = fetch;
@@ -1,6 +1,10 @@
1
1
  export { getCurrentTest };
2
2
  export { getCurrentTestOptional };
3
3
  export { setCurrentTest };
4
+ export { getRunInfo };
5
+ export { setRunInfo };
6
+ export { getCwd };
7
+ export { getServerUrl };
4
8
  export type { TestInfo };
5
9
  import type { Page } from 'playwright-chromium';
6
10
  declare type TestInfo = {
@@ -10,17 +14,18 @@ declare type TestInfo = {
10
14
  testDesc: string;
11
15
  testFn: Function;
12
16
  }[];
17
+ testOptions?: {
18
+ doNotFailOnWarning: boolean;
19
+ testFunctionTimeout: number;
20
+ isFlaky: boolean;
21
+ };
13
22
  runInfo?: {
14
23
  cmd: string;
15
- cwd: string;
16
- testFunctionTimeout: number;
17
- additionalTimeout: number;
18
- serverIsReadyMessage?: string | ((log: string) => boolean);
19
- serverIsReadyDelay: number;
20
- inspect: boolean;
21
- doNotFailOnWarning: boolean;
22
24
  serverUrl: string;
25
+ doNotFailOnWarning: boolean;
26
+ testFunctionTimeout: number;
23
27
  isFlaky: boolean;
28
+ isRunCommandThatTerminates: boolean;
24
29
  };
25
30
  hasStartedRunning?: boolean;
26
31
  skipped?: {
@@ -34,3 +39,21 @@ declare type TestInfo = {
34
39
  declare function getCurrentTest(): TestInfo;
35
40
  declare function getCurrentTestOptional(): null | TestInfo;
36
41
  declare function setCurrentTest(testFile: null | string): void;
42
+ declare function getRunInfo(): {
43
+ cmd: string;
44
+ serverUrl: string;
45
+ doNotFailOnWarning: boolean;
46
+ testFunctionTimeout: number;
47
+ isFlaky: boolean;
48
+ isRunCommandThatTerminates: boolean;
49
+ };
50
+ declare function setRunInfo({ cmd, serverUrl, additionalTimeout, doNotFailOnWarning, isFlaky, isRunCommandThatTerminates, }: {
51
+ cmd: string;
52
+ serverUrl?: string;
53
+ additionalTimeout?: number;
54
+ doNotFailOnWarning?: boolean;
55
+ isFlaky?: boolean;
56
+ isRunCommandThatTerminates?: boolean;
57
+ }): void;
58
+ declare function getCwd(): string;
59
+ declare function getServerUrl(): string;
@@ -3,9 +3,10 @@ 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.setCurrentTest = exports.getCurrentTestOptional = exports.getCurrentTest = void 0;
6
+ exports.getServerUrl = exports.getCwd = exports.setRunInfo = exports.getRunInfo = exports.setCurrentTest = exports.getCurrentTestOptional = exports.getCurrentTest = void 0;
7
7
  const utils_1 = require("./utils");
8
8
  const path_1 = __importDefault(require("path"));
9
+ const TIMEOUTS_1 = require("./TIMEOUTS");
9
10
  let testInfo = null;
10
11
  function getCurrentTest() {
11
12
  (0, utils_1.assert)(testInfo);
@@ -42,3 +43,35 @@ function removeRootDir(filePath) {
42
43
  (0, utils_1.assert)(filePath.startsWith(rootDir));
43
44
  return filePath.slice(rootDir.length);
44
45
  }
46
+ function getRunInfo() {
47
+ const testInfo = getCurrentTest();
48
+ (0, utils_1.assert)(testInfo.runInfo);
49
+ return testInfo.runInfo;
50
+ }
51
+ exports.getRunInfo = getRunInfo;
52
+ const serverUrlDefault = 'http://localhost:3000';
53
+ function setRunInfo({ cmd, serverUrl = serverUrlDefault, additionalTimeout = 0, doNotFailOnWarning = false, isFlaky = false, isRunCommandThatTerminates = false, }) {
54
+ const testInfo = getCurrentTest();
55
+ const testFunctionTimeout = TIMEOUTS_1.TIMEOUT_TEST_FUNCTION + additionalTimeout;
56
+ testInfo.runInfo = {
57
+ cmd,
58
+ serverUrl,
59
+ testFunctionTimeout,
60
+ doNotFailOnWarning,
61
+ isFlaky,
62
+ isRunCommandThatTerminates,
63
+ };
64
+ }
65
+ exports.setRunInfo = setRunInfo;
66
+ function getCwd() {
67
+ const { testFile } = getCurrentTest();
68
+ const cwd = path_1.default.dirname(testFile);
69
+ return cwd;
70
+ }
71
+ exports.getCwd = getCwd;
72
+ function getServerUrl() {
73
+ const testInfo = getCurrentTest();
74
+ const serverUrl = testInfo.runInfo?.serverUrl;
75
+ return serverUrl;
76
+ }
77
+ exports.getServerUrl = getServerUrl;
package/dist/index.d.ts CHANGED
@@ -1,6 +1,14 @@
1
- export * from './setup';
2
1
  export { expect } from './chai/expect';
3
2
  export { test } from './test';
4
3
  export { page } from './page';
5
4
  export { editFile, editFileRevert } from './editFile';
6
5
  export { testScreenshotFixture } from './testScreenshotFixture';
6
+ export { partRegex } from '@brillout/part-regex';
7
+ export { autoRetry } from './autoRetry';
8
+ export { fetch, fetchHtml } from './fetch';
9
+ export { expectLog } from './Logs';
10
+ export { run } from './run';
11
+ export { skip } from './skip';
12
+ export { isMinNodeVersion, isCI, isLinux, isWindows, isMac, sleep } from './utils';
13
+ export { getServerUrl } from './getCurrentTest';
14
+ export { runCommandThatTerminates } from './runCommandThatTerminates';
package/dist/index.js CHANGED
@@ -1,21 +1,6 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
2
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.testScreenshotFixture = exports.editFileRevert = exports.editFile = exports.page = exports.test = exports.expect = void 0;
18
- __exportStar(require("./setup"), exports);
3
+ exports.runCommandThatTerminates = exports.getServerUrl = exports.sleep = exports.isMac = exports.isWindows = exports.isLinux = exports.isCI = exports.isMinNodeVersion = exports.skip = exports.run = exports.expectLog = exports.fetchHtml = exports.fetch = exports.autoRetry = exports.partRegex = exports.testScreenshotFixture = exports.editFileRevert = exports.editFile = exports.page = exports.test = exports.expect = void 0;
19
4
  var expect_1 = require("./chai/expect");
20
5
  Object.defineProperty(exports, "expect", { enumerable: true, get: function () { return expect_1.expect; } });
21
6
  var test_1 = require("./test");
@@ -27,3 +12,27 @@ Object.defineProperty(exports, "editFile", { enumerable: true, get: function ()
27
12
  Object.defineProperty(exports, "editFileRevert", { enumerable: true, get: function () { return editFile_1.editFileRevert; } });
28
13
  var testScreenshotFixture_1 = require("./testScreenshotFixture");
29
14
  Object.defineProperty(exports, "testScreenshotFixture", { enumerable: true, get: function () { return testScreenshotFixture_1.testScreenshotFixture; } });
15
+ var part_regex_1 = require("@brillout/part-regex");
16
+ Object.defineProperty(exports, "partRegex", { enumerable: true, get: function () { return part_regex_1.partRegex; } });
17
+ var autoRetry_1 = require("./autoRetry");
18
+ Object.defineProperty(exports, "autoRetry", { enumerable: true, get: function () { return autoRetry_1.autoRetry; } });
19
+ var fetch_1 = require("./fetch");
20
+ Object.defineProperty(exports, "fetch", { enumerable: true, get: function () { return fetch_1.fetch; } });
21
+ Object.defineProperty(exports, "fetchHtml", { enumerable: true, get: function () { return fetch_1.fetchHtml; } });
22
+ var Logs_1 = require("./Logs");
23
+ Object.defineProperty(exports, "expectLog", { enumerable: true, get: function () { return Logs_1.expectLog; } });
24
+ var run_1 = require("./run");
25
+ Object.defineProperty(exports, "run", { enumerable: true, get: function () { return run_1.run; } });
26
+ var skip_1 = require("./skip");
27
+ Object.defineProperty(exports, "skip", { enumerable: true, get: function () { return skip_1.skip; } });
28
+ var utils_1 = require("./utils");
29
+ Object.defineProperty(exports, "isMinNodeVersion", { enumerable: true, get: function () { return utils_1.isMinNodeVersion; } });
30
+ Object.defineProperty(exports, "isCI", { enumerable: true, get: function () { return utils_1.isCI; } });
31
+ Object.defineProperty(exports, "isLinux", { enumerable: true, get: function () { return utils_1.isLinux; } });
32
+ Object.defineProperty(exports, "isWindows", { enumerable: true, get: function () { return utils_1.isWindows; } });
33
+ Object.defineProperty(exports, "isMac", { enumerable: true, get: function () { return utils_1.isMac; } });
34
+ Object.defineProperty(exports, "sleep", { enumerable: true, get: function () { return utils_1.sleep; } });
35
+ var getCurrentTest_1 = require("./getCurrentTest");
36
+ Object.defineProperty(exports, "getServerUrl", { enumerable: true, get: function () { return getCurrentTest_1.getServerUrl; } });
37
+ var runCommandThatTerminates_1 = require("./runCommandThatTerminates");
38
+ Object.defineProperty(exports, "runCommandThatTerminates", { enumerable: true, get: function () { return runCommandThatTerminates_1.runCommandThatTerminates; } });
@@ -51,8 +51,11 @@ function getStatusTags() {
51
51
  return { PASS, FAIL, WARN, BOOT };
52
52
  }
53
53
  function logBoot() {
54
+ if (!utils_1.isTTY)
55
+ return;
54
56
  const { testFile } = (0, getCurrentTest_1.getCurrentTest)();
55
57
  const { BOOT } = getStatusTags();
58
+ console.log();
56
59
  console.log(`${BOOT} ${testFile}`);
57
60
  }
58
61
  exports.logBoot = logBoot;
package/dist/run.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ export { run };
2
+ declare function run(cmd: string, { additionalTimeout, serverIsReadyMessage, serverIsReadyDelay, inspect, cwd, doNotFailOnWarning, serverUrl, isFlaky, }?: {
3
+ additionalTimeout?: number;
4
+ serverIsReadyMessage?: string | ((log: string) => boolean);
5
+ serverIsReadyDelay?: number;
6
+ inspect?: boolean;
7
+ /** deprecated */
8
+ cwd?: string;
9
+ doNotFailOnWarning?: boolean;
10
+ serverUrl?: string;
11
+ isFlaky?: boolean;
12
+ }): void;
package/dist/run.js ADDED
@@ -0,0 +1,188 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.run = void 0;
4
+ const utils_1 = require("./utils");
5
+ const utils_2 = require("./utils");
6
+ const Logs_1 = require("./Logs");
7
+ const editFile_1 = require("./editFile");
8
+ const getCurrentTest_1 = require("./getCurrentTest");
9
+ const page_1 = require("./page");
10
+ const TIMEOUTS_1 = require("./TIMEOUTS");
11
+ function run(cmd, {
12
+ //baseUrl = '',
13
+ additionalTimeout = 0, serverIsReadyMessage, serverIsReadyDelay = 1000, inspect = utils_1.cliConfig.inspect, cwd, doNotFailOnWarning, serverUrl, isFlaky, } = {}) {
14
+ (0, utils_2.assert)(cwd === undefined);
15
+ additionalTimeout += serverIsReadyDelay;
16
+ (0, getCurrentTest_1.setRunInfo)({
17
+ cmd,
18
+ serverUrl,
19
+ additionalTimeout,
20
+ doNotFailOnWarning,
21
+ isFlaky,
22
+ });
23
+ if (inspect) {
24
+ Logs_1.Logs.logEagerly = true;
25
+ }
26
+ const testInfo = (0, getCurrentTest_1.getCurrentTest)();
27
+ let runProcess = null;
28
+ testInfo.startServer = async () => {
29
+ runProcess = await startProcess({
30
+ cmd,
31
+ additionalTimeout,
32
+ serverIsReadyMessage,
33
+ serverIsReadyDelay,
34
+ });
35
+ page_1.page.on('console', onConsole);
36
+ page_1.page.on('pageerror', onPageError);
37
+ // This setting will change the default maximum time for all the methods accepting timeout option.
38
+ // https://playwright.dev/docs/api/class-page#page-set-default-timeout
39
+ page_1.page.setDefaultTimeout(TIMEOUTS_1.TIMEOUT_PLAYWRIGHT + additionalTimeout);
40
+ /*
41
+ await bailOnTimeout(
42
+ async () => {
43
+ await page.goto(getServerUrl() + baseUrl)
44
+ },
45
+ { timeout: TIMEOUT_PAGE_LOAD + additionalTimeout },
46
+ )
47
+ */
48
+ };
49
+ testInfo.afterEach = (hasFailed) => {
50
+ if (!hasFailed) {
51
+ (0, editFile_1.editFileAssertReverted)();
52
+ }
53
+ else {
54
+ (0, editFile_1.editFileRevert)();
55
+ }
56
+ };
57
+ testInfo.terminateServer = async () => {
58
+ Logs_1.Logs.add({
59
+ logSource: 'run()',
60
+ logText: 'Terminate server.',
61
+ });
62
+ page_1.page.off('console', onConsole);
63
+ page_1.page.off('pageerror', onPageError);
64
+ // runProcess is undefined if startProcess() failed
65
+ if (runProcess) {
66
+ await runProcess.terminate();
67
+ }
68
+ };
69
+ return;
70
+ // Also called when the page throws an error or a warning
71
+ function onConsole(msg) {
72
+ const type = msg.type();
73
+ Logs_1.Logs.add({
74
+ logSource: (() => {
75
+ if (type === 'error') {
76
+ return 'Browser Error';
77
+ }
78
+ if (type === 'warning') {
79
+ return 'Browser Warning';
80
+ }
81
+ return 'Browser Log';
82
+ })(),
83
+ logText: JSON.stringify({
84
+ type,
85
+ text: msg.text(),
86
+ location: msg.location(),
87
+ args: msg.args(),
88
+ }, null, 2),
89
+ });
90
+ }
91
+ // For uncaught exceptions
92
+ function onPageError(err) {
93
+ Logs_1.Logs.add({
94
+ logSource: 'Browser Error',
95
+ logText: JSON.stringify({
96
+ text: err.message,
97
+ location: err.stack,
98
+ }, null, 2),
99
+ });
100
+ }
101
+ }
102
+ exports.run = run;
103
+ async function startProcess({ serverIsReadyMessage, serverIsReadyDelay, additionalTimeout, cmd, }) {
104
+ const cwd = (0, getCurrentTest_1.getCwd)();
105
+ if (!serverIsReadyMessage) {
106
+ serverIsReadyMessage = (log) => {
107
+ const serverIsReady =
108
+ // Express.js server
109
+ log.includes('Server running at') ||
110
+ // npm package `serve`
111
+ log.includes('Accepting connections at') ||
112
+ // Vite
113
+ (log.includes('Local:') && log.includes('http://localhost:3000/'));
114
+ return serverIsReady;
115
+ };
116
+ }
117
+ Logs_1.Logs.add({
118
+ logSource: 'run()',
119
+ logText: `Spawn command \`${cmd}\``,
120
+ });
121
+ const done = (0, utils_1.logProgress)(`[run] ${cmd}`);
122
+ const { terminate, isReadyPromise } = (0, utils_1.runCommandLongRunning)({
123
+ cmd,
124
+ cwd,
125
+ isReadyLog: serverIsReadyMessage,
126
+ isReadyTimeout: TIMEOUTS_1.TIMEOUT_NPM_SCRIPT + additionalTimeout,
127
+ killPort: process.env.CI || !(0, utils_1.isLinux)() ? false : getServerPort(),
128
+ onStderr(data, { loggedAfterExit }) {
129
+ Logs_1.Logs.add({
130
+ logSource: 'stderr',
131
+ logText: data,
132
+ loggedAfterExit,
133
+ });
134
+ },
135
+ onStdout(data, { loggedAfterExit }) {
136
+ Logs_1.Logs.add({
137
+ logSource: 'stdout',
138
+ logText: data,
139
+ loggedAfterExit,
140
+ });
141
+ },
142
+ onExit(errMsg) {
143
+ if (!errMsg) {
144
+ Logs_1.Logs.add({
145
+ logSource: 'run()',
146
+ logText: `Process termination (expected)`,
147
+ });
148
+ }
149
+ else {
150
+ Logs_1.Logs.add({
151
+ logSource: 'run() failure',
152
+ logText: errMsg,
153
+ });
154
+ }
155
+ },
156
+ onTerminationError(errMsg) {
157
+ Logs_1.Logs.add({
158
+ logSource: 'run() failure',
159
+ logText: errMsg,
160
+ });
161
+ },
162
+ terminationTimeout: TIMEOUTS_1.TIMEOUT_PROCESS_TERMINATION,
163
+ });
164
+ let err;
165
+ try {
166
+ await isReadyPromise;
167
+ }
168
+ catch (err_) {
169
+ err = err_;
170
+ (0, utils_2.assert)(err);
171
+ }
172
+ done(!!err);
173
+ if (err)
174
+ throw err;
175
+ Logs_1.Logs.add({
176
+ logSource: 'run()',
177
+ logText: 'Server is ready.',
178
+ });
179
+ await (0, utils_1.sleep)(serverIsReadyDelay);
180
+ return { terminate };
181
+ }
182
+ function getServerPort() {
183
+ const serverUrl = (0, getCurrentTest_1.getServerUrl)();
184
+ const portStr = serverUrl.split(':').slice(-1)[0].split('/')[0];
185
+ (0, utils_2.assert)(/\d+/.test(portStr), { serverUrl });
186
+ const port = parseInt(portStr, 10);
187
+ return port;
188
+ }
package/dist/runAll.js CHANGED
@@ -59,25 +59,48 @@ async function buildAndTest(testFile, browser, isSecondAttempt) {
59
59
  (0, utils_1.assert)(testFileJs.endsWith('.mjs'));
60
60
  const cleanBuild = await (0, buildTs_1.buildTs)(testFile, testFileJs);
61
61
  (0, getCurrentTest_2.setCurrentTest)(testFile);
62
+ (0, logTestStatus_1.logBoot)();
63
+ let execErr;
62
64
  try {
63
65
  await import((0, utils_2.fsWindowsBugWorkaround)(testFileJs) + `?cacheBuster=${Date.now()}`);
64
66
  }
67
+ catch (err) {
68
+ (0, utils_1.assert)(err);
69
+ execErr = err;
70
+ }
65
71
  finally {
66
72
  cleanBuild();
67
73
  }
68
- const success = await runServerAndTests(browser, isSecondAttempt);
69
- (0, getCurrentTest_2.setCurrentTest)(null);
70
- return success;
71
- }
72
- async function runServerAndTests(browser, isSecondAttempt) {
74
+ if (execErr) {
75
+ (0, logTestStatus_1.logFail)(`an error was thrown while executing the file ${testFile}`, true);
76
+ (0, logError_1.logError)(execErr);
77
+ return false;
78
+ }
79
+ // When user calls skip()
73
80
  const testInfo = (0, getCurrentTest_1.getCurrentTest)();
74
- // Set when user calls `skip()`
75
81
  if (testInfo.skipped) {
76
82
  assertSkipUsage(testInfo);
77
83
  (0, logTestStatus_1.logWarn)(testInfo.skipped.reason);
78
84
  return true;
79
85
  }
80
- // Set when user calls `run()`
86
+ else {
87
+ // Set when user calls run() or runCommandThatTerminates()
88
+ (0, utils_1.assert)(testInfo.runInfo);
89
+ }
90
+ // When user calls run runCommandThatTerminates()
91
+ if (testInfo.runInfo.isRunCommandThatTerminates) {
92
+ (0, utils_1.assertUsage)(!testInfo.tests, "Can't call test() when calling runCommandThatTerminates()");
93
+ (0, utils_1.assertUsage)(!testInfo.startServer, "Can't call run() when calling runCommandThatTerminates()");
94
+ (0, logTestStatus_1.logPass)();
95
+ return true;
96
+ }
97
+ const success = await runServerAndTests(browser, isSecondAttempt);
98
+ (0, getCurrentTest_2.setCurrentTest)(null);
99
+ return success;
100
+ }
101
+ async function runServerAndTests(browser, isSecondAttempt) {
102
+ const testInfo = (0, getCurrentTest_1.getCurrentTest)();
103
+ // Set when user calls run()
81
104
  (0, utils_1.assert)(testInfo.runInfo);
82
105
  (0, utils_1.assert)(testInfo.startServer);
83
106
  (0, utils_1.assert)(testInfo.terminateServer);
@@ -104,7 +127,7 @@ async function runServerAndTests(browser, isSecondAttempt) {
104
127
  if (success) {
105
128
  const failOnWarning = true;
106
129
  if (Logs_1.Logs.hasFailLogs(failOnWarning) &&
107
- // See comments about taskkill in src/setup.ts
130
+ // See comments about taskkill in src/utils/runCommandLongRunning.ts
108
131
  !(0, utils_1.isWindows)()) {
109
132
  logFailure(null, `${getErrorType(failOnWarning)} occurred during server termination`, isFinalAttempt);
110
133
  success = false;
@@ -123,9 +146,12 @@ async function runTests(testInfo, isFinalAttempt) {
123
146
  // Set when user calls `run()`
124
147
  (0, utils_1.assert)(testInfo.runInfo);
125
148
  (0, utils_1.assert)(testInfo.afterEach);
126
- // Set when user calls `test()`
127
- (0, utils_1.assert)(testInfo.tests);
128
- for (const { testDesc, testFn } of testInfo.tests) {
149
+ const tests =
150
+ // Set when user calls test()
151
+ testInfo.tests ??
152
+ // When user hasn't any test() call
153
+ [];
154
+ for (const { testDesc, testFn } of tests) {
129
155
  Logs_1.Logs.add({
130
156
  logSource: 'test()',
131
157
  logText: testDesc,
@@ -0,0 +1,4 @@
1
+ export { runCommandThatTerminates };
2
+ declare function runCommandThatTerminates(cmd: string, { timeout }?: {
3
+ timeout?: number;
4
+ }): Promise<void>;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runCommandThatTerminates = void 0;
4
+ const getCurrentTest_1 = require("./getCurrentTest");
5
+ const utils_1 = require("./utils");
6
+ async function runCommandThatTerminates(cmd, { timeout = 2 * 60 * 1000 } = {}) {
7
+ (0, getCurrentTest_1.setRunInfo)({ cmd, isRunCommandThatTerminates: true });
8
+ const cwd = (0, getCurrentTest_1.getCwd)();
9
+ await (0, utils_1.runCommand)(cmd, { timeout, cwd });
10
+ }
11
+ exports.runCommandThatTerminates = runCommandThatTerminates;
package/dist/skip.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export { skip };
2
+ declare function skip(reason: string): void;