@brillout/test-e2e 0.5.8 → 0.5.9
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 +1 -1
- package/dist/Logs.js +4 -4
- package/dist/TIMEOUTS.d.ts +5 -0
- package/dist/TIMEOUTS.js +9 -0
- package/dist/autoRetry.d.ts +4 -0
- package/dist/autoRetry.js +24 -0
- package/dist/buildTs.js +1 -1
- package/dist/cli.js +1 -0
- package/dist/getCurrentTest.d.ts +28 -7
- package/dist/getCurrentTest.js +28 -1
- package/dist/logTestStatus.js +3 -0
- package/dist/runAll.js +31 -5
- package/dist/runCommandThatTerminates.d.ts +4 -0
- package/dist/runCommandThatTerminates.js +11 -0
- package/dist/setup.d.ts +5 -6
- package/dist/setup.js +97 -332
- package/dist/testScreenshotFixture.js +1 -1
- package/dist/utils/findFiles.js +3 -3
- package/dist/utils/genPromise.d.ts +5 -0
- package/dist/utils/genPromise.js +13 -0
- package/dist/utils/humanizeTime.d.ts +1 -1
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/runCommand.d.ts +4 -5
- package/dist/utils/runCommand.js +12 -32
- package/dist/utils/runCommandLongRunning.d.ts +20 -0
- package/dist/utils/runCommandLongRunning.js +232 -0
- package/dist/utils/runCommandShortLived.d.ts +6 -0
- package/dist/utils/runCommandShortLived.js +39 -0
- package/package.json +1 -1
package/dist/setup.js
CHANGED
|
@@ -3,9 +3,15 @@ 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.getServerUrl = exports.sleep = exports.isMac = exports.isWindows = exports.isLinux = exports.isCI = exports.isMinNodeVersion = exports.skip = exports.run = exports.expectError = exports.fetch = exports.fetchHtml = exports.autoRetry = exports.partRegex = void 0;
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
exports.runCommandThatTerminates = exports.getServerUrl = exports.sleep = exports.isMac = exports.isWindows = exports.isLinux = exports.isCI = exports.isMinNodeVersion = exports.skip = exports.run = exports.expectError = exports.fetch = exports.fetchHtml = exports.autoRetry = exports.partRegex = void 0;
|
|
7
|
+
var part_regex_1 = require("@brillout/part-regex");
|
|
8
|
+
Object.defineProperty(exports, "partRegex", { enumerable: true, get: function () { return part_regex_1.partRegex; } });
|
|
9
|
+
var autoRetry_1 = require("./autoRetry");
|
|
10
|
+
Object.defineProperty(exports, "autoRetry", { enumerable: true, get: function () { return autoRetry_1.autoRetry; } });
|
|
11
|
+
var Logs_1 = require("./Logs");
|
|
12
|
+
Object.defineProperty(exports, "expectError", { enumerable: true, get: function () { return Logs_1.expectError; } });
|
|
13
|
+
var runCommandThatTerminates_1 = require("./runCommandThatTerminates");
|
|
14
|
+
Object.defineProperty(exports, "runCommandThatTerminates", { enumerable: true, get: function () { return runCommandThatTerminates_1.runCommandThatTerminates; } });
|
|
9
15
|
const utils_1 = require("./utils");
|
|
10
16
|
Object.defineProperty(exports, "sleep", { enumerable: true, get: function () { return utils_1.sleep; } });
|
|
11
17
|
Object.defineProperty(exports, "isWindows", { enumerable: true, get: function () { return utils_1.isWindows; } });
|
|
@@ -14,22 +20,11 @@ Object.defineProperty(exports, "isCI", { enumerable: true, get: function () { re
|
|
|
14
20
|
Object.defineProperty(exports, "isMac", { enumerable: true, get: function () { return utils_1.isMac; } });
|
|
15
21
|
const node_fetch_1 = __importDefault(require("node-fetch"));
|
|
16
22
|
const utils_2 = require("./utils");
|
|
17
|
-
const
|
|
18
|
-
const strip_ansi_1 = __importDefault(require("strip-ansi"));
|
|
23
|
+
const Logs_2 = require("./Logs");
|
|
19
24
|
const editFile_1 = require("./editFile");
|
|
20
25
|
const getCurrentTest_1 = require("./getCurrentTest");
|
|
21
26
|
const page_1 = require("./page");
|
|
22
|
-
const
|
|
23
|
-
var part_regex_1 = require("@brillout/part-regex");
|
|
24
|
-
Object.defineProperty(exports, "partRegex", { enumerable: true, get: function () { return part_regex_1.partRegex; } });
|
|
25
|
-
var Logs_2 = require("./Logs");
|
|
26
|
-
Object.defineProperty(exports, "expectError", { enumerable: true, get: function () { return Logs_2.expectError; } });
|
|
27
|
-
const serverUrlDefault = 'http://localhost:3000';
|
|
28
|
-
const TIMEOUT_NPM_SCRIPT = 2 * 60 * 1000 * (!(0, utils_1.isCI)() ? 1 : (0, utils_1.isWindows)() ? 2 : 1);
|
|
29
|
-
const TIMEOUT_TEST_FUNCTION = 60 * 1000 * (!(0, utils_1.isCI)() ? 1 : (0, utils_1.isWindows)() ? 5 : 3);
|
|
30
|
-
const TIMEOUT_PROCESS_TERMINATION = 10 * 1000 * (!(0, utils_1.isCI)() ? 1 : (0, utils_1.isWindows)() ? 3 : !(0, utils_1.isLinux)() ? 3 : 1);
|
|
31
|
-
const TIMEOUT_AUTORETRY = TIMEOUT_TEST_FUNCTION / 2;
|
|
32
|
-
const TIMEOUT_PLAYWRIGHT = TIMEOUT_TEST_FUNCTION / 2;
|
|
27
|
+
const TIMEOUTS_1 = require("./TIMEOUTS");
|
|
33
28
|
function skip(reason) {
|
|
34
29
|
const testInfo = (0, getCurrentTest_1.getCurrentTest)();
|
|
35
30
|
testInfo.skipped = { reason };
|
|
@@ -37,32 +32,33 @@ function skip(reason) {
|
|
|
37
32
|
exports.skip = skip;
|
|
38
33
|
function run(cmd, {
|
|
39
34
|
//baseUrl = '',
|
|
40
|
-
additionalTimeout = 0, serverIsReadyMessage, serverIsReadyDelay = 1000, inspect = utils_1.cliConfig.inspect, cwd, doNotFailOnWarning
|
|
35
|
+
additionalTimeout = 0, serverIsReadyMessage, serverIsReadyDelay = 1000, inspect = utils_1.cliConfig.inspect, cwd, doNotFailOnWarning, serverUrl, isFlaky, } = {}) {
|
|
36
|
+
(0, utils_2.assert)(cwd === undefined);
|
|
41
37
|
additionalTimeout += serverIsReadyDelay;
|
|
42
|
-
|
|
43
|
-
testInfo.runInfo = {
|
|
38
|
+
(0, getCurrentTest_1.setRunInfo)({
|
|
44
39
|
cmd,
|
|
45
|
-
|
|
40
|
+
serverUrl,
|
|
46
41
|
additionalTimeout,
|
|
47
|
-
testFunctionTimeout: TIMEOUT_TEST_FUNCTION + additionalTimeout,
|
|
48
|
-
serverIsReadyMessage,
|
|
49
|
-
serverIsReadyDelay,
|
|
50
|
-
inspect,
|
|
51
42
|
doNotFailOnWarning,
|
|
52
|
-
serverUrl,
|
|
53
43
|
isFlaky,
|
|
54
|
-
};
|
|
44
|
+
});
|
|
55
45
|
if (inspect) {
|
|
56
|
-
|
|
46
|
+
Logs_2.Logs.logEagerly = true;
|
|
57
47
|
}
|
|
48
|
+
const testInfo = (0, getCurrentTest_1.getCurrentTest)();
|
|
58
49
|
let runProcess = null;
|
|
59
50
|
testInfo.startServer = async () => {
|
|
60
|
-
runProcess = await
|
|
51
|
+
runProcess = await startProcess({
|
|
52
|
+
cmd,
|
|
53
|
+
additionalTimeout,
|
|
54
|
+
serverIsReadyMessage,
|
|
55
|
+
serverIsReadyDelay,
|
|
56
|
+
});
|
|
61
57
|
page_1.page.on('console', onConsole);
|
|
62
58
|
page_1.page.on('pageerror', onPageError);
|
|
63
59
|
// This setting will change the default maximum time for all the methods accepting timeout option.
|
|
64
60
|
// https://playwright.dev/docs/api/class-page#page-set-default-timeout
|
|
65
|
-
page_1.page.setDefaultTimeout(TIMEOUT_PLAYWRIGHT + additionalTimeout);
|
|
61
|
+
page_1.page.setDefaultTimeout(TIMEOUTS_1.TIMEOUT_PLAYWRIGHT + additionalTimeout);
|
|
66
62
|
/*
|
|
67
63
|
await bailOnTimeout(
|
|
68
64
|
async () => {
|
|
@@ -81,13 +77,13 @@ additionalTimeout = 0, serverIsReadyMessage, serverIsReadyDelay = 1000, inspect
|
|
|
81
77
|
}
|
|
82
78
|
};
|
|
83
79
|
testInfo.terminateServer = async () => {
|
|
84
|
-
|
|
80
|
+
Logs_2.Logs.add({
|
|
85
81
|
logSource: 'run()',
|
|
86
82
|
logText: 'Terminate server.',
|
|
87
83
|
});
|
|
88
84
|
page_1.page.off('console', onConsole);
|
|
89
85
|
page_1.page.off('pageerror', onPageError);
|
|
90
|
-
//
|
|
86
|
+
// runProcess is undefined if startProcess() failed
|
|
91
87
|
if (runProcess) {
|
|
92
88
|
await runProcess.terminate();
|
|
93
89
|
}
|
|
@@ -96,7 +92,7 @@ additionalTimeout = 0, serverIsReadyMessage, serverIsReadyDelay = 1000, inspect
|
|
|
96
92
|
// Also called when the page throws an error or a warning
|
|
97
93
|
function onConsole(msg) {
|
|
98
94
|
const type = msg.type();
|
|
99
|
-
|
|
95
|
+
Logs_2.Logs.add({
|
|
100
96
|
logSource: (() => {
|
|
101
97
|
if (type === 'error') {
|
|
102
98
|
return 'Browser Error';
|
|
@@ -116,7 +112,7 @@ additionalTimeout = 0, serverIsReadyMessage, serverIsReadyDelay = 1000, inspect
|
|
|
116
112
|
}
|
|
117
113
|
// For uncaught exceptions
|
|
118
114
|
function onPageError(err) {
|
|
119
|
-
|
|
115
|
+
Logs_2.Logs.add({
|
|
120
116
|
logSource: 'Browser Error',
|
|
121
117
|
logText: JSON.stringify({
|
|
122
118
|
text: err.message,
|
|
@@ -126,312 +122,85 @@ additionalTimeout = 0, serverIsReadyMessage, serverIsReadyDelay = 1000, inspect
|
|
|
126
122
|
}
|
|
127
123
|
}
|
|
128
124
|
exports.run = run;
|
|
129
|
-
function
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
if (utils_1.isTTY) {
|
|
137
|
-
console.log();
|
|
138
|
-
(0, logTestStatus_1.logBoot)();
|
|
139
|
-
}
|
|
140
|
-
const done = (0, utils_1.logProgress)(`[run] ${cmd}`);
|
|
141
|
-
let hasSuccessfullyStarted = false;
|
|
142
|
-
let resolveServerStart;
|
|
143
|
-
let rejectServerStart;
|
|
144
|
-
const promise = new Promise((_resolve, _reject) => {
|
|
145
|
-
resolveServerStart = () => {
|
|
146
|
-
(0, utils_2.assert)(!processHasExited());
|
|
147
|
-
(0, utils_2.assert)(getRunInfo().cmd === cmd);
|
|
148
|
-
Logs_1.Logs.add({
|
|
149
|
-
logSource: 'run()',
|
|
150
|
-
logText: 'Server is ready.',
|
|
151
|
-
});
|
|
152
|
-
hasSuccessfullyStarted = true;
|
|
153
|
-
clearTimeout(serverStartTimeout);
|
|
154
|
-
const runProcess = { terminate };
|
|
155
|
-
_resolve(runProcess);
|
|
156
|
-
};
|
|
157
|
-
rejectServerStart = async (err) => {
|
|
158
|
-
(0, utils_2.assert)(processHasExited());
|
|
159
|
-
(0, utils_2.assert)(getRunInfo().cmd === cmd);
|
|
160
|
-
done(true);
|
|
161
|
-
clearTimeout(serverStartTimeout);
|
|
162
|
-
_reject(err);
|
|
163
|
-
};
|
|
164
|
-
});
|
|
165
|
-
const timeoutTotal = TIMEOUT_NPM_SCRIPT + additionalTimeout;
|
|
166
|
-
let hasTimedout = false;
|
|
167
|
-
const serverStartTimeout = setTimeout(async () => {
|
|
168
|
-
hasTimedout = true;
|
|
169
|
-
let errMsg = '';
|
|
170
|
-
errMsg += `Server still didn't start after ${(0, utils_1.humanizeTime)(timeoutTotal)} of running the npm script \`${cmd}\`.`;
|
|
171
|
-
if (serverIsReadyMessage) {
|
|
172
|
-
errMsg += ` (The stdout of the npm script did not include: "${serverIsReadyMessage}".)`;
|
|
173
|
-
}
|
|
174
|
-
Logs_1.Logs.add({
|
|
175
|
-
logSource: 'run() failure',
|
|
176
|
-
logText: errMsg,
|
|
177
|
-
});
|
|
178
|
-
await terminate(true);
|
|
179
|
-
rejectServerStart(new Error(errMsg));
|
|
180
|
-
}, timeoutTotal);
|
|
181
|
-
// Kill any process that listens to the server port
|
|
182
|
-
if (!process.env.CI && (0, utils_1.isLinux)()) {
|
|
183
|
-
const port = getPort();
|
|
184
|
-
(0, utils_2.assert)(/\d+/.test(port));
|
|
185
|
-
await (0, utils_1.runCommand)(`fuser -k ${port}/tcp`, { swallowError: true, timeout: 10 * 1000 });
|
|
186
|
-
}
|
|
187
|
-
const { terminate, processHasExited } = execRunScript({
|
|
188
|
-
async onFailure(err) {
|
|
189
|
-
(0, utils_2.assert)(processHasExited());
|
|
190
|
-
rejectServerStart(err);
|
|
191
|
-
},
|
|
192
|
-
onExit() {
|
|
193
|
-
(0, utils_2.assert)(processHasExited());
|
|
194
|
-
const exitIsPossible = hasSuccessfullyStarted === true || hasTimedout;
|
|
195
|
-
return exitIsPossible;
|
|
196
|
-
},
|
|
197
|
-
async onStdout(data) {
|
|
198
|
-
const log = (0, strip_ansi_1.default)(data);
|
|
199
|
-
const isServerReady =
|
|
200
|
-
// Custom
|
|
201
|
-
(typeof serverIsReadyMessage === 'string' && log.includes(serverIsReadyMessage)) ||
|
|
202
|
-
((0, utils_1.isCallable)(serverIsReadyMessage) && serverIsReadyMessage(log)) ||
|
|
203
|
-
// Express.js server
|
|
204
|
-
log.includes('Server running at') ||
|
|
125
|
+
async function startProcess({ serverIsReadyMessage, serverIsReadyDelay, additionalTimeout, cmd, }) {
|
|
126
|
+
const cwd = (0, getCurrentTest_1.getCwd)();
|
|
127
|
+
if (!serverIsReadyMessage) {
|
|
128
|
+
serverIsReadyMessage = (log) => {
|
|
129
|
+
const serverIsReady =
|
|
130
|
+
// Express.js server
|
|
131
|
+
log.includes('Server running at') ||
|
|
205
132
|
// npm package `serve`
|
|
206
133
|
log.includes('Accepting connections at') ||
|
|
207
134
|
// Vite
|
|
208
135
|
(log.includes('Local:') && log.includes('http://localhost:3000/'));
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
await (0, utils_1.sleep)(serverIsReadyDelay);
|
|
212
|
-
resolveServerStart();
|
|
213
|
-
done();
|
|
214
|
-
}
|
|
215
|
-
},
|
|
216
|
-
});
|
|
217
|
-
return promise;
|
|
218
|
-
}
|
|
219
|
-
function stopProcess({ proc, cwd, cmd, force, }) {
|
|
220
|
-
const prefix = `[Run Stop][${cwd}][${cmd}]`;
|
|
221
|
-
let resolve;
|
|
222
|
-
let reject;
|
|
223
|
-
const promise = new Promise((_resolve, _reject) => {
|
|
224
|
-
resolve = _resolve;
|
|
225
|
-
reject = _reject;
|
|
226
|
-
});
|
|
227
|
-
const onProcessClose = (code) => {
|
|
228
|
-
if (code === 0 || code === null || (code === 1 && (0, utils_1.isWindows)())) {
|
|
229
|
-
resolve();
|
|
230
|
-
}
|
|
231
|
-
else {
|
|
232
|
-
reject(new Error(`${prefix} Terminated with non-0 error code ${code}`));
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
proc.on('close', onProcessClose);
|
|
236
|
-
proc.on('exit', onProcessClose);
|
|
237
|
-
if ((0, utils_1.isWindows)()) {
|
|
238
|
-
// - https://github.com/nodejs/node/issues/3617#issuecomment-377731194
|
|
239
|
-
// - https://stackoverflow.com/questions/23706055/why-can-i-not-kill-my-child-process-in-nodejs-on-windows/28163919#28163919
|
|
240
|
-
// - taskkill seems to be buggy in many ways:
|
|
241
|
-
// - taskkill seems to make the process exit with code `1`
|
|
242
|
-
// - Because process exits with code `1`, Node.js/npm complains:
|
|
243
|
-
// ```
|
|
244
|
-
// [15:36:10.626][\examples\react][npm run preview][stderr] npm
|
|
245
|
-
// [15:36:10.626][\examples\react][npm run preview][stderr]
|
|
246
|
-
// [15:36:10.626][\examples\react][npm run preview][stderr] ERR!
|
|
247
|
-
// [15:36:10.626][\examples\react][npm run preview][stderr]
|
|
248
|
-
// [15:36:10.626][\examples\react][npm run preview][stderr] code
|
|
249
|
-
// [15:36:10.626][\examples\react][npm run preview][stderr] ELIFECYCLE
|
|
250
|
-
// ```
|
|
251
|
-
// Because stderr isn't empty, runTests() believes that the termination failed.
|
|
252
|
-
// - taskkill sometimes throws:
|
|
253
|
-
// ```
|
|
254
|
-
// ERROR: The process with PID 6052 (child process of PID 3184) could not be terminated.
|
|
255
|
-
// Reason: There is no running instance of the task.
|
|
256
|
-
// ```
|
|
257
|
-
// ```
|
|
258
|
-
// ERROR: The process "6564" not found.
|
|
259
|
-
// ```
|
|
260
|
-
// There doesn't seem to be an option to suppress these errors: https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/taskkill#parameters
|
|
261
|
-
(0, child_process_1.spawn)('taskkill', ['/pid', String(proc.pid), '/f', '/t'], {
|
|
262
|
-
stdio: [
|
|
263
|
-
'ignore',
|
|
264
|
-
// 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', () => /* ... */)`.)
|
|
265
|
-
// ```
|
|
266
|
-
// SUCCESS: The process with PID 6932 (child process of PID 2744) has been terminated.
|
|
267
|
-
// ```
|
|
268
|
-
'ignore',
|
|
269
|
-
// Ignoring stderr doesn't solve the problem that taskkill makes the process exit with code 1
|
|
270
|
-
'inherit', // stderr
|
|
271
|
-
],
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
else {
|
|
275
|
-
(0, utils_2.assert)(proc.pid);
|
|
276
|
-
const processGroup = -1 * proc.pid;
|
|
277
|
-
const signal = force ? 'SIGKILL' : 'SIGTERM';
|
|
278
|
-
process.kill(processGroup, signal);
|
|
279
|
-
/*
|
|
280
|
-
try {
|
|
281
|
-
process.kill(-proc.pid, signal)
|
|
282
|
-
} catch (err: unknown) {
|
|
283
|
-
// ESRCH: No process or process group can be found corresponding to that specified by pid.
|
|
284
|
-
// => probably means that the process was killed already.
|
|
285
|
-
if (typeof err === 'object' && err !== null && 'code' in err && err['code'] === 'ESRCH') {
|
|
286
|
-
printLog('stdout', '=============== swallowError')
|
|
287
|
-
return
|
|
288
|
-
} else {
|
|
289
|
-
printLog('stdout', '=============== no swallowError')
|
|
290
|
-
throw err
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
*/
|
|
294
|
-
}
|
|
295
|
-
return promise;
|
|
296
|
-
}
|
|
297
|
-
function execRunScript({ onStdout, onFailure, onExit, }) {
|
|
298
|
-
const { cwd, cmd } = getRunInfo();
|
|
299
|
-
let [command, ...args] = cmd.split(' ');
|
|
300
|
-
let detached = true;
|
|
301
|
-
if ((0, utils_1.isWindows)()) {
|
|
302
|
-
detached = false;
|
|
303
|
-
if (command === 'npm' || command === 'pnpm') {
|
|
304
|
-
command = command + '.cmd';
|
|
305
|
-
}
|
|
136
|
+
return serverIsReady;
|
|
137
|
+
};
|
|
306
138
|
}
|
|
307
|
-
|
|
139
|
+
Logs_2.Logs.add({
|
|
308
140
|
logSource: 'run()',
|
|
309
141
|
logText: `Spawn command \`${cmd}\``,
|
|
310
142
|
});
|
|
311
|
-
const
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
await exitAndFail(new Error(`Command is \`${cmd}\` (${cwd}) is invoking \`stdin\`: ${data}.`));
|
|
324
|
-
});
|
|
325
|
-
proc.stdout.on('data', (chunk) => {
|
|
326
|
-
const data = String(chunk);
|
|
327
|
-
Logs_1.Logs.add({
|
|
328
|
-
logSource: 'stdout',
|
|
329
|
-
logText: data,
|
|
330
|
-
loggedAfterExit: procExited,
|
|
331
|
-
});
|
|
332
|
-
onStdout?.(data);
|
|
333
|
-
});
|
|
334
|
-
proc.stderr.on('data', async (chunk) => {
|
|
335
|
-
const data = String(chunk);
|
|
336
|
-
Logs_1.Logs.add({
|
|
337
|
-
logSource: 'stderr',
|
|
338
|
-
logText: data,
|
|
339
|
-
loggedAfterExit: procExited,
|
|
340
|
-
});
|
|
341
|
-
if (data.includes('EADDRINUSE')) {
|
|
342
|
-
await exitAndFail(new Error('Port conflict? Port already in use EADDRINUSE.'));
|
|
343
|
-
}
|
|
344
|
-
});
|
|
345
|
-
let exitPromiseResolve;
|
|
346
|
-
const exitPromise = new Promise((r) => (exitPromiseResolve = r));
|
|
347
|
-
proc.on('exit', (code) => {
|
|
348
|
-
procExited = true;
|
|
349
|
-
(0, utils_2.assert)(getRunInfo().cmd === cmd);
|
|
350
|
-
const exitIsPossible = onExit();
|
|
351
|
-
const isSuccessCode = [0, null].includes(code) || ((0, utils_1.isWindows)() && code === 1);
|
|
352
|
-
const isExpected = isSuccessCode && exitIsPossible;
|
|
353
|
-
if (!isExpected) {
|
|
354
|
-
const errMsg = `Unexpected premature process termination, exit code: ${code}`;
|
|
355
|
-
Logs_1.Logs.add({
|
|
356
|
-
logText: errMsg,
|
|
357
|
-
logSource: 'run() failure',
|
|
143
|
+
const done = (0, utils_1.logProgress)(`[run] ${cmd}`);
|
|
144
|
+
const { terminate, isReadyPromise } = (0, utils_1.runCommandLongRunning)({
|
|
145
|
+
cmd,
|
|
146
|
+
cwd,
|
|
147
|
+
isReadyLog: serverIsReadyMessage,
|
|
148
|
+
isReadyTimeout: TIMEOUTS_1.TIMEOUT_NPM_SCRIPT + additionalTimeout,
|
|
149
|
+
killPort: process.env.CI || !(0, utils_1.isLinux)() ? false : getServerPort(),
|
|
150
|
+
onStderr(data, { loggedAfterExit }) {
|
|
151
|
+
Logs_2.Logs.add({
|
|
152
|
+
logSource: 'stderr',
|
|
153
|
+
logText: data,
|
|
154
|
+
loggedAfterExit,
|
|
358
155
|
});
|
|
359
|
-
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
logText:
|
|
364
|
-
|
|
156
|
+
},
|
|
157
|
+
onStdout(data, { loggedAfterExit }) {
|
|
158
|
+
Logs_2.Logs.add({
|
|
159
|
+
logSource: 'stdout',
|
|
160
|
+
logText: data,
|
|
161
|
+
loggedAfterExit,
|
|
365
162
|
});
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
});
|
|
384
|
-
const timeout = setTimeout(() => {
|
|
385
|
-
const errMsg = 'Process termination timeout. Cmd: ' + cmd;
|
|
386
|
-
Logs_1.Logs.add({
|
|
163
|
+
},
|
|
164
|
+
onExit(errMsg) {
|
|
165
|
+
if (!errMsg) {
|
|
166
|
+
Logs_2.Logs.add({
|
|
167
|
+
logSource: 'run()',
|
|
168
|
+
logText: `Process termination (expected)`,
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
Logs_2.Logs.add({
|
|
173
|
+
logSource: 'run() failure',
|
|
174
|
+
logText: errMsg,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
onTerminationError(errMsg) {
|
|
179
|
+
Logs_2.Logs.add({
|
|
387
180
|
logSource: 'run() failure',
|
|
388
181
|
logText: errMsg,
|
|
389
182
|
});
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
try {
|
|
397
|
-
await stopProcess({
|
|
398
|
-
proc,
|
|
399
|
-
cwd,
|
|
400
|
-
cmd,
|
|
401
|
-
force,
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
catch (err) {
|
|
405
|
-
Logs_1.Logs.add({
|
|
406
|
-
logSource: 'run() failure',
|
|
407
|
-
logText: String(err),
|
|
408
|
-
});
|
|
409
|
-
}
|
|
410
|
-
clearTimeout(timeout);
|
|
411
|
-
await exitPromise;
|
|
412
|
-
resolve();
|
|
413
|
-
return promise;
|
|
183
|
+
},
|
|
184
|
+
terminationTimeout: TIMEOUTS_1.TIMEOUT_PROCESS_TERMINATION,
|
|
185
|
+
});
|
|
186
|
+
let err;
|
|
187
|
+
try {
|
|
188
|
+
await isReadyPromise;
|
|
414
189
|
}
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
const numberOfTries = timeout / period;
|
|
419
|
-
let i = 0;
|
|
420
|
-
while (true) {
|
|
421
|
-
try {
|
|
422
|
-
await test();
|
|
423
|
-
return;
|
|
424
|
-
}
|
|
425
|
-
catch (err) {
|
|
426
|
-
i = i + 1;
|
|
427
|
-
if (i > numberOfTries) {
|
|
428
|
-
throw err;
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
await (0, utils_1.sleep)(period);
|
|
190
|
+
catch (err_) {
|
|
191
|
+
err = err_;
|
|
192
|
+
(0, utils_2.assert)(err);
|
|
432
193
|
}
|
|
194
|
+
done(!!err);
|
|
195
|
+
if (err)
|
|
196
|
+
throw err;
|
|
197
|
+
Logs_2.Logs.add({
|
|
198
|
+
logSource: 'run()',
|
|
199
|
+
logText: 'Server is ready.',
|
|
200
|
+
});
|
|
201
|
+
await (0, utils_1.sleep)(serverIsReadyDelay);
|
|
202
|
+
return { terminate };
|
|
433
203
|
}
|
|
434
|
-
exports.autoRetry = autoRetry;
|
|
435
204
|
async function fetchHtml(pathname) {
|
|
436
205
|
const response = await fetch(getServerUrl() + pathname);
|
|
437
206
|
const html = await response.text();
|
|
@@ -443,7 +212,7 @@ async function fetch(...args) {
|
|
|
443
212
|
return await (0, node_fetch_1.default)(...args);
|
|
444
213
|
}
|
|
445
214
|
catch (err) {
|
|
446
|
-
|
|
215
|
+
Logs_2.Logs.add({
|
|
447
216
|
logSource: 'Connection Error',
|
|
448
217
|
logText: `Couldn't connect to \`${args[0]}\`. Args: \`${JSON.stringify(args.slice(1))}\`. Err: \`${
|
|
449
218
|
// @ts-ignore
|
|
@@ -480,20 +249,16 @@ function isMinNodeVersion(minNodeVersion) {
|
|
|
480
249
|
return major >= minNodeVersion;
|
|
481
250
|
}
|
|
482
251
|
exports.isMinNodeVersion = isMinNodeVersion;
|
|
483
|
-
function getCwd() {
|
|
484
|
-
const { testFile } = (0, getCurrentTest_1.getCurrentTest)();
|
|
485
|
-
const cwd = (0, path_1.dirname)(testFile);
|
|
486
|
-
return cwd;
|
|
487
|
-
}
|
|
488
252
|
function getServerUrl() {
|
|
489
253
|
const testInfo = (0, getCurrentTest_1.getCurrentTest)();
|
|
490
254
|
const serverUrl = testInfo.runInfo?.serverUrl;
|
|
491
255
|
return serverUrl;
|
|
492
256
|
}
|
|
493
257
|
exports.getServerUrl = getServerUrl;
|
|
494
|
-
function
|
|
258
|
+
function getServerPort() {
|
|
495
259
|
const serverUrl = getServerUrl();
|
|
496
|
-
const
|
|
497
|
-
(0, utils_2.assert)(/\d+/.test(
|
|
260
|
+
const portStr = serverUrl.split(':').slice(-1)[0].split('/')[0];
|
|
261
|
+
(0, utils_2.assert)(/\d+/.test(portStr), { serverUrl });
|
|
262
|
+
const port = parseInt(portStr, 10);
|
|
498
263
|
return port;
|
|
499
264
|
}
|
|
@@ -82,6 +82,6 @@ function getPngPaths() {
|
|
|
82
82
|
function getTestFileDir() {
|
|
83
83
|
const { testFile, runInfo } = (0, getCurrentTest_1.getCurrentTest)();
|
|
84
84
|
const cwd = path_1.default.dirname(testFile);
|
|
85
|
-
(0, utils_1.assert)(
|
|
85
|
+
(0, utils_1.assert)(cwd === (0, getCurrentTest_1.getCwd)());
|
|
86
86
|
return cwd;
|
|
87
87
|
}
|
package/dist/utils/findFiles.js
CHANGED
|
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.findFilesParseCliArgs = exports.findFiles = void 0;
|
|
7
7
|
const fast_glob_1 = __importDefault(require("fast-glob"));
|
|
8
8
|
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const
|
|
9
|
+
const runCommandShortLived_1 = require("./runCommandShortLived");
|
|
10
10
|
const cwd = process.cwd();
|
|
11
11
|
let gitFiles;
|
|
12
12
|
async function findFiles(pattern, findFilter) {
|
|
@@ -19,11 +19,11 @@ async function findFiles(pattern, findFilter) {
|
|
|
19
19
|
exports.findFiles = findFiles;
|
|
20
20
|
async function filterGitIgnoredFiles(files) {
|
|
21
21
|
if (!gitFiles) {
|
|
22
|
-
const stdout1 = await (0,
|
|
22
|
+
const stdout1 = await (0, runCommandShortLived_1.runCommandShortLived)('git ls-files', { cwd });
|
|
23
23
|
// Also include untracked files.
|
|
24
24
|
// - In other words, we remove git ignored files. (Staged files are tracked and listed by `$ git ls-files`.)
|
|
25
25
|
// - `git ls-files --others --exclude-standard` from https://stackoverflow.com/questions/3801321/git-list-only-untracked-files-also-custom-commands/3801554#3801554
|
|
26
|
-
const stdout2 = await (0,
|
|
26
|
+
const stdout2 = await (0, runCommandShortLived_1.runCommandShortLived)('git ls-files --others --exclude-standard', { cwd });
|
|
27
27
|
gitFiles = [...stdout1.split('\n'), ...stdout2.split('\n')].map((filePathRelative) => path_1.default.join(cwd, filePathRelative));
|
|
28
28
|
}
|
|
29
29
|
const filesFiltered = files.filter((file) => gitFiles.includes(file));
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.genPromise = void 0;
|
|
4
|
+
function genPromise() {
|
|
5
|
+
let resolve;
|
|
6
|
+
let reject;
|
|
7
|
+
const promise = new Promise((resolve_, reject_) => {
|
|
8
|
+
resolve = resolve_;
|
|
9
|
+
reject = reject_;
|
|
10
|
+
});
|
|
11
|
+
return { promise, resolve, reject };
|
|
12
|
+
}
|
|
13
|
+
exports.genPromise = genPromise;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { humanizeTime };
|
|
2
|
-
declare function humanizeTime(milliseconds: number): string
|
|
2
|
+
declare function humanizeTime(milliseconds: number): `${string} seconds` | `${string} minutes`;
|
package/dist/utils/index.d.ts
CHANGED
package/dist/utils/index.js
CHANGED
|
@@ -16,6 +16,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./sleep"), exports);
|
|
18
18
|
__exportStar(require("./runCommand"), exports);
|
|
19
|
+
__exportStar(require("./runCommandShortLived"), exports);
|
|
20
|
+
__exportStar(require("./runCommandLongRunning"), exports);
|
|
19
21
|
__exportStar(require("./assert"), exports);
|
|
20
22
|
__exportStar(require("./humanizeTime"), exports);
|
|
21
23
|
__exportStar(require("./isTTY"), exports);
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export { runCommand };
|
|
2
|
-
declare function runCommand(cmd: string, {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}): Promise<string>;
|
|
2
|
+
declare function runCommand(cmd: string, { timeout, cwd }: {
|
|
3
|
+
timeout: number;
|
|
4
|
+
cwd: string;
|
|
5
|
+
}): Promise<void>;
|