@jsenv/test 1.0.0 → 1.0.1
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 +200 -0
- package/dist/jsenv_test.js +2 -0
- package/package.json +2 -2
package/README.md
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# @jsenv/test [](https://www.npmjs.com/package/@jsenv/test)
|
|
2
|
+
|
|
3
|
+
Executing test files in web browsers and/or Node.js.
|
|
4
|
+
This tool enforce test files to be written as **standard** files, without any sort of complexity.
|
|
5
|
+
|
|
6
|
+
# 1. Example
|
|
7
|
+
|
|
8
|
+
Let's see how to write tests for the following code
|
|
9
|
+
|
|
10
|
+
```js
|
|
11
|
+
// add.js
|
|
12
|
+
export const add = (a, b) => a + b
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## 1.1 Testing on web browser
|
|
16
|
+
|
|
17
|
+
```html
|
|
18
|
+
<!-- add.test.html -->
|
|
19
|
+
<!DOCTYPE html>
|
|
20
|
+
<html>
|
|
21
|
+
<head>
|
|
22
|
+
<title>Title</title>
|
|
23
|
+
<meta charset="utf-8" />
|
|
24
|
+
<link rel="icon" href="data:," />
|
|
25
|
+
</head>
|
|
26
|
+
|
|
27
|
+
<body>
|
|
28
|
+
<script type="module">
|
|
29
|
+
import { add } from "./add.js"
|
|
30
|
+
|
|
31
|
+
const actual = add(1, 2)
|
|
32
|
+
const expected = 3
|
|
33
|
+
if (actual !== expected) {
|
|
34
|
+
throw new Error(`add(1,2) should return 3, got ${actual}`)
|
|
35
|
+
}
|
|
36
|
+
</script>
|
|
37
|
+
</body>
|
|
38
|
+
</html>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## 1.2 Testing on Node.js
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
// add.test.mjs
|
|
45
|
+
import { add } from "./add.js"
|
|
46
|
+
|
|
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
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## 1.3 Assertion library
|
|
55
|
+
|
|
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.
|
|
58
|
+
|
|
59
|
+
```diff
|
|
60
|
+
+ import { assert } from "@jsenv/assert"
|
|
61
|
+
import { add } from "./add.js"
|
|
62
|
+
|
|
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 })
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
# 2. JavaScript API
|
|
72
|
+
|
|
73
|
+
## 2.1 Executing tests on browsers
|
|
74
|
+
|
|
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.
|
|
77
|
+
|
|
78
|
+
```js
|
|
79
|
+
import { executeTestPlan, chromium } from "@jsenv/test"
|
|
80
|
+
|
|
81
|
+
await executeTestPlan({
|
|
82
|
+
rootDirectoryUrl: new URL("../", import.meta.url),
|
|
83
|
+
testPlan: {
|
|
84
|
+
"./**/*.test.html": {
|
|
85
|
+
chromium: { runtime: chromium() },
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
webServer: {
|
|
89
|
+
origin: "http://localhost:3456",
|
|
90
|
+
rootDirectoryUrl: new URL("../src/", import.meta.url),
|
|
91
|
+
moduleUrl: new URL("./dev.mjs", import.meta.url),
|
|
92
|
+
},
|
|
93
|
+
})
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
When executing tests on browsers there is a few things to ensure:
|
|
97
|
+
|
|
98
|
+
1. `"playwright"` must be in package.json dependencies (`npm i playwright --save-dev`)
|
|
99
|
+
|
|
100
|
+
2. `webServer` parameter must be used:
|
|
101
|
+
|
|
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)` |
|
|
107
|
+
|
|
108
|
+
Test files must be inside `webServer.rootDirectoryUrl`:
|
|
109
|
+
|
|
110
|
+
<pre>
|
|
111
|
+
project/
|
|
112
|
+
src/
|
|
113
|
+
bar.js
|
|
114
|
+
<strong>bar.test.html</strong>
|
|
115
|
+
foo.js
|
|
116
|
+
<strong>foo.test.html</strong>
|
|
117
|
+
index.html
|
|
118
|
+
</pre>
|
|
119
|
+
|
|
120
|
+
It's also possible to create a directory dedicated to tests
|
|
121
|
+
|
|
122
|
+
<pre>
|
|
123
|
+
project/
|
|
124
|
+
src/
|
|
125
|
+
tests/
|
|
126
|
+
<strong>bar.test.html</strong>
|
|
127
|
+
<strong>foo.test.html</strong>
|
|
128
|
+
bar.js
|
|
129
|
+
foo.js
|
|
130
|
+
index.html
|
|
131
|
+
</pre>
|
|
132
|
+
|
|
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.
|
|
135
|
+
|
|
136
|
+
## 2.2 Executing on more browsers
|
|
137
|
+
|
|
138
|
+
```js
|
|
139
|
+
import { executeTestPlan, chromium, firefox, webkit } from "@jsenv/test"
|
|
140
|
+
|
|
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
|
+
})
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## 2.3 Executing tests on Node.js
|
|
159
|
+
|
|
160
|
+
With Node.js there is no server involved so test files can be anywhere and only rootDirectoryUrl and testPlan parameters are **required**.
|
|
161
|
+
|
|
162
|
+
```js
|
|
163
|
+
import { executeTestPlan, nodeWorkerThread } from "@jsenv/test"
|
|
164
|
+
|
|
165
|
+
await executeTestPlan({
|
|
166
|
+
rootDirectoryUrl: new URL("../", import.meta.url),
|
|
167
|
+
testPlan: {
|
|
168
|
+
"./tests/**/*.test.mjs": {
|
|
169
|
+
node: { runtime: nodeWorkerThread() },
|
|
170
|
+
},
|
|
171
|
+
},
|
|
172
|
+
})
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## 2.4 Allocated time
|
|
176
|
+
|
|
177
|
+
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.
|
|
179
|
+
This duration can be configured as shown below:
|
|
180
|
+
|
|
181
|
+
```js
|
|
182
|
+
import { executeTestPlan, nodeWorkerThread } from "@jsenv/test"
|
|
183
|
+
|
|
184
|
+
await executeTestPlan({
|
|
185
|
+
rootDirectoryUrl: new URL("../", import.meta.url),
|
|
186
|
+
testPlan: {
|
|
187
|
+
"./tests/**/*.test.mjs": {
|
|
188
|
+
node: { runtime: nodeWorkerThread(), allocatedMs: 60_000 },
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
})
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
☝️ Code above changes the default allocated time to 60s.
|
|
195
|
+
|
|
196
|
+
# 3. Installation
|
|
197
|
+
|
|
198
|
+
```console
|
|
199
|
+
npm install --save-dev @jsenv/test
|
|
200
|
+
```
|
package/dist/jsenv_test.js
CHANGED
|
@@ -2081,6 +2081,8 @@ ansiEscapes.clearTerminal = isWindows ? `${ansiEscapes.eraseScreen}${ESC}0f`
|
|
|
2081
2081
|
// 3. Moves cursor to the top-left position
|
|
2082
2082
|
// More info: https://www.real-world-systems.com/docs/ANSIcode.html
|
|
2083
2083
|
: `${ansiEscapes.eraseScreen}${ESC}3J${ESC}H`;
|
|
2084
|
+
ansiEscapes.enterAlternativeScreen = ESC + '?1049h';
|
|
2085
|
+
ansiEscapes.exitAlternativeScreen = ESC + '?1049l';
|
|
2084
2086
|
ansiEscapes.beep = BEL;
|
|
2085
2087
|
ansiEscapes.link = (text, url) => [OSC, '8', SEP, SEP, url, BEL, text, OSC, '8', SEP, SEP, BEL].join('');
|
|
2086
2088
|
ansiEscapes.image = (buffer, options = {}) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/test",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"playwright": "1.x"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@jsenv/core": "35.0.
|
|
36
|
+
"@jsenv/core": "35.0.1",
|
|
37
37
|
"@jsenv/abort": "4.2.4",
|
|
38
38
|
"@jsenv/ast": "3.0.6",
|
|
39
39
|
"@jsenv/filesystem": "4.2.3",
|