@jsenv/test 1.1.2 → 1.1.3

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.
Files changed (50) hide show
  1. package/dist/jsenv_test.js +4 -2
  2. package/package.json +2 -2
  3. package/src/coverage/babel_plugin_instrument.js +15 -15
  4. package/src/coverage/coverage_reporter_html_directory.js +10 -10
  5. package/src/coverage/coverage_reporter_json_file.js +7 -7
  6. package/src/coverage/coverage_reporter_text_log.js +8 -8
  7. package/src/coverage/empty_coverage_factory.js +24 -24
  8. package/src/coverage/file_by_file_coverage.js +10 -10
  9. package/src/coverage/istanbul_coverage_composition.js +16 -16
  10. package/src/coverage/istanbul_coverage_map_from_coverage.js +8 -8
  11. package/src/coverage/list_files_not_covered.js +4 -4
  12. package/src/coverage/missing_coverage.js +17 -17
  13. package/src/coverage/report_to_coverage.js +52 -52
  14. package/src/coverage/v8_and_istanbul.js +17 -16
  15. package/src/coverage/v8_coverage.js +8 -8
  16. package/src/coverage/v8_coverage_composition.js +12 -12
  17. package/src/coverage/v8_coverage_node_directory.js +42 -42
  18. package/src/coverage/v8_coverage_to_istanbul.js +45 -45
  19. package/src/execution/execute.js +21 -21
  20. package/src/execution/execute_steps.js +129 -129
  21. package/src/execution/execute_test_plan.js +72 -68
  22. package/src/execution/execution_colors.js +2 -2
  23. package/src/execution/execution_steps.js +20 -20
  24. package/src/execution/gc.js +5 -5
  25. package/src/execution/logs_file_execution.js +126 -126
  26. package/src/execution/logs_file_execution.test.mjs +11 -11
  27. package/src/execution/run.js +51 -51
  28. package/src/execution/web_server_param.js +24 -24
  29. package/src/main.js +7 -7
  30. package/src/runtime_browsers/chromium.js +7 -7
  31. package/src/runtime_browsers/firefox.js +10 -10
  32. package/src/runtime_browsers/middleware_istanbul.js +23 -23
  33. package/src/runtime_browsers/middleware_js_supervisor.js +32 -32
  34. package/src/runtime_browsers/using_playwright.js +186 -186
  35. package/src/runtime_browsers/webkit.js +11 -11
  36. package/src/runtime_node/child_exec_options.js +43 -43
  37. package/src/runtime_node/controllable_child_process.mjs +47 -47
  38. package/src/runtime_node/controllable_worker_thread.mjs +37 -37
  39. package/src/runtime_node/exec_options.js +26 -26
  40. package/src/runtime_node/execute_using_dynamic_import.js +26 -26
  41. package/src/runtime_node/exit_codes.js +4 -4
  42. package/src/runtime_node/importmap_node_loader.mjs +24 -24
  43. package/src/runtime_node/importmap_node_loader_file_url.js +1 -1
  44. package/src/runtime_node/kill_process_tree.js +30 -30
  45. package/src/runtime_node/no_experimental_warnings.cjs +4 -4
  46. package/src/runtime_node/no_experimental_warnings_file_url.js +1 -1
  47. package/src/runtime_node/node_child_process.js +128 -128
  48. package/src/runtime_node/node_execution_performance.js +28 -28
  49. package/src/runtime_node/node_worker_thread.js +108 -108
  50. package/src/runtime_node/profiler_v8_coverage.js +21 -21
@@ -1,24 +1,24 @@
1
- import { fork } from "node:child_process"
2
- import { fileURLToPath } from "node:url"
1
+ import { fork } from "node:child_process";
2
+ import { fileURLToPath } from "node:url";
3
3
  import {
4
4
  Abort,
5
5
  raceCallbacks,
6
6
  createCallbackListNotifiedOnce,
7
- } from "@jsenv/abort"
8
- import { createDetailedMessage } from "@jsenv/log"
9
- import { memoize } from "@jsenv/utils/src/memoize/memoize.js"
7
+ } from "@jsenv/abort";
8
+ import { createDetailedMessage } from "@jsenv/log";
9
+ import { memoize } from "@jsenv/utils/src/memoize/memoize.js";
10
10
 
11
- import { createChildExecOptions } from "./child_exec_options.js"
12
- import { ExecOptions } from "./exec_options.js"
13
- import { killProcessTree } from "./kill_process_tree.js"
14
- import { EXIT_CODES } from "./exit_codes.js"
15
- import { IMPORTMAP_NODE_LOADER_FILE_URL } from "./importmap_node_loader_file_url.js"
16
- import { NO_EXPERIMENTAL_WARNING_FILE_URL } from "./no_experimental_warnings_file_url.js"
11
+ import { createChildExecOptions } from "./child_exec_options.js";
12
+ import { ExecOptions } from "./exec_options.js";
13
+ import { killProcessTree } from "./kill_process_tree.js";
14
+ import { EXIT_CODES } from "./exit_codes.js";
15
+ import { IMPORTMAP_NODE_LOADER_FILE_URL } from "./importmap_node_loader_file_url.js";
16
+ import { NO_EXPERIMENTAL_WARNING_FILE_URL } from "./no_experimental_warnings_file_url.js";
17
17
 
18
18
  const CONTROLLABLE_CHILD_PROCESS_URL = new URL(
19
19
  "./controllable_child_process.mjs?entry_point",
20
20
  import.meta.url,
21
- ).href
21
+ ).href;
22
22
 
23
23
  export const nodeChildProcess = ({
24
24
  logProcessCommand = false,
@@ -35,12 +35,12 @@ export const nodeChildProcess = ({
35
35
  stderr = "pipe",
36
36
  } = {}) => {
37
37
  if (env !== undefined && typeof env !== "object") {
38
- throw new TypeError(`env must be an object, got ${env}`)
38
+ throw new TypeError(`env must be an object, got ${env}`);
39
39
  }
40
40
  env = {
41
41
  ...env,
42
42
  JSENV: true,
43
- }
43
+ };
44
44
 
45
45
  return {
46
46
  type: "node",
@@ -64,54 +64,54 @@ export const nodeChildProcess = ({
64
64
  collectPerformance,
65
65
  }) => {
66
66
  if (coverageMethodForNodeJs !== "NODE_V8_COVERAGE") {
67
- env.NODE_V8_COVERAGE = ""
67
+ env.NODE_V8_COVERAGE = "";
68
68
  }
69
69
  commandLineOptions = [
70
70
  "--experimental-import-meta-resolve",
71
71
  ...commandLineOptions,
72
- ]
72
+ ];
73
73
 
74
74
  if (importMap) {
75
- env.IMPORT_MAP = JSON.stringify(importMap)
76
- env.IMPORT_MAP_BASE_URL = rootDirectoryUrl
75
+ env.IMPORT_MAP = JSON.stringify(importMap);
76
+ env.IMPORT_MAP_BASE_URL = rootDirectoryUrl;
77
77
  commandLineOptions.push(
78
78
  `--experimental-loader=${IMPORTMAP_NODE_LOADER_FILE_URL}`,
79
- )
79
+ );
80
80
  commandLineOptions.push(
81
81
  `--require=${fileURLToPath(NO_EXPERIMENTAL_WARNING_FILE_URL)}`,
82
- )
82
+ );
83
83
  }
84
84
 
85
- const cleanupCallbackList = createCallbackListNotifiedOnce()
85
+ const cleanupCallbackList = createCallbackListNotifiedOnce();
86
86
  const cleanup = async (reason) => {
87
- await cleanupCallbackList.notify({ reason })
88
- }
87
+ await cleanupCallbackList.notify({ reason });
88
+ };
89
89
 
90
90
  const childExecOptions = await createChildExecOptions({
91
91
  signal,
92
92
  debugPort,
93
93
  debugMode,
94
94
  debugModeInheritBreak,
95
- })
95
+ });
96
96
  const execArgv = ExecOptions.toExecArgv({
97
97
  ...childExecOptions,
98
98
  ...ExecOptions.fromExecArgv(commandLineOptions),
99
- })
99
+ });
100
100
  const envForChildProcess = {
101
101
  ...(inheritProcessEnv ? process.env : {}),
102
102
  ...env,
103
- }
103
+ };
104
104
  logger[logProcessCommand ? "info" : "debug"](
105
105
  `${process.argv[0]} ${execArgv.join(" ")} ${fileURLToPath(
106
106
  CONTROLLABLE_CHILD_PROCESS_URL,
107
107
  )}`,
108
- )
108
+ );
109
109
  const childProcess = fork(fileURLToPath(CONTROLLABLE_CHILD_PROCESS_URL), {
110
110
  execArgv,
111
111
  // silent: true
112
112
  stdio: ["pipe", "pipe", "pipe", "ipc"],
113
113
  env: envForChildProcess,
114
- })
114
+ });
115
115
  logger.debug(
116
116
  createDetailedMessage(
117
117
  `child process forked (pid ${childProcess.pid})`,
@@ -119,26 +119,26 @@ export const nodeChildProcess = ({
119
119
  "custom env": JSON.stringify(env, null, " "),
120
120
  },
121
121
  ),
122
- )
122
+ );
123
123
  // if we pass stream, pipe them https://github.com/sindresorhus/execa/issues/81
124
124
  if (typeof stdin === "object") {
125
- stdin.pipe(childProcess.stdin)
125
+ stdin.pipe(childProcess.stdin);
126
126
  }
127
127
  if (typeof stdout === "object") {
128
- childProcess.stdout.pipe(stdout)
128
+ childProcess.stdout.pipe(stdout);
129
129
  }
130
130
  if (typeof stderr === "object") {
131
- childProcess.stderr.pipe(stderr)
131
+ childProcess.stderr.pipe(stderr);
132
132
  }
133
133
  const childProcessReadyPromise = new Promise((resolve) => {
134
- onceChildProcessMessage(childProcess, "ready", resolve)
135
- })
134
+ onceChildProcessMessage(childProcess, "ready", resolve);
135
+ });
136
136
  const removeOutputListener = installChildProcessOutputListener(
137
137
  childProcess,
138
138
  ({ type, text }) => {
139
- onConsole({ type, text })
139
+ onConsole({ type, text });
140
140
  },
141
- )
141
+ );
142
142
  const stop = memoize(async ({ gracefulStopAllocatedMs } = {}) => {
143
143
  // all libraries are facing problem on windows when trying
144
144
  // to kill a process spawning other processes.
@@ -147,40 +147,40 @@ export const nodeChildProcess = ({
147
147
  // There is no satisfying solution to this problem so we stick to the basic
148
148
  // childProcess.kill()
149
149
  if (process.platform === "win32") {
150
- childProcess.kill()
151
- return
150
+ childProcess.kill();
151
+ return;
152
152
  }
153
153
  if (gracefulStopAllocatedMs) {
154
154
  try {
155
155
  await killProcessTree(childProcess.pid, {
156
156
  signal: GRACEFUL_STOP_SIGNAL,
157
157
  timeout: gracefulStopAllocatedMs,
158
- })
159
- return
158
+ });
159
+ return;
160
160
  } catch (e) {
161
161
  if (e.code === "TIMEOUT") {
162
162
  logger.debug(
163
163
  `kill with SIGTERM because gracefulStop still pending after ${gracefulStopAllocatedMs}ms`,
164
- )
164
+ );
165
165
  await killProcessTree(childProcess.pid, {
166
166
  signal: GRACEFUL_STOP_FAILED_SIGNAL,
167
- })
168
- return
167
+ });
168
+ return;
169
169
  }
170
- throw e
170
+ throw e;
171
171
  }
172
172
  }
173
- await killProcessTree(childProcess.pid, { signal: STOP_SIGNAL })
174
- return
175
- })
173
+ await killProcessTree(childProcess.pid, { signal: STOP_SIGNAL });
174
+ return;
175
+ });
176
176
 
177
- const actionOperation = Abort.startOperation()
178
- actionOperation.addAbortSignal(signal)
177
+ const actionOperation = Abort.startOperation();
178
+ actionOperation.addAbortSignal(signal);
179
179
  const winnerPromise = new Promise((resolve) => {
180
180
  raceCallbacks(
181
181
  {
182
182
  aborted: (cb) => {
183
- return actionOperation.addAbortCallback(cb)
183
+ return actionOperation.addAbortCallback(cb);
184
184
  },
185
185
  // https://nodejs.org/api/child_process.html#child_process_event_disconnect
186
186
  // disconnect: (cb) => {
@@ -188,34 +188,34 @@ export const nodeChildProcess = ({
188
188
  // },
189
189
  // https://nodejs.org/api/child_process.html#child_process_event_error
190
190
  error: (cb) => {
191
- return onceChildProcessEvent(childProcess, "error", cb)
191
+ return onceChildProcessEvent(childProcess, "error", cb);
192
192
  },
193
193
  exit: (cb) => {
194
194
  return onceChildProcessEvent(
195
195
  childProcess,
196
196
  "exit",
197
197
  (code, signal) => {
198
- cb({ code, signal })
198
+ cb({ code, signal });
199
199
  },
200
- )
200
+ );
201
201
  },
202
202
  response: (cb) => {
203
- return onceChildProcessMessage(childProcess, "action-result", cb)
203
+ return onceChildProcessMessage(childProcess, "action-result", cb);
204
204
  },
205
205
  },
206
206
  resolve,
207
- )
208
- })
207
+ );
208
+ });
209
209
  const result = {
210
210
  status: "executing",
211
211
  errors: [],
212
212
  namespace: null,
213
- }
213
+ };
214
214
 
215
215
  const writeResult = async () => {
216
- actionOperation.throwIfAborted()
217
- await childProcessReadyPromise
218
- actionOperation.throwIfAborted()
216
+ actionOperation.throwIfAborted();
217
+ await childProcessReadyPromise;
218
+ actionOperation.throwIfAborted();
219
219
  await sendToChildProcess(childProcess, {
220
220
  type: "action",
221
221
  data: {
@@ -231,30 +231,30 @@ export const nodeChildProcess = ({
231
231
  exitAfterAction: true,
232
232
  },
233
233
  },
234
- })
235
- const winner = await winnerPromise
234
+ });
235
+ const winner = await winnerPromise;
236
236
  if (winner.name === "aborted") {
237
- result.status = "aborted"
238
- return
237
+ result.status = "aborted";
238
+ return;
239
239
  }
240
240
  if (winner.name === "error") {
241
- const error = winner.data
242
- removeOutputListener()
243
- result.status = "failed"
244
- result.errors.push(error)
245
- return
241
+ const error = winner.data;
242
+ removeOutputListener();
243
+ result.status = "failed";
244
+ result.errors.push(error);
245
+ return;
246
246
  }
247
247
  if (winner.name === "exit") {
248
- const { code } = winner.data
249
- await cleanup("process exit")
248
+ const { code } = winner.data;
249
+ await cleanup("process exit");
250
250
  if (code === 12) {
251
- result.status = "failed"
251
+ result.status = "failed";
252
252
  result.errors.push(
253
253
  new Error(
254
254
  `node process exited with 12 (the forked child process wanted to use a non-available port for debug)`,
255
255
  ),
256
- )
257
- return
256
+ );
257
+ return;
258
258
  }
259
259
  if (
260
260
  code === null ||
@@ -263,59 +263,59 @@ export const nodeChildProcess = ({
263
263
  code === EXIT_CODES.SIGTERM ||
264
264
  code === EXIT_CODES.SIGABORT
265
265
  ) {
266
- result.status = "failed"
266
+ result.status = "failed";
267
267
  result.errors.push(
268
268
  new Error(`node process exited during execution`),
269
- )
270
- return
269
+ );
270
+ return;
271
271
  }
272
272
  // process.exit(1) in child process or process.exitCode = 1 + process.exit()
273
273
  // means there was an error even if we don't know exactly what.
274
- result.status = "failed"
274
+ result.status = "failed";
275
275
  result.errors.push(
276
276
  new Error(`node process exited with code ${code} during execution`),
277
- )
278
- return
277
+ );
278
+ return;
279
279
  }
280
- const { status, value } = winner.data
280
+ const { status, value } = winner.data;
281
281
  if (status === "action-failed") {
282
- result.status = "failed"
283
- result.errors.push(value)
284
- return
282
+ result.status = "failed";
283
+ result.errors.push(value);
284
+ return;
285
285
  }
286
- const { namespace, performance, coverage } = value
287
- result.status = "completed"
288
- result.namespace = namespace
289
- result.performance = performance
290
- result.coverage = coverage
291
- }
286
+ const { namespace, performance, coverage } = value;
287
+ result.status = "completed";
288
+ result.namespace = namespace;
289
+ result.performance = performance;
290
+ result.coverage = coverage;
291
+ };
292
292
 
293
293
  try {
294
- await writeResult()
294
+ await writeResult();
295
295
  } catch (e) {
296
- result.status = "failed"
297
- result.errors.push(e)
296
+ result.status = "failed";
297
+ result.errors.push(e);
298
298
  }
299
299
  if (keepRunning) {
300
- stopSignal.notify = stop
300
+ stopSignal.notify = stop;
301
301
  } else {
302
302
  await stop({
303
303
  gracefulStopAllocatedMs,
304
- })
304
+ });
305
305
  }
306
- await actionOperation.end()
307
- return result
306
+ await actionOperation.end();
307
+ return result;
308
308
  },
309
- }
310
- }
309
+ };
310
+ };
311
311
 
312
312
  // http://man7.org/linux/man-pages/man7/signal.7.html
313
313
  // https:// github.com/nodejs/node/blob/1d9511127c419ec116b3ddf5fc7a59e8f0f1c1e4/lib/internal/child_process.js#L472
314
- const GRACEFUL_STOP_SIGNAL = "SIGTERM"
315
- const STOP_SIGNAL = "SIGKILL"
314
+ const GRACEFUL_STOP_SIGNAL = "SIGTERM";
315
+ const STOP_SIGNAL = "SIGKILL";
316
316
  // it would be more correct if GRACEFUL_STOP_FAILED_SIGNAL was SIGHUP instead of SIGKILL.
317
317
  // but I'm not sure and it changes nothing so just use SIGKILL
318
- const GRACEFUL_STOP_FAILED_SIGNAL = "SIGKILL"
318
+ const GRACEFUL_STOP_FAILED_SIGNAL = "SIGKILL";
319
319
 
320
320
  const sendToChildProcess = async (childProcess, { type, data }) => {
321
321
  return new Promise((resolve, reject) => {
@@ -327,48 +327,48 @@ const sendToChildProcess = async (childProcess, { type, data }) => {
327
327
  },
328
328
  (error) => {
329
329
  if (error) {
330
- reject(error)
330
+ reject(error);
331
331
  } else {
332
- resolve()
332
+ resolve();
333
333
  }
334
334
  },
335
- )
336
- })
337
- }
335
+ );
336
+ });
337
+ };
338
338
 
339
339
  const installChildProcessOutputListener = (childProcess, callback) => {
340
340
  // beware that we may receive ansi output here, should not be a problem but keep that in mind
341
341
  const stdoutDataCallback = (chunk) => {
342
- callback({ type: "log", text: String(chunk) })
343
- }
344
- childProcess.stdout.on("data", stdoutDataCallback)
342
+ callback({ type: "log", text: String(chunk) });
343
+ };
344
+ childProcess.stdout.on("data", stdoutDataCallback);
345
345
  const stdErrorDataCallback = (chunk) => {
346
- callback({ type: "error", text: String(chunk) })
347
- }
348
- childProcess.stderr.on("data", stdErrorDataCallback)
346
+ callback({ type: "error", text: String(chunk) });
347
+ };
348
+ childProcess.stderr.on("data", stdErrorDataCallback);
349
349
  return () => {
350
- childProcess.stdout.removeListener("data", stdoutDataCallback)
351
- childProcess.stderr.removeListener("data", stdoutDataCallback)
352
- }
353
- }
350
+ childProcess.stdout.removeListener("data", stdoutDataCallback);
351
+ childProcess.stderr.removeListener("data", stdoutDataCallback);
352
+ };
353
+ };
354
354
 
355
355
  const onceChildProcessMessage = (childProcess, type, callback) => {
356
356
  const onmessage = (message) => {
357
357
  if (message && message.jsenv && message.type === type) {
358
- childProcess.removeListener("message", onmessage)
358
+ childProcess.removeListener("message", onmessage);
359
359
  // eslint-disable-next-line no-eval
360
- callback(message.data ? eval(`(${message.data})`) : "")
360
+ callback(message.data ? eval(`(${message.data})`) : "");
361
361
  }
362
- }
363
- childProcess.on("message", onmessage)
362
+ };
363
+ childProcess.on("message", onmessage);
364
364
  return () => {
365
- childProcess.removeListener("message", onmessage)
366
- }
367
- }
365
+ childProcess.removeListener("message", onmessage);
366
+ };
367
+ };
368
368
 
369
369
  const onceChildProcessEvent = (childProcess, type, callback) => {
370
- childProcess.once(type, callback)
370
+ childProcess.once(type, callback);
371
371
  return () => {
372
- childProcess.removeListener(type, callback)
373
- }
374
- }
372
+ childProcess.removeListener(type, callback);
373
+ };
374
+ };
@@ -1,67 +1,67 @@
1
- import { PerformanceObserver, performance } from "node:perf_hooks"
1
+ import { PerformanceObserver, performance } from "node:perf_hooks";
2
2
 
3
3
  export const startObservingPerformances = () => {
4
- const measureEntries = []
4
+ const measureEntries = [];
5
5
  // https://nodejs.org/dist/latest-v16.x/docs/api/perf_hooks.html
6
6
  const perfObserver = new PerformanceObserver(
7
7
  (
8
8
  // https://nodejs.org/dist/latest-v16.x/docs/api/perf_hooks.html#perf_hooks_class_performanceobserverentrylist
9
9
  list,
10
10
  ) => {
11
- const perfMeasureEntries = list.getEntriesByType("measure")
12
- measureEntries.push(...perfMeasureEntries)
11
+ const perfMeasureEntries = list.getEntriesByType("measure");
12
+ measureEntries.push(...perfMeasureEntries);
13
13
  },
14
- )
14
+ );
15
15
  perfObserver.observe({
16
16
  entryTypes: ["measure"],
17
- })
17
+ });
18
18
  return async () => {
19
19
  // wait for node to call the performance observer
20
20
  await new Promise((resolve) => {
21
- setTimeout(resolve)
22
- })
23
- performance.clearMarks()
24
- perfObserver.disconnect()
21
+ setTimeout(resolve);
22
+ });
23
+ performance.clearMarks();
24
+ perfObserver.disconnect();
25
25
  return {
26
26
  ...readNodePerformance(),
27
27
  measures: measuresFromMeasureEntries(measureEntries),
28
- }
29
- }
30
- }
28
+ };
29
+ };
30
+ };
31
31
 
32
32
  const readNodePerformance = () => {
33
33
  const nodePerformance = {
34
34
  nodeTiming: asPlainObject(performance.nodeTiming),
35
35
  timeOrigin: performance.timeOrigin,
36
36
  eventLoopUtilization: performance.eventLoopUtilization(),
37
- }
38
- return nodePerformance
39
- }
37
+ };
38
+ return nodePerformance;
39
+ };
40
40
 
41
41
  // remove getters that cannot be stringified
42
42
  const asPlainObject = (objectWithGetters) => {
43
- const objectWithoutGetters = {}
43
+ const objectWithoutGetters = {};
44
44
  Object.keys(objectWithGetters).forEach((key) => {
45
- objectWithoutGetters[key] = objectWithGetters[key]
46
- })
47
- return objectWithoutGetters
48
- }
45
+ objectWithoutGetters[key] = objectWithGetters[key];
46
+ });
47
+ return objectWithoutGetters;
48
+ };
49
49
 
50
50
  const measuresFromMeasureEntries = (measureEntries) => {
51
- const measures = {}
51
+ const measures = {};
52
52
  // Sort to ensure measures order is predictable
53
53
  // It seems to be already predictable on Node 16+ but
54
54
  // it's not the case on Node 14.
55
55
  measureEntries.sort((a, b) => {
56
- return a.startTime - b.startTime
57
- })
56
+ return a.startTime - b.startTime;
57
+ });
58
58
  measureEntries.forEach(
59
59
  (
60
60
  // https://nodejs.org/dist/latest-v16.x/docs/api/perf_hooks.html#perf_hooks_class_performanceentry
61
61
  perfMeasureEntry,
62
62
  ) => {
63
- measures[perfMeasureEntry.name] = perfMeasureEntry.duration
63
+ measures[perfMeasureEntry.name] = perfMeasureEntry.duration;
64
64
  },
65
- )
66
- return measures
67
- }
65
+ );
66
+ return measures;
67
+ };