@jsenv/test 1.0.1 → 1.0.2

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,19 +3,45 @@
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. Example
6
+ # 1. Writing tests on web browsers
7
7
 
8
- Let's see how to write tests for the following code
8
+ This section demonstrates how to write a test that will be executed in a web browser.
9
+
10
+ The function that will be tested is inside "add.js" file:
9
11
 
10
12
  ```js
11
- // add.js
12
13
  export const add = (a, b) => a + b
13
14
  ```
14
15
 
15
- ## 1.1 Testing on web browser
16
+ The demonstration uses the following file structure:
17
+
18
+ <pre>
19
+ project/
20
+ src/
21
+ <strong>add.js</strong>
22
+ index.html
23
+ package.json
24
+ </pre>
25
+
26
+ At the end of the demo, the file structure will be like this:
27
+
28
+ <pre>
29
+ project/
30
+ scripts/
31
+ <strong>dev.mjs</strong>
32
+ <strong>test.mjs</strong>
33
+ src/
34
+ add.js
35
+ <strong>add.test.html</strong>
36
+ index.html
37
+ package.json
38
+ </pre>
39
+
40
+ ## 1.1 Writing the test file
41
+
42
+ *src/add.test.html*
16
43
 
17
44
  ```html
18
- <!-- add.test.html -->
19
45
  <!DOCTYPE html>
20
46
  <html>
21
47
  <head>
@@ -38,51 +64,80 @@ export const add = (a, b) => a + b
38
64
  </html>
39
65
  ```
40
66
 
41
- ## 1.2 Testing on Node.js
67
+ ## 1.2 Executing the test file
68
+
69
+ *scripts/dev.mjs*: will start a web server that is needed to executed "add.test.html" in a browser.
42
70
 
43
71
  ```js
44
- // add.test.mjs
45
- import { add } from "./add.js"
72
+ import { startDevServer } from "@jsenv/core"
46
73
 
47
- const actual = add(1, 2)
48
- const expected = 3
49
- if (actual !== expected) {
50
- throw new Error(`add(1,2) should return 3, got ${actual}`)
51
- }
74
+ await startDevServer({
75
+ sourceDirectoryUrl: new URL("../src/", import.meta.url),
76
+ port: 3456,
77
+ })
52
78
  ```
53
79
 
54
- ## 1.3 Assertion library
80
+ *scripts/test.mjs*: will start a web browser and use it to execute all test files.
55
81
 
56
- To keep example very basic "assert" block do not use an assertion library.
57
- In pratice test likely needs one. The diff below showns how the "assert" block can be written using [@jsenv/assert](../assert). Note that any other assertion library would work.
82
+ ```js
83
+ import { executeTestPlan, chromium } from "@jsenv/test"
58
84
 
59
- ```diff
60
- + import { assert } from "@jsenv/assert"
61
- import { add } from "./add.js"
85
+ await executeTestPlan({
86
+ rootDirectoryUrl: new URL("../", import.meta.url),
87
+ testPlan: {
88
+ "./src/**/*.test.html": {
89
+ chromium: {
90
+ runtime: chromium()
91
+ },
92
+ },
93
+ },
94
+ webServer: {
95
+ origin: "http://localhost:3456",
96
+ rootDirectoryUrl: new URL("../src/", import.meta.url),
97
+ moduleUrl: new URL("./dev.mjs", import.meta.url),
98
+ },
99
+ })
100
+ ```
62
101
 
63
- const actual = add(1, 2)
64
- const expected = 3
65
- - if (actual !== expected) {
66
- - throw new Error(`add(1,2) should return 3, got ${actual}`)
67
- - }
68
- + assert({ actual, expected })
102
+ Command to install dependencies:
103
+
104
+ ```console
105
+ npm i --save-dev @jsenv/core
106
+ npm i --save-dev @jsenv/test
107
+ npm i --save-dev playwright
69
108
  ```
70
109
 
71
- # 2. JavaScript API
110
+ ☝️ Playwright is used by `@jsenv/test` to start a web browser, see [playwright website](https://github.com/microsoft/playwright)<sup>↗</sup>.
72
111
 
73
- ## 2.1 Executing tests on browsers
112
+ Command to execute tests:
74
113
 
75
- Code below execute all files endings by `".test.html"` on chromium.
76
- [playwright](https://github.com/microsoft/playwright)<sup>↗</sup> is used to start a headless chromium.
114
+ ```console
115
+ node ./scripts/test.mjs
116
+ ```
117
+
118
+ ### 1.3 Executing on more browsers
77
119
 
78
120
  ```js
79
- import { executeTestPlan, chromium } from "@jsenv/test"
121
+ import {
122
+ executeTestPlan,
123
+ chromium,
124
+ firefox,
125
+ webkit,
126
+ } from "@jsenv/test"
80
127
 
81
128
  await executeTestPlan({
82
129
  rootDirectoryUrl: new URL("../", import.meta.url),
83
130
  testPlan: {
84
- "./**/*.test.html": {
85
- chromium: { runtime: chromium() },
131
+ "./src/**/*.test.html": {
132
+ chromium: {
133
+ runtime: chromium()
134
+ },
135
+ firefox: {
136
+ runtime: firefox()
137
+ },
138
+ webkit: {
139
+ runtime: webkit()
140
+ },
86
141
  },
87
142
  },
88
143
  webServer: {
@@ -93,71 +148,55 @@ await executeTestPlan({
93
148
  })
94
149
  ```
95
150
 
96
- When executing tests on browsers there is a few things to ensure:
151
+ ## 2. Writing tests on Node.js
97
152
 
98
- 1. `"playwright"` must be in package.json dependencies (`npm i playwright --save-dev`)
153
+ This section demonstrates how to write a test that will be executed in Node.js.
99
154
 
100
- 2. `webServer` parameter must be used:
155
+ The function that will be tested is inside "add.js" file:
101
156
 
102
- | Param | Description | Example |
103
- | -------------------------- | ------------------------------------------------- | --------------------------------------- |
104
- | webServer.origin | url listened by a web server | `"http://localhost:3456"` |
105
- | webServer.rootDirectoryUrl | url of directory served by the web server | `new URL("../src/", import.meta.url)` |
106
- | webServer.moduleUrl | url of the file responsible to start a web server | `new URL("./dev.mjs", import.meta.url)` |
157
+ ```js
158
+ export const add = (a, b) => a + b
159
+ ```
107
160
 
108
- Test files must be inside `webServer.rootDirectoryUrl`:
161
+ The demonstration uses the following file structure:
109
162
 
110
163
  <pre>
111
164
  project/
112
165
  src/
113
- bar.js
114
- <strong>bar.test.html</strong>
115
- foo.js
116
- <strong>foo.test.html</strong>
117
- index.html
166
+ <strong>add.js</strong>
167
+ package.json
118
168
  </pre>
119
169
 
120
- It's also possible to create a directory dedicated to tests
170
+ At the end of the demo, the file structure will be like this:
121
171
 
122
172
  <pre>
123
173
  project/
174
+ scripts/
175
+ <strong>test.mjs</strong>
124
176
  src/
125
- tests/
126
- <strong>bar.test.html</strong>
127
- <strong>foo.test.html</strong>
128
- bar.js
129
- foo.js
130
- index.html
177
+ add.js
178
+ tests/
179
+ <strong>add.test.mjs</strong>
180
+ package.json
131
181
  </pre>
132
182
 
133
- This way the web server can serve test files alongside with source files.
134
- It's best to configure `webServer` to lead to jsenv dev server but it does not have to; Any server serving files from a directory can be used.
183
+ ## 2.1 Writing the test file
135
184
 
136
- ## 2.2 Executing on more browsers
185
+ *add.test.mjs*
137
186
 
138
187
  ```js
139
- import { executeTestPlan, chromium, firefox, webkit } from "@jsenv/test"
188
+ import { add } from "./add.js"
140
189
 
141
- await executeTestPlan({
142
- rootDirectoryUrl: new URL("../", import.meta.url),
143
- testPlan: {
144
- "./src/**/*.test.html": {
145
- chromium: { runtime: chromium() },
146
- firefox: { runtime: firefox() },
147
- webkit: { runtime: webkit() },
148
- },
149
- },
150
- webServer: {
151
- origin: "http://localhost:3456",
152
- rootDirectoryUrl: new URL("../src/", import.meta.url),
153
- moduleUrl: new URL("./dev.mjs", import.meta.url),
154
- },
155
- })
190
+ const actual = add(1, 2)
191
+ const expected = 3
192
+ if (actual !== expected) {
193
+ throw new Error(`add(1,2) should return 3, got ${actual}`)
194
+ }
156
195
  ```
157
196
 
158
- ## 2.3 Executing tests on Node.js
197
+ ## 2.2 Executing the test file
159
198
 
160
- With Node.js there is no server involved so test files can be anywhere and only rootDirectoryUrl and testPlan parameters are **required**.
199
+ *scripts/test.mjs*
161
200
 
162
201
  ```js
163
202
  import { executeTestPlan, nodeWorkerThread } from "@jsenv/test"
@@ -166,26 +205,105 @@ await executeTestPlan({
166
205
  rootDirectoryUrl: new URL("../", import.meta.url),
167
206
  testPlan: {
168
207
  "./tests/**/*.test.mjs": {
169
- node: { runtime: nodeWorkerThread() },
208
+ node: {
209
+ runtime: nodeWorkerThread()
210
+ },
170
211
  },
171
212
  },
172
213
  })
173
214
  ```
174
215
 
175
- ## 2.4 Allocated time
216
+ Command to install dependencies:
217
+
218
+ ```console
219
+ npm i --save-dev @jsenv/test
220
+ ```
221
+
222
+ Command to execute tests:
223
+
224
+ ```console
225
+ node ./scripts/test.mjs
226
+ ```
227
+
228
+ ## 3. Assertion library
229
+
230
+ To have a basic example, the part of the code comparing `actual` and `expected` was done without an assertion library.
231
+ 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.
232
+
233
+ ```diff
234
+ + import { assert } from "@jsenv/assert"
235
+ import { add } from "./add.js"
236
+
237
+ const actual = add(1, 2)
238
+ const expected = 3
239
+ - if (actual !== expected) {
240
+ - throw new Error(`add(1,2) should return 3, got ${actual}`)
241
+ - }
242
+ + assert({ actual, expected })
243
+ ```
244
+
245
+ ## 4. API
246
+
247
+ ## 4.1 executeTestPlan
248
+
249
+ ```js
250
+ import { executeTestPlan } from "@jsenv/test"
251
+
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
255
+ })
256
+ report // contains many information about test executions
257
+ ```
258
+
259
+ ## 4.2 chromium/firefox/webkit
260
+
261
+ Params can be used to configure how the browser runtime is started
262
+
263
+ ```js
264
+ chromium({
265
+ headful: true // browser UI would be displayed while running tests
266
+ })
267
+ ```
268
+
269
+ ## 4.3 nodeWorkerThread/nodeChildProcess
270
+
271
+ Params can be used to configure how node child process or node worker thread is started.
272
+ Both runtime share the same arguments.
273
+
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
+ ```
286
+
287
+ ## 4.4 Allocated time
176
288
 
177
289
  Each file is given 30s to execute.
178
- If this duration is exceeded the browser tab (or node process/worker thread) is closed and executiong is considered as failed.
290
+ If this duration is exceeded the browser tab (or node process/worker thread) is closed and execution is considered as failed.
179
291
  This duration can be configured as shown below:
180
292
 
181
293
  ```js
182
- import { executeTestPlan, nodeWorkerThread } from "@jsenv/test"
294
+ import {
295
+ executeTestPlan,
296
+ nodeWorkerThread
297
+ } from "@jsenv/test"
183
298
 
184
299
  await executeTestPlan({
185
300
  rootDirectoryUrl: new URL("../", import.meta.url),
186
301
  testPlan: {
187
302
  "./tests/**/*.test.mjs": {
188
- node: { runtime: nodeWorkerThread(), allocatedMs: 60_000 },
303
+ node: {
304
+ runtime: nodeWorkerThread(),
305
+ allocatedMs: 60_000
306
+ },
189
307
  },
190
308
  },
191
309
  })
@@ -193,8 +311,4 @@ await executeTestPlan({
193
311
 
194
312
  ☝️ Code above changes the default allocated time to 60s.
195
313
 
196
- # 3. Installation
197
314
 
198
- ```console
199
- npm install --save-dev @jsenv/test
200
- ```
@@ -4505,7 +4505,7 @@ const createRuntimeUsingPlaywright = ({
4505
4505
  stopOnExit: true,
4506
4506
  playwrightLaunchOptions: {
4507
4507
  ...playwrightLaunchOptions,
4508
- headless: !headful
4508
+ headless: headful === undefined ? !keepRunning : !headful
4509
4509
  }
4510
4510
  });
4511
4511
  if (browser._initializer.version) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/test",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -83,7 +83,7 @@ export const createRuntimeUsingPlaywright = ({
83
83
  stopOnExit: true,
84
84
  playwrightLaunchOptions: {
85
85
  ...playwrightLaunchOptions,
86
- headless: !headful,
86
+ headless: headful === undefined ? !keepRunning : !headful,
87
87
  },
88
88
  })
89
89
  if (browser._initializer.version) {