@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 ADDED
@@ -0,0 +1,200 @@
1
+ # @jsenv/test [![npm package](https://img.shields.io/npm/v/@jsenv/test.svg?logo=npm&label=package)](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
+ ```
@@ -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.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.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",