polendina 3.3.2 → 3.3.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.
Files changed (43) hide show
  1. package/.github/dependabot.yml +1 -130
  2. package/.github/workflows/test-and-release.yml +1 -3
  3. package/AGENTS.md +81 -49
  4. package/CHANGELOG.md +12 -0
  5. package/README.md +11 -0
  6. package/lib/puppeteer.js +4 -36
  7. package/lib/webpack.config.js +5 -2
  8. package/package.json +3 -4
  9. package/polendina-cli.js +0 -6
  10. package/polendina.js +1 -1
  11. package/resources/common-run.js +0 -3
  12. package/resources/mocha-run.js +1 -6
  13. package/test/common.js +27 -10
  14. package/test/consumer/package.json +11 -0
  15. package/test/fixtures/bare-async/package.json +1 -14
  16. package/test/fixtures/bare-async-esm/package.json +2 -15
  17. package/test/fixtures/bare-async-failure/package.json +1 -14
  18. package/test/fixtures/bare-async-failure-esm/package.json +2 -15
  19. package/test/fixtures/bare-sync/package.json +1 -14
  20. package/test/fixtures/bare-sync-esm/package.json +2 -15
  21. package/test/fixtures/bare-sync-failure/package.json +1 -14
  22. package/test/fixtures/bare-sync-failure-esm/package.json +2 -15
  23. package/test/fixtures/mocha/fixture.txt +1 -0
  24. package/test/fixtures/mocha/package.json +1 -15
  25. package/test/fixtures/mocha/test-1.js +4 -0
  26. package/test/fixtures/mocha-esm/fixture.txt +1 -0
  27. package/test/fixtures/mocha-esm/package.json +2 -16
  28. package/test/fixtures/mocha-esm/test-1.js +5 -0
  29. package/test/fixtures/mocha-failure/package.json +1 -15
  30. package/test/fixtures/mocha-failure-esm/package.json +2 -16
  31. package/test/fixtures/tape/package.json +1 -14
  32. package/test/fixtures/tape-esm/package.json +2 -15
  33. package/test/fixtures/tape-failure/package.json +1 -14
  34. package/test/fixtures/tape-failure-esm/package.json +2 -15
  35. package/test/fixtures/webpack-merge/package.json +1 -14
  36. package/test/setup.js +96 -0
  37. package/test/test-bare-async.js +14 -18
  38. package/test/test-bare-sync.js +14 -18
  39. package/test/test-mocha.js +28 -27
  40. package/test/test-packed-install.js +29 -69
  41. package/test/test-polendina-node.js +11 -21
  42. package/test/test-tape.js +14 -18
  43. package/test/test-webpack-merge.js +4 -8
@@ -17,138 +17,9 @@ updates:
17
17
  include: 'scope'
18
18
 
19
19
  - package-ecosystem: 'npm'
20
- directory: '/test/fixtures/bare-async'
20
+ directory: '/test/consumer'
21
21
  schedule:
22
22
  interval: 'daily'
23
23
  commit-message:
24
24
  prefix: 'chore'
25
25
  include: 'scope'
26
-
27
- - package-ecosystem: 'npm'
28
- directory: '/test/fixtures/bare-async-esm'
29
- schedule:
30
- interval: 'daily'
31
- commit-message:
32
- prefix: 'chore'
33
- include: 'scope'
34
-
35
- - package-ecosystem: 'npm'
36
- directory: '/test/fixtures/bare-async-failure'
37
- schedule:
38
- interval: 'daily'
39
- commit-message:
40
- prefix: 'chore'
41
- include: 'scope'
42
-
43
- - package-ecosystem: 'npm'
44
- directory: '/test/fixtures/bare-async-failure-esm'
45
- schedule:
46
- interval: 'daily'
47
- commit-message:
48
- prefix: 'chore'
49
- include: 'scope'
50
-
51
- - package-ecosystem: 'npm'
52
- directory: '/test/fixtures/bare-sync'
53
- schedule:
54
- interval: 'daily'
55
- commit-message:
56
- prefix: 'chore'
57
- include: 'scope'
58
-
59
- - package-ecosystem: 'npm'
60
- directory: '/test/fixtures/bare-sync-esm'
61
- schedule:
62
- interval: 'daily'
63
- commit-message:
64
- prefix: 'chore'
65
- include: 'scope'
66
-
67
- - package-ecosystem: 'npm'
68
- directory: '/test/fixtures/bare-sync-failure'
69
- schedule:
70
- interval: 'daily'
71
- commit-message:
72
- prefix: 'chore'
73
- include: 'scope'
74
-
75
- - package-ecosystem: 'npm'
76
- directory: '/test/fixtures/bare-sync-failure-esm'
77
- schedule:
78
- interval: 'daily'
79
- commit-message:
80
- prefix: 'chore'
81
- include: 'scope'
82
-
83
- - package-ecosystem: 'npm'
84
- directory: '/test/fixtures/mocha'
85
- schedule:
86
- interval: 'daily'
87
- commit-message:
88
- prefix: 'chore'
89
- include: 'scope'
90
-
91
- - package-ecosystem: 'npm'
92
- directory: '/test/fixtures/mocha-esm'
93
- schedule:
94
- interval: 'daily'
95
- commit-message:
96
- prefix: 'chore'
97
- include: 'scope'
98
-
99
- - package-ecosystem: 'npm'
100
- directory: '/test/fixtures/mocha-failure'
101
- schedule:
102
- interval: 'daily'
103
- commit-message:
104
- prefix: 'chore'
105
- include: 'scope'
106
-
107
- - package-ecosystem: 'npm'
108
- directory: '/test/fixtures/mocha-failure-esm'
109
- schedule:
110
- interval: 'daily'
111
- commit-message:
112
- prefix: 'chore'
113
- include: 'scope'
114
-
115
- - package-ecosystem: 'npm'
116
- directory: '/test/fixtures/tape'
117
- schedule:
118
- interval: 'daily'
119
- commit-message:
120
- prefix: 'chore'
121
- include: 'scope'
122
-
123
- - package-ecosystem: 'npm'
124
- directory: '/test/fixtures/tape-esm'
125
- schedule:
126
- interval: 'daily'
127
- commit-message:
128
- prefix: 'chore'
129
- include: 'scope'
130
-
131
- - package-ecosystem: 'npm'
132
- directory: '/test/fixtures/tape-failure'
133
- schedule:
134
- interval: 'daily'
135
- commit-message:
136
- prefix: 'chore'
137
- include: 'scope'
138
-
139
- - package-ecosystem: 'npm'
140
- directory: '/test/fixtures/tape-failure-esm'
141
- schedule:
142
- interval: 'daily'
143
- commit-message:
144
- prefix: 'chore'
145
- include: 'scope'
146
-
147
- - package-ecosystem: 'npm'
148
- directory: '/test/fixtures/webpack-merge'
149
- schedule:
150
- interval: 'daily'
151
- commit-message:
152
- prefix: 'chore'
153
- include: 'scope'
154
-
@@ -19,9 +19,7 @@ jobs:
19
19
  run: |
20
20
  npm install --no-progress
21
21
  - name: Run tests
22
- run: |
23
- npm config set script-shell bash
24
- npm test
22
+ run: npm test
25
23
  release:
26
24
  name: Release
27
25
  needs: test
package/AGENTS.md CHANGED
@@ -65,6 +65,9 @@ Real usage, in increasing order of involvement. Each shape must keep working:
65
65
  - `polendina --runner=bare-async test/test.js` paired with
66
66
  `polendina-node bare-async test/test.js`. The same files run in Node.js and
67
67
  the browser with no test framework at all.
68
+ - `import hex from '!!raw-loader!./fixtures/block.hex'` inside a test to read a
69
+ fixture as a string. Binary and hex fixture suites do this, declaring no
70
+ loader of their own.
68
71
  - `polendina --cleanup --webpack-config test/webpack.config.js test/test-*.js`
69
72
  where the config is `export default { externals: { standard: 'null' } }`.
70
73
  `js-ipld-schema` does this to stop webpack bundling a Node-only
@@ -102,8 +105,9 @@ Files:
102
105
  `index.html` and `page-run.js` are served static. `common-run.js`,
103
106
  `test-registry.cjs` and one of `mocha-run.js`, `tape-run.js`, `bare-run.js`
104
107
  are bundled as the last entry.
105
- - `test/` runs the CLI against `test/fixtures/*`, one real standalone package
106
- per runner, in CJS and ESM, passing and failing.
108
+ - `test/` packs polendina, installs it into temporary consumers outside the
109
+ repo, one per runner, and runs the CLI against `test/fixtures/*` from
110
+ inside them, one fixture per runner, in CJS and ESM, passing and failing.
107
111
 
108
112
  ### The deferral trick
109
113
 
@@ -132,9 +136,13 @@ believing it.
132
136
 
133
137
  Things that look wrong and are not. Each exists because something broke.
134
138
 
135
- - **`resolve.modules` and `resolveLoader.modules` list `process.cwd()` first,
136
- polendina's `node_modules` second.** The consumer's mocha, tape and chai must
137
- win. polendina has no mocha or tape in its own tree, on purpose.
139
+ - **`resolve.modules` and `resolveLoader.modules` list the relative
140
+ `node_modules` first, polendina's own `node_modules` second.** The relative
141
+ entry walks up from the requesting file as Node does, so the consumer's
142
+ mocha, tape and chai win and hoisted or nested dependencies resolve from a
143
+ workspace package or any subdirectory. An absolute `cwd/node_modules` here
144
+ does not walk and breaks both. polendina has no mocha or tape in its own
145
+ tree, on purpose.
138
146
  - **Tape gets `resolve.fallback` for `stream` and `path`, `fs: false`, and
139
147
  `ProvidePlugin({ process })`.** Webpack 5 dropped Node core polyfills.
140
148
  Mocha's browser bundle is self-contained; tape's is not. `process`,
@@ -144,8 +152,13 @@ Things that look wrong and are not. Each exists because something broke.
144
152
  `polendina/node_modules` directory.
145
153
  - **`import 'mocha/mocha.js'` for side effect, then `globalThis.mocha`.**
146
154
  Mocha 11 ships UMD, 12 ships ESM. The global is the common denominator.
147
- Both are supported at once. The `color()` / `useColors()` branch is the
148
- same idea for older mochas.
155
+ Both are supported at once.
156
+ - **`raw-loader` is a dependency that no polendina source references.**
157
+ Consumers load fixture files as text with
158
+ `import hex from '!!raw-loader!./fixtures/block.hex'` and declare nothing; the
159
+ loader resolves from polendina's tree through `resolveLoader.modules`. The
160
+ mocha fixtures assert it. Removing it or the second `resolveLoader` entry
161
+ breaks those consumers.
149
162
  - **`exprContextCritical: false`.** Mocha's bundle has a dynamic
150
163
  `require.resolve`; without this every run prints a webpack warning.
151
164
  - **`resolve.tsconfig: false`.** Webpack 5.109+ on Node 22.6+ follows a
@@ -155,9 +168,8 @@ Things that look wrong and are not. Each exists because something broke.
155
168
  forward-slashed.** Tests in subdirectories and Windows paths both broke the
156
169
  cwd-relative version. Three separate fixes landed here. Paths in
157
170
  `wrap-loader.cjs` are the most common regression site in the repo.
158
- - **`puppeteer.launch({ args: ['--no-sandbox'], headless: 'new' })`.**
159
- `--no-sandbox` for root in Docker and CI. `'new'` was a Puppeteer 20
160
- deprecation fix and is itself a candidate for removal on current Puppeteer.
171
+ - **`puppeteer.launch({ args: ['--no-sandbox'] })`.** `--no-sandbox` for
172
+ root in Docker and CI. Headless is Puppeteer's default and is not named.
161
173
  - **`st({ cache: false })`.** A stale cached bundle between page, worker and
162
174
  serviceworker runs on Windows.
163
175
  - **`setTimeout(...).unref()` for `--timeout`.** A clean finish must not be
@@ -167,12 +179,22 @@ Things that look wrong and are not. Each exists because something broke.
167
179
  enumeration would otherwise see the wrong keys.
168
180
  - **`polendina-cli` exits with the mocha failure count; `polendina-node` exits
169
181
  0 or 1.** The first matches mocha's own behaviour. Keep both.
170
- - **`test:install` is a bash loop that `npm i`s every fixture with
171
- `--no-package-lock`, and CI sets `script-shell bash` for Windows.** Each
172
- fixture is a real package with its own devDependencies so the suite proves
173
- fence one. mocha and tape must never become devDependencies of the root
174
- package: they would land in polendina's `node_modules` and silently mask a
175
- broken consumer resolve. `test:run` uses `npx mocha` for the same reason.
182
+ - **The test frameworks live in `test/consumer/package.json`, not the root
183
+ package, and `test:run` uses `npx --yes mocha`.** mocha and tape must never
184
+ become devDependencies of the root package: they would land in polendina's
185
+ `node_modules` and silently mask a broken consumer resolve. That file is
186
+ the one place dependabot bumps them; it is never installed as is. The flag,
187
+ not an `npm_config_yes=` prefix, because npm scripts run under cmd.exe on
188
+ Windows and a `VAR=value` prefix is not a command there.
189
+ - **One consumer per runner, never one consumer with every framework.** Tape
190
+ and polendina both depend on `readable-stream`. Installed together with
191
+ mocha, npm nests whichever versions clash and the fixtures run on a tree no
192
+ real consumer has. Each consumer installs only what its runner's fixtures
193
+ import.
194
+ - **Fixture `package.json` files declare only a name and, for ESM, a
195
+ `type`.** Their dependencies come from the consumer they are copied into.
196
+ The webpack-merge fixture's config `require('webpack')` finds the hoisted
197
+ copy there, as a real consumer's would.
176
198
  - **`test/common.js` asserts empty stderr on success and always passes
177
199
  `--cleanup`.** Any stray warning is a test failure. Fixtures stay clean
178
200
  between runs only because of the flag.
@@ -212,14 +234,23 @@ green matrix is a Node.js interop issue, not a flaky test.
212
234
  ## Testing polendina itself
213
235
 
214
236
  ```bash
215
- npm test # lint, install fixtures, run the matrix (slow)
216
- npm run test:install # once, after a fixture package.json changes
217
- npx mocha test/test-mocha.js # one runner's suite
218
- npx mocha test/test-packed-install.js # the real install layout, needs a warm npm cache
219
- cd test/fixtures/mocha && ../../../polendina-cli.js --cleanup test-*.js # by hand
220
- cd test/fixtures/mocha && ../../../polendina-cli.js test-*.js --stats # keep build/ to inspect
237
+ npm test # lint and the whole matrix
238
+ npx mocha --require test/setup.js test/test-mocha.js # one runner's suite
239
+ POLENDINA_KEEP_CONSUMERS=1 npx mocha --require test/setup.js test/test-tape.js # keep the consumers to poke at
240
+ cd test/fixtures/mocha && ../../../polendina-cli.js test-*.js --stats # by hand, in-repo layout, keep build/
221
241
  ```
222
242
 
243
+ `test/setup.js` is a mocha global fixture. It packs the working tree, writes
244
+ a `package.json` per consumer, installs the tarball with that consumer's
245
+ frameworks into a temporary directory, copies `test/fixtures` in, and removes
246
+ everything afterwards. Its `variants` table maps a consumer name to the
247
+ packages it installs: `mocha` and `bare` take chai, `tape` takes tape,
248
+ `mocha11` pins the previous mocha major. Bare names take their version range
249
+ from `test/consumer/package.json`. Each suite names the consumer it runs in
250
+ when it calls `runCli`. The installs run in parallel from the npm cache with
251
+ the Chrome that puppeteer already downloaded for the root install, so they
252
+ need a warm cache and take well under a minute.
253
+
223
254
  ### Install topologies
224
255
 
225
256
  polendina resolves modules two ways at once: Node resolution for its own
@@ -230,30 +261,34 @@ test setup covers all three cases.
230
261
 
231
262
  | Topology | polendina's own `node_modules` | What it hides |
232
263
  |----------|-------------------------------|---------------|
233
- | Fixtures in this repo | The dev tree, two directories up | Fixtures can walk up and find polendina's dev dependencies. A missing fixture dependency, or any package added to the root, is silently masked. This is why mocha and tape must never be root dependencies. |
264
+ | Fixtures run in this repo by hand | The dev tree, two directories up | Fixtures can walk up and find polendina's dev dependencies. A missing dependency, or any package added to the root, is silently masked. Fine for poking at a bundle, proves nothing about resolution. |
234
265
  | Symlinked working copy in a consumer | polendina's own full tree, separate from the consumer's | Two complete trees, no hoisting, no version contention. Cleaner than any real install. Will not reproduce a hoisting break. |
235
- | Published install in a consumer | Mostly absent: dependencies are hoisted into the consumer's flat tree | Anything that assumes a file exists under `polendina/node_modules/` breaks. Version conflicts between polendina's dependencies and the consumer's resolve by npm nesting and are then found by `resolve.modules` in whichever order npm left them. This is reality. |
266
+ | Published install in a consumer | Mostly absent: dependencies are hoisted into the consumer's flat tree | Anything that assumes a file exists under `polendina/node_modules/` breaks. Version conflicts between polendina's dependencies and the consumer's resolve by npm nesting and are then found by `resolve.modules` in whichever order npm left them. This is reality, and it is what the suite runs in. |
236
267
 
237
268
  Consequences:
238
269
 
239
- - A resolution change passing the fixture suite proves little on its own.
240
- `test/test-packed-install.js` covers the published layout for tape and
241
- mocha; extend it when a change touches resolution.
242
270
  - Never reference polendina's own `node_modules` by path. Resolve through
243
271
  Node from a file inside polendina so it works wherever npm put the package.
244
- - The `webpack-merge` fixture resolves `webpack` by walking up to polendina's
245
- tree, which stands in for a real consumer with no webpack of their own.
246
- That is the fixture topology leaking, and it happens to match reality
247
- because webpack is hoisted.
272
+ - The fixtures sit in a subdirectory of the consumer, so the suite also
273
+ stands in for a workspace package whose dependencies are hoisted to a
274
+ parent. Module resolution must walk up.
275
+ - `test/test-packed-install.js` asserts the layout itself: polendina's
276
+ dependencies hoisted, each framework present only in its own consumer,
277
+ mocha and tape absent from polendina's own tree.
248
278
 
249
279
  Rules the suite relies on:
250
280
 
251
- - polendina is tested the way it is used: as a CLI run from inside a consumer
252
- directory. Do not import `polendina.js` into tests to make them faster.
253
- - Fixture `package.json` files are real and own their test framework.
281
+ - polendina is tested the way it is used: as a CLI installed from a tarball
282
+ and run from inside a consumer directory. Do not import `polendina.js` into
283
+ tests to make them faster.
284
+ - The mocha spec reporter's pass symbol differs between majors in the
285
+ browser bundle, so mocha expectations take the tick from a per-consumer
286
+ table rather than a literal.
254
287
  - Every runner has a passing and a failing fixture, in CJS and ESM. A new
255
- runner or mode adds all four. A new code path in an existing runner adds an
256
- assertion to the existing fixtures rather than a new fixture.
288
+ runner or mode adds all four, a row in `variants` with its framework, and
289
+ that framework in `test/consumer/package.json`. A new code path in an
290
+ existing runner adds an assertion to the existing fixtures rather than a
291
+ new fixture.
257
292
  - Expected output is matched as exact multi-line strings with timings
258
293
  scrubbed. When output changes on purpose, update the expectation and say so
259
294
  in the PR.
@@ -288,19 +323,16 @@ Good work, roughly in order of value:
288
323
 
289
324
  - **Keep the matrix green.** Pick up a red dependabot PR, find the fallout,
290
325
  land the fix with the bump. This is the single most useful thing.
291
- - **Remove dead weight with evidence.** `raw-loader` is a dependency no source
292
- references. The `--coverage` flag and the `pti` TODO have never shipped. The
293
- commented-out `page.on('console')` block is dead. The `useColors` branch is
294
- unreachable on supported mochas. Each removal is one PR with a full test run
295
- and a `git log -S` showing where it came from.
296
- - **Move the fixtures into the packed consumer.** `test/test-packed-install.js`
297
- already packs polendina and installs it into a temporary consumer outside
298
- the repo, the only layout a real user has. Running the existing fixture
299
- directories from inside that consumer would replace seventeen `npm i` runs
300
- and seventeen dependabot entries with one install, close the topology leak
301
- for every test, and make a second consumer on the previous mocha major
302
- cheap. The fixtures and their assertions stay as they are; only where they
303
- run changes.
326
+ - **Remove dead weight with evidence.** A flag that never shipped, a branch
327
+ unreachable on supported versions. Each removal is one PR with a full test
328
+ run and a `git log -S` showing where it came from. A dependency with no
329
+ reference in this repo is not evidence on its own: `raw-loader` is used
330
+ only from consumers' inline loader strings. Search the consumers first.
331
+ - **Make dynamic `import()` work in Worker and ServiceWorker modes.** Webpack
332
+ splits each one into a chunk and loads it through a script tag, which only
333
+ a page has. `module.parser.javascript.dynamicImportMode: 'eager'` would
334
+ inline them into the single bundle; the mocha fixtures' raw-loader case
335
+ would then pass as a dynamic import in all three scopes.
304
336
  - **Make failures legible.** When a resolve fails inside a consumer's
305
337
  dependency, the webpack error is the user's only clue. Better messages
306
338
  around bundle errors and the timeout are cheap wins.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## [3.3.4](https://github.com/rvagg/polendina/compare/v3.3.3...v3.3.4) (2026-10-24)
2
+
3
+ ### Trivial Changes
4
+
5
+ * remove dead code, document and test raw-loader ([#206](https://github.com/rvagg/polendina/issues/206)) ([3ce94c0](https://github.com/rvagg/polendina/commit/3ce94c02208d72e8c174d6607bc30266e2ad69aa))
6
+
7
+ ## [3.3.3](https://github.com/rvagg/polendina/compare/v3.3.2...v3.3.3) (2026-10-24)
8
+
9
+ ### Tests
10
+
11
+ * run fixtures from a packed install in temporary consumers ([#205](https://github.com/rvagg/polendina/issues/205)) ([d1601fc](https://github.com/rvagg/polendina/commit/d1601fcc94b50bb6192629173500b85443a405f2))
12
+
1
13
  ## [3.3.2](https://github.com/rvagg/polendina/compare/v3.3.1...v3.3.2) (2026-10-24)
2
14
 
3
15
  ### Bug Fixes
package/README.md CHANGED
@@ -20,6 +20,7 @@
20
20
  * [bare-sync](#bare-sync)
21
21
  * [bare-async](#bare-async)
22
22
  * [TypeScript support (and other Webpack extensions)](#typescript-support-and-other-webpack-extensions)
23
+ * [Loading fixture files](#loading-fixture-files)
23
24
  * [polendina-node: the minimal Node.js test runner](#polendina-node-the-minimal-nodejs-test-runner)
24
25
  * [Minimising Puppeteer's size](#minimising-puppeteers-size)
25
26
  * [Global and npx](#global-and-npx)
@@ -187,6 +188,16 @@ module.exports = {
187
188
  $ polendina --cleanup test/*.spec.ts --webpack-config webpack.config.ts.js
188
189
  ```
189
190
 
191
+ ## Loading fixture files
192
+
193
+ polendina bundles [raw-loader](https://ghub.io/raw-loader) so a test can read a fixture file as a string without any configuration, using webpack's inline loader syntax:
194
+
195
+ ```js
196
+ import hex from '!!raw-loader!./fixtures/block.hex'
197
+ ```
198
+
199
+ The leading `!!` stops any other loader from touching the file. In a CommonJS test the string is on `require('!!raw-loader!./fixtures/block.hex').default`. A dynamic `import()` works too, but only in page mode: webpack loads it as a separate chunk through a script tag, which Workers and ServiceWorkers do not have.
200
+
190
201
 
191
202
  ## `polendina-node`: the minimal Node.js test runner
192
203
 
package/lib/puppeteer.js CHANGED
@@ -1,15 +1,12 @@
1
1
  import puppeteer from 'puppeteer'
2
- // TODO
3
- // const pti = require('puppeteer-to-istanbul')
4
- // const { copyFile } = require('fs').promises
5
2
  import { log, error, logRaw, logWrite, flushLogs } from './log.js'
6
3
 
7
4
  // wrap our convoluted _run() function in a pure Promise that can handle
8
5
  // both standard throws and the callback that ends it. _run() needs to handle
9
6
  // ends in a few different ways, hence the hack.
10
- export function run (outputDir, port, timeout, mode, runner, coverage) {
7
+ export function run (outputDir, port, timeout, mode, runner) {
11
8
  return new Promise((resolve, reject) => {
12
- _run(outputDir, port, timeout, mode, runner, coverage, (err, errors) => {
9
+ _run(outputDir, port, timeout, mode, runner, (err, errors) => {
13
10
  if (err) {
14
11
  return reject(err)
15
12
  }
@@ -21,10 +18,10 @@ export function run (outputDir, port, timeout, mode, runner, coverage) {
21
18
  // this can throw, or it can end via `callback()` which may or may not contain
22
19
  // a runtime-error argument and a "number of errors from tests" argument.
23
20
  // the callback may be triggered by proper test end or failure, or a timeout.
24
- async function _run (outputDir, port, timeout, mode, runner, coverage, callback) {
21
+ async function _run (outputDir, port, timeout, mode, runner, callback) {
25
22
  let executionQueue = Promise.resolve()
26
23
 
27
- const browser = await puppeteer.launch({ args: ['--no-sandbox'], headless: 'new' })
24
+ const browser = await puppeteer.launch({ args: ['--no-sandbox'] })
28
25
  const [page] = await browser.pages()
29
26
 
30
27
  // this works as a debounce exit method, when process.stdout.write() is used
@@ -44,13 +41,6 @@ async function _run (outputDir, port, timeout, mode, runner, coverage, callback)
44
41
  executionQueue.then(async () => {
45
42
  flushLogs(true)
46
43
  executionQueue = null
47
- /* TODO
48
- if (coverage) {
49
- const jsCoverage = await page.coverage.stopJSCoverage()
50
- pti.write([...jsCoverage])
51
- await copyFile('build/bundle.js.map', '.nyc_output/js/bundle.js.map')
52
- }
53
- */
54
44
  await browser.close()
55
45
  }).catch(callback)
56
46
  .then(() => { callback(null, errors) })
@@ -64,24 +54,6 @@ async function _run (outputDir, port, timeout, mode, runner, coverage, callback)
64
54
  }
65
55
  }
66
56
 
67
- // this should be a rare, or impossible event since we intercept console.log
68
- /*
69
- page.on('console', (msg) => {
70
- if (!executionQueue) {
71
- error(`log after end: ${msg.text()}`)
72
- return
73
- }
74
- const args = []
75
- executionQueue = executionQueue.then(async () => {
76
- logRaw('info', -1, await Promise.all(args))
77
- })
78
- for (const arg of msg.args()) {
79
- args.push(arg.evaluate(n => n))
80
- }
81
- maybeEnd()
82
- })
83
- */
84
-
85
57
  page.on('error', (error) => console.error(error))
86
58
  page.on('pageerror', (error) => console.error(error))
87
59
 
@@ -97,10 +69,6 @@ async function _run (outputDir, port, timeout, mode, runner, coverage, callback)
97
69
  maybeEnd()
98
70
  })
99
71
 
100
- if (coverage) {
101
- await page.coverage.startJSCoverage()
102
- }
103
-
104
72
  const url = `http://localhost:${port}/?mode=${mode}&runner=${runner}`
105
73
  log(`Running ${runner} ${mode} tests with Puppeteer via\n ${url}`)
106
74
  if (runner !== 'mocha') {
@@ -34,14 +34,17 @@ export function webpackConfig (env, options, runner) {
34
34
  // published deps; tsconfig-aware resolution follows it and fails every resolve
35
35
  // inside that dependency.
36
36
  tsconfig: false,
37
+ // the consumer's tree first, walking up from the requesting file as Node
38
+ // does so hoisted and nested dependencies resolve; polendina's own tree
39
+ // is only a fallback for its runner shims
37
40
  modules: [
38
- path.join(process.cwd(), 'node_modules'),
41
+ 'node_modules',
39
42
  path.join(__dirname, '../node_modules')
40
43
  ]
41
44
  },
42
45
  resolveLoader: {
43
46
  modules: [
44
- path.join(process.cwd(), 'node_modules'),
47
+ 'node_modules',
45
48
  path.join(__dirname, '../node_modules')
46
49
  ]
47
50
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "polendina",
3
- "version": "3.3.2",
3
+ "version": "3.3.4",
4
4
  "description": "Non-UI browser testing for JavaScript libraries from the command-line",
5
5
  "main": "polendina.js",
6
6
  "type": "module",
@@ -26,9 +26,8 @@
26
26
  },
27
27
  "scripts": {
28
28
  "lint": "standard",
29
- "test:install": "for f in $(cd test/fixtures/; ls); do (cd test/fixtures/$f && grep devDependencies package.json > /dev/null && npm i --no-audit --no-fund --no-package-lock) || true; done",
30
- "test:run": "npm_config_yes=true npx mocha test/test-*.js",
31
- "test": "npm run lint && npm run test:install && npm run test:run"
29
+ "test:run": "npx --yes mocha --require test/setup.js test/test-*.js",
30
+ "test": "npm run lint && npm run test:run"
32
31
  },
33
32
  "repository": {
34
33
  "type": "git",
package/polendina-cli.js CHANGED
@@ -52,12 +52,6 @@ const argv = yargs(hideBin(process.argv))
52
52
  describe: 'Number of seconds to wait before auto-failing the test suite',
53
53
  default: 30
54
54
  })
55
- .option('coverage', {
56
- type: 'boolean',
57
- describe: 'Enable coverage reporting',
58
- default: false,
59
- hidden: true
60
- })
61
55
  .option('webpack-config', {
62
56
  type: 'string',
63
57
  describe: 'Supply a path to a webpack.config.js to merge into Polendina\'s Webpack config (use with caution)',
package/polendina.js CHANGED
@@ -132,7 +132,7 @@ export class Polendina {
132
132
  server.on('error', reject)
133
133
  server.listen(() => {
134
134
  const port = server.address().port
135
- puppeteer(this.outputDir, port, this._options.timeout, mode, this._options.runner, this._options.coverage)
135
+ puppeteer(this.outputDir, port, this._options.timeout, mode, this._options.runner)
136
136
  .then((errors) => {
137
137
  server.close(() => {
138
138
  if (this._options.runner !== 'mocha') {
@@ -26,12 +26,10 @@ export const log = {
26
26
  executionQueue(() => globalThis.polendinaLog(['info', logSeq++].concat(args)))
27
27
  return executionQueue
28
28
  },
29
- // TODO
30
29
  warn: (...args) => {
31
30
  executionQueue(() => globalThis.polendinaLog(['warn', logSeq++].concat(args)))
32
31
  return executionQueue
33
32
  },
34
- // TODO
35
33
  error: (...args) => {
36
34
  executionQueue(() => globalThis.polendinaLog(['error', logSeq++].concat(args)))
37
35
  return executionQueue
@@ -87,7 +85,6 @@ function setupLogging () {
87
85
  log.info.apply(null, args)
88
86
  }
89
87
 
90
- // TODO: differentiate
91
88
  console.warn = log.warn
92
89
  console.error = log.error
93
90
  }
@@ -8,12 +8,7 @@ import { registry, executionQueue, log, setup } from './common-run.js'
8
8
  async function runMocha () {
9
9
  const mochaLocal = globalThis.mocha
10
10
  mochaLocal.setup({ reporter: registry.argv.mochaReporter, ui: 'bdd' })
11
- // mocha@7 deprecated useColors()
12
- if (typeof mochaLocal.color === 'function') {
13
- mochaLocal.color(true)
14
- } else if (typeof mochaLocal.useColors === 'function') {
15
- mochaLocal.useColors(true)
16
- }
11
+ mochaLocal.color(true)
17
12
 
18
13
  // the well-behaved reporters, like spec, are easy to intercept
19
14
  mochaLocal.constructor.reporters.Base.consoleLog = log.info
package/test/common.js CHANGED
@@ -1,19 +1,37 @@
1
1
  import path from 'path'
2
2
  import assert from 'assert'
3
3
  import { execFile } from 'child_process'
4
- import { fileURLToPath } from 'url'
5
4
 
6
- const __dirname = fileURLToPath(path.dirname(import.meta.url))
7
- const cli = path.join(__dirname, '../polendina-cli.js')
5
+ // consumers installed by setup.js, one per runner, named by its variants table
6
+ export function consumers () {
7
+ return JSON.parse(process.env.POLENDINA_CONSUMERS)
8
+ }
9
+
10
+ export function consumer (name) {
11
+ const dir = consumers()[name]
12
+ if (!dir) {
13
+ throw new Error(`no consumer named ${name}`)
14
+ }
15
+ return dir
16
+ }
17
+
18
+ // runs the installed polendina CLI from inside a copied fixture directory;
19
+ // resolved at call time because consumers exist only once setup.js has run
20
+ export async function runCli (consumerName, fixture, args = []) {
21
+ const dir = consumer(consumerName)
22
+ const cli = path.join(dir, 'node_modules/polendina/polendina-cli.js')
23
+ return runCommand(cli, ['test*.js', 'test/test*.js', '--cleanup', ...args], path.join(dir, 'fixtures', fixture))
24
+ }
8
25
 
9
- export async function runCli (cwd, args) {
10
- return runCommand(`${cli} test*.js test/test*.js --cleanup ${args || ''}`, cwd)
26
+ export async function runNodeCli (consumerName, fixture, mode) {
27
+ const dir = consumer(consumerName)
28
+ const cli = path.join(dir, 'node_modules/polendina/polendina-node-cli.js')
29
+ return runCommand(cli, [mode, 'test*.js'], path.join(dir, 'fixtures', fixture))
11
30
  }
12
31
 
13
- export async function runCommand (command, cwd) {
32
+ export async function runCommand (script, args, cwd) {
14
33
  return new Promise((resolve, reject) => {
15
- const args = command.split(' ').filter(Boolean)
16
- execFile(process.execPath, args, { cwd }, (err, stdout, stderr) => {
34
+ execFile(process.execPath, [script, ...args], { cwd }, (err, stdout, stderr) => {
17
35
  const code = err ? err.code : 0
18
36
  if (!code) {
19
37
  try {
@@ -22,8 +40,7 @@ export async function runCommand (command, cwd) {
22
40
  return reject(e)
23
41
  }
24
42
  }
25
- const out = { stdout: stdout.toString(), stderr: stderr.toString(), code }
26
- resolve(out)
43
+ resolve({ stdout: stdout.toString(), stderr: stderr.toString(), code })
27
44
  })
28
45
  })
29
46
  }