@jsenv/test 1.0.2 → 1.0.4

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/README.md CHANGED
@@ -3,9 +3,9 @@
3
3
  Executing test files in web browsers and/or Node.js.
4
4
  This tool enforce test files to be written as **standard** files, without any sort of complexity.
5
5
 
6
- # 1. Writing tests on web browsers
6
+ # 1. Writing tests on web browsers
7
7
 
8
- This section demonstrates how to write a test that will be executed in a web browser.
8
+ This section demonstrates how to write a test that will be executed in a web browser.
9
9
 
10
10
  The function that will be tested is inside "add.js" file:
11
11
 
@@ -39,7 +39,7 @@ project/
39
39
 
40
40
  ## 1.1 Writing the test file
41
41
 
42
- *src/add.test.html*
42
+ _src/add.test.html_
43
43
 
44
44
  ```html
45
45
  <!DOCTYPE html>
@@ -66,7 +66,7 @@ project/
66
66
 
67
67
  ## 1.2 Executing the test file
68
68
 
69
- *scripts/dev.mjs*: will start a web server that is needed to executed "add.test.html" in a browser.
69
+ _scripts/dev.mjs_: will start a web server that is needed to executed "add.test.html" in a browser.
70
70
 
71
71
  ```js
72
72
  import { startDevServer } from "@jsenv/core"
@@ -77,7 +77,7 @@ await startDevServer({
77
77
  })
78
78
  ```
79
79
 
80
- *scripts/test.mjs*: will start a web browser and use it to execute all test files.
80
+ _scripts/test.mjs_: will start a web browser and use it to execute all test files.
81
81
 
82
82
  ```js
83
83
  import { executeTestPlan, chromium } from "@jsenv/test"
@@ -87,7 +87,7 @@ await executeTestPlan({
87
87
  testPlan: {
88
88
  "./src/**/*.test.html": {
89
89
  chromium: {
90
- runtime: chromium()
90
+ runtime: chromium(),
91
91
  },
92
92
  },
93
93
  },
@@ -118,25 +118,20 @@ node ./scripts/test.mjs
118
118
  ### 1.3 Executing on more browsers
119
119
 
120
120
  ```js
121
- import {
122
- executeTestPlan,
123
- chromium,
124
- firefox,
125
- webkit,
126
- } from "@jsenv/test"
121
+ import { executeTestPlan, chromium, firefox, webkit } from "@jsenv/test"
127
122
 
128
123
  await executeTestPlan({
129
124
  rootDirectoryUrl: new URL("../", import.meta.url),
130
125
  testPlan: {
131
126
  "./src/**/*.test.html": {
132
127
  chromium: {
133
- runtime: chromium()
128
+ runtime: chromium(),
134
129
  },
135
130
  firefox: {
136
- runtime: firefox()
131
+ runtime: firefox(),
137
132
  },
138
133
  webkit: {
139
- runtime: webkit()
134
+ runtime: webkit(),
140
135
  },
141
136
  },
142
137
  },
@@ -148,9 +143,9 @@ await executeTestPlan({
148
143
  })
149
144
  ```
150
145
 
151
- ## 2. Writing tests on Node.js
146
+ # 2. Writing tests on Node.js
152
147
 
153
- This section demonstrates how to write a test that will be executed in Node.js.
148
+ This section demonstrates how to write a test that will be executed in Node.js.
154
149
 
155
150
  The function that will be tested is inside "add.js" file:
156
151
 
@@ -182,7 +177,7 @@ project/
182
177
 
183
178
  ## 2.1 Writing the test file
184
179
 
185
- *add.test.mjs*
180
+ _add.test.mjs_
186
181
 
187
182
  ```js
188
183
  import { add } from "./add.js"
@@ -196,7 +191,7 @@ if (actual !== expected) {
196
191
 
197
192
  ## 2.2 Executing the test file
198
193
 
199
- *scripts/test.mjs*
194
+ _scripts/test.mjs_
200
195
 
201
196
  ```js
202
197
  import { executeTestPlan, nodeWorkerThread } from "@jsenv/test"
@@ -206,7 +201,7 @@ await executeTestPlan({
206
201
  testPlan: {
207
202
  "./tests/**/*.test.mjs": {
208
203
  node: {
209
- runtime: nodeWorkerThread()
204
+ runtime: nodeWorkerThread(),
210
205
  },
211
206
  },
212
207
  },
@@ -225,7 +220,7 @@ Command to execute tests:
225
220
  node ./scripts/test.mjs
226
221
  ```
227
222
 
228
- ## 3. Assertion library
223
+ # 3. Assertion library
229
224
 
230
225
  To have a basic example, the part of the code comparing `actual` and `expected` was done without an assertion library.
231
226
  In pratice a test would likely use one. The diff below shows how the assertion can be written using [@jsenv/assert](../assert). Note that any other assertion library would work.
@@ -242,47 +237,102 @@ const expected = 3
242
237
  + assert({ actual, expected })
243
238
  ```
244
239
 
245
- ## 4. API
246
-
247
- ## 4.1 executeTestPlan
240
+ # 4. API
248
241
 
249
242
  ```js
250
- import { executeTestPlan } from "@jsenv/test"
243
+ import {
244
+ executeTestPlan,
245
+ chromium,
246
+ firefox,
247
+ webkit,
248
+ nodeWorkerThread,
249
+ nodeChildProcess,
250
+ } from "@jsenv/test"
251
251
 
252
252
  const report = await executeTestPlan({
253
- keepRunning: false, // true would keep process alive and all browsers opened even when tests are done
254
- coverageEnabled: false, // collect code coverage while executing tests
253
+ rootDirectoryUrl: new URL("../", import.meta.url),
254
+ testPlan: {
255
+ "./src/**/*.test.html": {
256
+ chromium: {
257
+ runtime: chromium(),
258
+ },
259
+ firefox: {
260
+ runtime: firefox(),
261
+ },
262
+ webkit: {
263
+ runtime: webkit(),
264
+ },
265
+ },
266
+ "./src/**/*.test.mjs": {
267
+ node_worker: {
268
+ runtime: nodeWorkerThread(),
269
+ },
270
+ node_process: {
271
+ runtime: nodeChildProcess({
272
+ commandLineOptions: ["--no-warnings"],
273
+ env: { TEST: "1" },
274
+ importMap: {
275
+ imports: { foo: "./foo_mock.js" },
276
+ },
277
+ }),
278
+ },
279
+ },
280
+ },
281
+ webServer: {
282
+ origin: "http://localhost:3456",
283
+ rootDirectoryUrl: new URL("../src/", import.meta.url),
284
+ moduleUrl: new URL("./dev.mjs", import.meta.url),
285
+ },
286
+ keepRunning: true,
287
+ logShortForCompletedExecutions: true,
288
+ logMergeForCompletedExecutions: true,
289
+ coverageEnabled: true,
290
+ coverageConfig: {
291
+ "./src/**/*.js": true,
292
+ "./src/**/*.test.mjs": false,
293
+ },
255
294
  })
256
295
  report // contains many information about test executions
257
296
  ```
258
297
 
298
+ | Parameter | Description |
299
+ | ------------------------------ | ----------------------------------------------------------------------------------------------------- |
300
+ | rootDirectoryUrl | Url used to resolve relative urls in other parameters (like testPlan) |
301
+ | testPlan | Object listing the files to execute and configuring where they will be executed |
302
+ | keepRunning | Boolean that can be used to keep browser/node process alive after all executions are done |
303
+ | logShortForCompletedExecutions | Boolean, when enabled completed execution logs will be shorter |
304
+ | logMergeForCompletedExecutions | Boolean, when enabled, as long as executions are completed, logs are overridden to shorten the output |
305
+ | coverageEnabled | Boolean controlling if code coverage will be collected while executing test files |
306
+ | coverageConfig | Object describing the files that should be covered |
307
+ | coverageReportHtml | Boolean controlling if a code coverage report will be written as HTML files |
308
+ | coverageReportHtmlDirectoryUrl | String or url where html files composing the code coverage report will be written |
309
+
310
+ # 4.1 webServer
311
+
312
+ | Parameter | Description |
313
+ | -------------------------- | ----------------------------------------------------------------------------------------------------------------- |
314
+ | webServer.origin | Url listened by the web server |
315
+ | webServer.rootDirectoryUrl | Url leading to the root directory for the web server |
316
+ | webServer.moduleUrl | `executeTestPlan` does a dynamic import on `webServer.moduleUrl` if there is nothing listening `webServer.origin` |
317
+
259
318
  ## 4.2 chromium/firefox/webkit
260
319
 
261
- Params can be used to configure how the browser runtime is started
320
+ chromium, firefox and webkit runtimes can be configured, they use the parameters listed in the table below:
262
321
 
263
- ```js
264
- chromium({
265
- headful: true // browser UI would be displayed while running tests
266
- })
267
- ```
322
+ | Parameter | Description |
323
+ | ----------------------- | ----------------------------------------------------------------------------------------------------------------- |
324
+ | headful | browser UI would be displayed while running tests |
325
+ | playwrightLaunchOptions | Will be forwarded to playwright launch, see https://playwright.dev/docs/api/class-browsertype#browser-type-launch |
268
326
 
269
327
  ## 4.3 nodeWorkerThread/nodeChildProcess
270
328
 
271
- Params can be used to configure how node child process or node worker thread is started.
272
- Both runtime share the same arguments.
329
+ nodeWorkerThread and nodeChildProcess can be configured, they use the parameters listed in the table below:
273
330
 
274
- ```js
275
- import {
276
- nodeWorkerThread,
277
- nodeChildProcess
278
- } from "@jsenv/test"
279
-
280
- nodeWorkerThread({
281
- commandLineOptions: [], // see https://nodejs.org/api/cli.html#options
282
- env: null // will be written on process.env, see https://nodejs.org/api/child_process.html#child_processexeccommand-options-callback
283
- importMap: null, // can be used to override import resolution (redirect to other files during test)
284
- })
285
- ```
331
+ | Parameter | Description |
332
+ | ------------------ | ----------------------------------------------------------------------------------------------------------------------- |
333
+ | commandLineOptions | Command line options for node, see https://nodejs.org/api/cli.html#options |
334
+ | env | Becomes `process.env`, see "env" in https://nodejs.org/api/child_process.html#child_processexeccommand-options-callback |
335
+ | importMap | Can be used to override import resolution (redirect to other files during test) |
286
336
 
287
337
  ## 4.4 Allocated time
288
338
 
@@ -291,10 +341,7 @@ If this duration is exceeded the browser tab (or node process/worker thread) is
291
341
  This duration can be configured as shown below:
292
342
 
293
343
  ```js
294
- import {
295
- executeTestPlan,
296
- nodeWorkerThread
297
- } from "@jsenv/test"
344
+ import { executeTestPlan, nodeWorkerThread } from "@jsenv/test"
298
345
 
299
346
  await executeTestPlan({
300
347
  rootDirectoryUrl: new URL("../", import.meta.url),
@@ -302,7 +349,7 @@ await executeTestPlan({
302
349
  "./tests/**/*.test.mjs": {
303
350
  node: {
304
351
  runtime: nodeWorkerThread(),
305
- allocatedMs: 60_000
352
+ allocatedMs: 60_000,
306
353
  },
307
354
  },
308
355
  },
@@ -310,5 +357,3 @@ await executeTestPlan({
310
357
  ```
311
358
 
312
359
  ☝️ Code above changes the default allocated time to 60s.
313
-
314
-
@@ -3244,7 +3244,7 @@ const createExecutionLog = ({
3244
3244
  startMs,
3245
3245
  endMs
3246
3246
  }, {
3247
- completedExecutionLogAbbreviation,
3247
+ logShortForCompletedExecutions,
3248
3248
  counters,
3249
3249
  logRuntime,
3250
3250
  logEachDuration,
@@ -3267,7 +3267,7 @@ const createExecutionLog = ({
3267
3267
  memoryHeap
3268
3268
  });
3269
3269
  let log;
3270
- if (completedExecutionLogAbbreviation && status === "completed") {
3270
+ if (logShortForCompletedExecutions && status === "completed") {
3271
3271
  log = `${description}${summary}`;
3272
3272
  } else {
3273
3273
  const {
@@ -3300,7 +3300,7 @@ const createExecutionLog = ({
3300
3300
  wordWrap: false
3301
3301
  });
3302
3302
  if (endMs) {
3303
- if (completedExecutionLogAbbreviation) {
3303
+ if (logShortForCompletedExecutions) {
3304
3304
  return `${log}\n`;
3305
3305
  }
3306
3306
  if (executionIndex === counters.total - 1) {
@@ -3608,8 +3608,8 @@ const executeSteps = async (executionSteps, {
3608
3608
  logTimeUsage,
3609
3609
  logMemoryHeapUsage,
3610
3610
  logFileRelativeUrl,
3611
- completedExecutionLogMerging,
3612
- completedExecutionLogAbbreviation,
3611
+ logMergeForCompletedExecutions,
3612
+ logShortForCompletedExecutions,
3613
3613
  rootDirectoryUrl,
3614
3614
  webServer,
3615
3615
  keepRunning,
@@ -3697,9 +3697,9 @@ const executeSteps = async (executionSteps, {
3697
3697
  coverageMethodForNodeJs,
3698
3698
  stopAfterAllSignal
3699
3699
  };
3700
- if (completedExecutionLogMerging && !process.stdout.isTTY) {
3701
- completedExecutionLogMerging = false;
3702
- logger.debug(`Force completedExecutionLogMerging to false because process.stdout.isTTY is false`);
3700
+ if (logMergeForCompletedExecutions && !process.stdout.isTTY) {
3701
+ logMergeForCompletedExecutions = false;
3702
+ logger.debug(`Force logMergeForCompletedExecutions to false because process.stdout.isTTY is false`);
3703
3703
  }
3704
3704
  const debugLogsEnabled = logger.levels.debug;
3705
3705
  const executionLogsEnabled = logger.levels.info;
@@ -3834,7 +3834,7 @@ const executeSteps = async (executionSteps, {
3834
3834
  }
3835
3835
  if (executionLogsEnabled) {
3836
3836
  const log = createExecutionLog(afterExecutionInfo, {
3837
- completedExecutionLogAbbreviation,
3837
+ logShortForCompletedExecutions,
3838
3838
  counters,
3839
3839
  logRuntime,
3840
3840
  logEachDuration,
@@ -3850,7 +3850,7 @@ const executeSteps = async (executionSteps, {
3850
3850
  executionLog.write(log);
3851
3851
  rawOutput += stripAnsi(log);
3852
3852
  const canOverwriteLog = canOverwriteLogGetter({
3853
- completedExecutionLogMerging,
3853
+ logMergeForCompletedExecutions,
3854
3854
  executionResult
3855
3855
  });
3856
3856
  if (canOverwriteLog) {
@@ -3906,10 +3906,10 @@ const executeSteps = async (executionSteps, {
3906
3906
  }
3907
3907
  };
3908
3908
  const canOverwriteLogGetter = ({
3909
- completedExecutionLogMerging,
3909
+ logMergeForCompletedExecutions,
3910
3910
  executionResult
3911
3911
  }) => {
3912
- if (!completedExecutionLogMerging) {
3912
+ if (!logMergeForCompletedExecutions) {
3913
3913
  return false;
3914
3914
  }
3915
3915
  if (executionResult.status === "aborted") {
@@ -3974,8 +3974,8 @@ const executeInParallel = async ({
3974
3974
  * @param {string|url} testPlanParameters.rootDirectoryUrl Directory containing test files;
3975
3975
  * @param {Object} [testPlanParameters.webServer] Web server info; required when executing test on browsers
3976
3976
  * @param {Object} testPlanParameters.testPlan Object associating files with runtimes where they will be executed
3977
- * @param {boolean} [testPlanParameters.completedExecutionLogAbbreviation=false] Abbreviate completed execution information to shorten terminal output
3978
- * @param {boolean} [testPlanParameters.completedExecutionLogMerging=false] Merge completed execution logs to shorten terminal output
3977
+ * @param {boolean} [testPlanParameters.logShortForCompletedExecutions=false] Abbreviate completed execution information to shorten terminal output
3978
+ * @param {boolean} [testPlanParameters.logMergeForCompletedExecutions=false] Merge completed execution logs to shorten terminal output
3979
3979
  * @param {number} [testPlanParameters.maxExecutionsInParallel=1] Maximum amount of execution in parallel
3980
3980
  * @param {number} [testPlanParameters.defaultMsAllocatedPerExecution=30000] Milliseconds after which execution is aborted and considered as failed by timeout
3981
3981
  * @param {boolean} [testPlanParameters.failFast=false] Fails immediatly when a test execution fails
@@ -3996,8 +3996,8 @@ const executeTestPlan = async ({
3996
3996
  logTimeUsage = false,
3997
3997
  logMemoryHeapUsage = false,
3998
3998
  logFileRelativeUrl = ".jsenv/test_plan_debug.txt",
3999
- completedExecutionLogAbbreviation = false,
4000
- completedExecutionLogMerging = false,
3999
+ logShortForCompletedExecutions = false,
4000
+ logMergeForCompletedExecutions = false,
4001
4001
  rootDirectoryUrl,
4002
4002
  webServer,
4003
4003
  testPlan,
@@ -4196,8 +4196,8 @@ const executeTestPlan = async ({
4196
4196
  logTimeUsage,
4197
4197
  logMemoryHeapUsage,
4198
4198
  logFileRelativeUrl,
4199
- completedExecutionLogMerging,
4200
- completedExecutionLogAbbreviation,
4199
+ logShortForCompletedExecutions,
4200
+ logMergeForCompletedExecutions,
4201
4201
  rootDirectoryUrl,
4202
4202
  webServer,
4203
4203
  maxExecutionsInParallel,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/test",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,8 +25,8 @@ export const executeSteps = async (
25
25
  logTimeUsage,
26
26
  logMemoryHeapUsage,
27
27
  logFileRelativeUrl,
28
- completedExecutionLogMerging,
29
- completedExecutionLogAbbreviation,
28
+ logMergeForCompletedExecutions,
29
+ logShortForCompletedExecutions,
30
30
  rootDirectoryUrl,
31
31
  webServer,
32
32
 
@@ -124,10 +124,10 @@ export const executeSteps = async (
124
124
  stopAfterAllSignal,
125
125
  }
126
126
 
127
- if (completedExecutionLogMerging && !process.stdout.isTTY) {
128
- completedExecutionLogMerging = false
127
+ if (logMergeForCompletedExecutions && !process.stdout.isTTY) {
128
+ logMergeForCompletedExecutions = false
129
129
  logger.debug(
130
- `Force completedExecutionLogMerging to false because process.stdout.isTTY is false`,
130
+ `Force logMergeForCompletedExecutions to false because process.stdout.isTTY is false`,
131
131
  )
132
132
  }
133
133
  const debugLogsEnabled = logger.levels.debug
@@ -273,7 +273,7 @@ export const executeSteps = async (
273
273
  }
274
274
  if (executionLogsEnabled) {
275
275
  const log = createExecutionLog(afterExecutionInfo, {
276
- completedExecutionLogAbbreviation,
276
+ logShortForCompletedExecutions,
277
277
  counters,
278
278
  logRuntime,
279
279
  logEachDuration,
@@ -292,7 +292,7 @@ export const executeSteps = async (
292
292
  rawOutput += stripAnsi(log)
293
293
 
294
294
  const canOverwriteLog = canOverwriteLogGetter({
295
- completedExecutionLogMerging,
295
+ logMergeForCompletedExecutions,
296
296
  executionResult,
297
297
  })
298
298
  if (canOverwriteLog) {
@@ -352,10 +352,10 @@ export const executeSteps = async (
352
352
  }
353
353
 
354
354
  const canOverwriteLogGetter = ({
355
- completedExecutionLogMerging,
355
+ logMergeForCompletedExecutions,
356
356
  executionResult,
357
357
  }) => {
358
- if (!completedExecutionLogMerging) {
358
+ if (!logMergeForCompletedExecutions) {
359
359
  return false
360
360
  }
361
361
  if (executionResult.status === "aborted") {
@@ -21,8 +21,8 @@ import { executeSteps } from "./execute_steps.js"
21
21
  * @param {string|url} testPlanParameters.rootDirectoryUrl Directory containing test files;
22
22
  * @param {Object} [testPlanParameters.webServer] Web server info; required when executing test on browsers
23
23
  * @param {Object} testPlanParameters.testPlan Object associating files with runtimes where they will be executed
24
- * @param {boolean} [testPlanParameters.completedExecutionLogAbbreviation=false] Abbreviate completed execution information to shorten terminal output
25
- * @param {boolean} [testPlanParameters.completedExecutionLogMerging=false] Merge completed execution logs to shorten terminal output
24
+ * @param {boolean} [testPlanParameters.logShortForCompletedExecutions=false] Abbreviate completed execution information to shorten terminal output
25
+ * @param {boolean} [testPlanParameters.logMergeForCompletedExecutions=false] Merge completed execution logs to shorten terminal output
26
26
  * @param {number} [testPlanParameters.maxExecutionsInParallel=1] Maximum amount of execution in parallel
27
27
  * @param {number} [testPlanParameters.defaultMsAllocatedPerExecution=30000] Milliseconds after which execution is aborted and considered as failed by timeout
28
28
  * @param {boolean} [testPlanParameters.failFast=false] Fails immediatly when a test execution fails
@@ -43,8 +43,8 @@ export const executeTestPlan = async ({
43
43
  logTimeUsage = false,
44
44
  logMemoryHeapUsage = false,
45
45
  logFileRelativeUrl = ".jsenv/test_plan_debug.txt",
46
- completedExecutionLogAbbreviation = false,
47
- completedExecutionLogMerging = false,
46
+ logShortForCompletedExecutions = false,
47
+ logMergeForCompletedExecutions = false,
48
48
 
49
49
  rootDirectoryUrl,
50
50
  webServer,
@@ -293,8 +293,8 @@ export const executeTestPlan = async ({
293
293
  logTimeUsage,
294
294
  logMemoryHeapUsage,
295
295
  logFileRelativeUrl,
296
- completedExecutionLogMerging,
297
- completedExecutionLogAbbreviation,
296
+ logShortForCompletedExecutions,
297
+ logMergeForCompletedExecutions,
298
298
  rootDirectoryUrl,
299
299
  webServer,
300
300
 
@@ -21,7 +21,7 @@ export const createExecutionLog = (
21
21
  endMs,
22
22
  },
23
23
  {
24
- completedExecutionLogAbbreviation,
24
+ logShortForCompletedExecutions,
25
25
  counters,
26
26
  logRuntime,
27
27
  logEachDuration,
@@ -43,7 +43,7 @@ export const createExecutionLog = (
43
43
  memoryHeap,
44
44
  })
45
45
  let log
46
- if (completedExecutionLogAbbreviation && status === "completed") {
46
+ if (logShortForCompletedExecutions && status === "completed") {
47
47
  log = `${description}${summary}`
48
48
  } else {
49
49
  const { consoleCalls = [], errors = [] } = executionResult
@@ -75,7 +75,7 @@ export const createExecutionLog = (
75
75
  wordWrap: false,
76
76
  })
77
77
  if (endMs) {
78
- if (completedExecutionLogAbbreviation) {
78
+ if (logShortForCompletedExecutions) {
79
79
  return `${log}\n`
80
80
  }
81
81
  if (executionIndex === counters.total - 1) {