polendina 0.2.0 → 1.1.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.
@@ -0,0 +1,58 @@
1
+ name: Test & Maybe Release
2
+ on: [push, pull_request]
3
+ jobs:
4
+ test:
5
+ strategy:
6
+ fail-fast: false
7
+ matrix:
8
+ node: [14.x, 16.x]
9
+ os: [macos-latest, ubuntu-latest, windows-latest]
10
+ runs-on: ${{ matrix.os }}
11
+ steps:
12
+ - name: Checkout Repository
13
+ uses: actions/checkout@v2.3.4
14
+ - name: Use Node.js ${{ matrix.node }}
15
+ uses: actions/setup-node@v2.4.0
16
+ with:
17
+ node-version: ${{ matrix.node }}
18
+ - name: Install Dependencies
19
+ run: |
20
+ npm install --no-progress
21
+ - name: Run tests
22
+ run: |
23
+ npm config set script-shell bash
24
+ npm test
25
+ release:
26
+ name: Release
27
+ needs: test
28
+ runs-on: ubuntu-latest
29
+ if: github.event_name == 'push' && github.ref == 'refs/heads/master'
30
+ steps:
31
+ - name: Checkout
32
+ uses: actions/checkout@v2.3.4
33
+ with:
34
+ fetch-depth: 0
35
+ - name: Setup Node.js
36
+ uses: actions/setup-node@v2.4.0
37
+ with:
38
+ node-version: 14
39
+ - name: Install dependencies
40
+ run: |
41
+ npm install --no-progress --no-package-lock --no-save
42
+ - name: Install plugins
43
+ run: |
44
+ npm install \
45
+ @semantic-release/commit-analyzer \
46
+ conventional-changelog-conventionalcommits \
47
+ @semantic-release/release-notes-generator \
48
+ @semantic-release/npm \
49
+ @semantic-release/github \
50
+ @semantic-release/git \
51
+ @semantic-release/changelog \
52
+ --no-progress --no-package-lock --no-save
53
+ - name: Release
54
+ env:
55
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
56
+ NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
57
+ run: npx semantic-release
58
+
package/CHANGELOG.md ADDED
@@ -0,0 +1,11 @@
1
+ ### [1.1.1](https://github.com/rvagg/polendina/compare/v1.1.0...v1.1.1) (2021-12-07)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * no build step for release ([b91faf0](https://github.com/rvagg/polendina/commit/b91faf08395e6f8bc44b21d02d94c2136bcac942))
7
+
8
+
9
+ ### Trivial Changes
10
+
11
+ * add auto-releases ([#17](https://github.com/rvagg/polendina/issues/17)) ([9e71246](https://github.com/rvagg/polendina/commit/9e71246667ba96d8253aa180271728b35e700b45))
package/README.md CHANGED
@@ -19,9 +19,10 @@
19
19
  * [Tape](#tape)
20
20
  * [bare-sync](#bare-sync)
21
21
  * [bare-async](#bare-async)
22
- * [`polendina-node`: the minimal Node.js test runner](#polendina-node-the-minimal-nodejs-test-runner)
22
+ * [TypeScript support (and other Webpack extensions)](#typescript-support-and-other-webpack-extensions)
23
+ * [polendina-node: the minimal Node.js test runner](#polendina-node-the-minimal-nodejs-test-runner)
23
24
  * [Minimising Puppeteer's size](#minimising-puppeteers-size)
24
- * [Global and `npx`](#global-and-npx)
25
+ * [Global and npx](#global-and-npx)
25
26
  * [License and Copyright](#license-and-copyright)
26
27
 
27
28
  ## What and why?
@@ -63,6 +64,7 @@ Even though polendina is intended for "non-UI" testing, your tests run in a stan
63
64
  * `--stats`: Write webpack-stats.json with bundle; written to the `output-dir` so will be removed if `--cleanup` is specified (default: "false")
64
65
  * `--cleanup`: Remove the `output-dir` after execution (default: "false")
65
66
  * `--timeout`: Number of seconds to wait before auto-failing the test suite (default: "30")
67
+ * `--webpack-config`: Supply a path to a webpack.config.js to merge into Polendina's Webpack config (use with caution)
66
68
  * `--mocha-reporter`: Specify the Mocha reporter if the test runner is Mocha (default: "spec")
67
69
 
68
70
  ## Examples
@@ -158,6 +160,34 @@ module.exports.testFail = async () => {
158
160
  }
159
161
  ```
160
162
 
163
+ ## TypeScript support (and other Webpack extensions)
164
+
165
+ Among other things, the `--webpack-config` option can be used to enable TypeScript support by mixing in the [ts-loader](https://ghub.io/ts-loader) package:
166
+
167
+ **webpack.config.ts.js**
168
+
169
+ ```js
170
+ module.exports = {
171
+ module: {
172
+ rules: [
173
+ {
174
+ test: /\.tsx?$/,
175
+ use: 'ts-loader',
176
+ exclude: /node_modules/
177
+ }
178
+ ]
179
+ }
180
+ resolve: {
181
+ extensions: ['.tsx', '.ts', '.js']
182
+ }
183
+ }
184
+ ```
185
+
186
+ ```sh
187
+ $ polendina --cleanup test/*.spec.ts --webpack-config webpack.config.ts.js
188
+ ```
189
+
190
+
161
191
  ## `polendina-node`: the minimal Node.js test runner
162
192
 
163
193
  polendina's `bare-sync` and `bare-async` modes run plain Node.js modules in the browser without the need for a test runner. But if you want to run these types of files in Node.js you may find it difficult to scale when you have many modules.
package/lib/puppeteer.js CHANGED
@@ -79,6 +79,9 @@ async function _run (outputDir, port, timeout, mode, runner, coverage, callback)
79
79
  maybeEnd()
80
80
  })
81
81
 
82
+ page.on('error', (error) => console.error(error))
83
+ page.on('pageerror', (error) => console.error(error))
84
+
82
85
  await page.exposeFunction('polendinaEnd', (errors) => {
83
86
  end(errors)
84
87
  })
@@ -2,10 +2,10 @@ const path = require('path')
2
2
  const glob = require('glob')
3
3
 
4
4
  module.exports = function (env, options, runner) {
5
- const bundleRun = path.resolve(options.outputDir, runner)
5
+ const bundleRun = path.normalize(path.resolve(options.outputDir, runner))
6
6
  const testFiles = options._.reduce((p, c) => {
7
7
  return p.concat(glob.sync(c, { absolute: true }))
8
- }, [])
8
+ }, []).map(path.normalize)
9
9
 
10
10
  // our globs may be fruitless
11
11
  if (!testFiles.length) {
@@ -16,6 +16,7 @@ module.exports = function (env, options, runner) {
16
16
 
17
17
  return {
18
18
  mode: 'development',
19
+ context: process.cwd(),
19
20
  entry: testFiles,
20
21
  output: {
21
22
  path: path.resolve(process.cwd(), options.outputDir),
@@ -27,18 +28,23 @@ module.exports = function (env, options, runner) {
27
28
  },
28
29
  resolve: {
29
30
  modules: [
30
- path.join(__dirname, '../node_modules'),
31
- path.join(process.cwd(), 'node_modules')
31
+ path.join(process.cwd(), 'node_modules'),
32
+ path.join(__dirname, '../node_modules')
32
33
  ]
33
34
  },
34
35
  resolveLoader: {
35
36
  modules: [
36
- path.join(__dirname, '../node_modules'),
37
- path.join(process.cwd(), 'node_modules')
37
+ path.join(process.cwd(), 'node_modules'),
38
+ path.join(__dirname, '../node_modules')
38
39
  ]
39
40
  },
40
41
  node: {
41
- fs: 'empty'
42
+ dgram: 'empty',
43
+ fs: 'empty',
44
+ net: 'empty',
45
+ tls: 'empty',
46
+ dns: 'empty',
47
+ child_process: 'empty'
42
48
  },
43
49
  module: {
44
50
  rules: [
@@ -19,10 +19,10 @@ loader.pitch = function pitch (remainingRequest) {
19
19
 
20
20
  // wrap the test in a function that is only called when we want it called
21
21
  return `
22
- const registry = require(${JSON.stringify(`!!${path.resolve(argv.outputDir, 'test-registry.js')}`)})
23
- registry.argv = JSON.parse('${JSON.stringify(argv)}')
22
+ const registry = require(${JSON.stringify(`!!${path.normalize(path.resolve(argv.outputDir, 'test-registry.js'))}`)})
23
+ registry.argv = JSON.parse(${JSON.stringify(JSON.stringify(argv))})
24
24
  registry.tests.push({
25
- name: JSON.parse('${JSON.stringify(path.relative(process.cwd(), remainingRequest))}'),
25
+ name: JSON.parse('${JSON.stringify(path.normalize(path.relative(process.cwd(), remainingRequest)))}'),
26
26
  load: () => { return require(${JSON.stringify(`!!${remainingRequest}`)}) }
27
27
  })
28
28
  `
package/package.json CHANGED
@@ -1,32 +1,30 @@
1
1
  {
2
2
  "name": "polendina",
3
- "version": "0.2.0",
3
+ "version": "1.1.1",
4
4
  "description": "Non-UI browser testing for JavaScript libraries from the command-line",
5
5
  "main": "polendina.js",
6
6
  "dependencies": {
7
7
  "ansi-colors": "^4.1.1",
8
8
  "glob": "^7.1.6",
9
- "puppeteer": "^2.0.0",
9
+ "puppeteer": "^5.2.1",
10
10
  "raw-loader": "^4.0.0",
11
+ "readable-stream": "^2.3.7",
11
12
  "rimraf": "^3.0.0",
12
13
  "st": "^2.0.0",
13
14
  "strip-ansi": "^6.0.0",
14
15
  "webpack": "^4.41.5",
16
+ "webpack-merge": "^4.2.2",
15
17
  "yargs": "^15.1.0"
16
18
  },
17
19
  "bin": {
18
20
  "polendina": "./polendina-cli.js",
19
21
  "polendina-node": "./polendina-node-cli.js"
20
22
  },
21
- "devDependencies": {
22
- "mocha": "^7.0.0",
23
- "standard": "^14.3.1",
24
- "tape": "^4.12.1"
25
- },
26
23
  "scripts": {
27
- "lint": "standard",
28
- "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); done",
29
- "test": "npm run lint && npm run test:install && mocha test/test-*.js"
24
+ "lint": "npx standard",
25
+ "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",
26
+ "test:run": "npx mocha test/test-*.js",
27
+ "test": "npm run lint && npm run test:install && npm run test:run"
30
28
  },
31
29
  "repository": {
32
30
  "type": "git",
@@ -43,5 +41,86 @@
43
41
  "test"
44
42
  ],
45
43
  "author": "Rod <rod@vagg.org> (http://r.va.gg/)",
46
- "license": "Apache-2.0"
44
+ "license": "Apache-2.0",
45
+ "release": {
46
+ "branches": [
47
+ "master"
48
+ ],
49
+ "plugins": [
50
+ [
51
+ "@semantic-release/commit-analyzer",
52
+ {
53
+ "preset": "conventionalcommits",
54
+ "releaseRules": [
55
+ {
56
+ "breaking": true,
57
+ "release": "major"
58
+ },
59
+ {
60
+ "revert": true,
61
+ "release": "patch"
62
+ },
63
+ {
64
+ "type": "feat",
65
+ "release": "minor"
66
+ },
67
+ {
68
+ "type": "fix",
69
+ "release": "patch"
70
+ },
71
+ {
72
+ "type": "chore",
73
+ "release": "patch"
74
+ },
75
+ {
76
+ "type": "docs",
77
+ "release": "patch"
78
+ },
79
+ {
80
+ "type": "test",
81
+ "release": "patch"
82
+ },
83
+ {
84
+ "scope": "no-release",
85
+ "release": false
86
+ }
87
+ ]
88
+ }
89
+ ],
90
+ [
91
+ "@semantic-release/release-notes-generator",
92
+ {
93
+ "preset": "conventionalcommits",
94
+ "presetConfig": {
95
+ "types": [
96
+ {
97
+ "type": "feat",
98
+ "section": "Features"
99
+ },
100
+ {
101
+ "type": "fix",
102
+ "section": "Bug Fixes"
103
+ },
104
+ {
105
+ "type": "chore",
106
+ "section": "Trivial Changes"
107
+ },
108
+ {
109
+ "type": "docs",
110
+ "section": "Trivial Changes"
111
+ },
112
+ {
113
+ "type": "test",
114
+ "section": "Tests"
115
+ }
116
+ ]
117
+ }
118
+ }
119
+ ],
120
+ "@semantic-release/changelog",
121
+ "@semantic-release/npm",
122
+ "@semantic-release/github",
123
+ "@semantic-release/git"
124
+ ]
125
+ }
47
126
  }
package/polendina-cli.js CHANGED
@@ -57,6 +57,11 @@ const argv = require('yargs')
57
57
  default: false,
58
58
  hidden: true
59
59
  })
60
+ .option('webpack-config', {
61
+ type: 'string',
62
+ describe: 'Supply a path to a webpack.config.js to merge into Polendina\'s Webpack config (use with caution)',
63
+ requiresArg: true
64
+ })
60
65
  .option('mocha-reporter', {
61
66
  type: 'string',
62
67
  describe: 'Specify the Mocha reporter',
package/polendina.js CHANGED
@@ -5,6 +5,7 @@ const http = require('http')
5
5
  const st = require('st')
6
6
  const rimraf = promisify(require('rimraf'))
7
7
  const webpack = promisify(require('webpack'))
8
+ const merge = require('webpack-merge')
8
9
  const puppeteer = require('./lib/puppeteer')
9
10
 
10
11
  class Polendina {
@@ -31,7 +32,12 @@ class Polendina {
31
32
  }
32
33
 
33
34
  async build () {
34
- const webpackConfig = require('./lib/webpack.config')(process.env, this._options, this._runnerModule)
35
+ let webpackConfig = require('./lib/webpack.config')(process.env, this._options, this._runnerModule)
36
+
37
+ if (this._options.webpackConfig) {
38
+ const userConfig = require(path.join(process.cwd(), this._options.webpackConfig))
39
+ webpackConfig = merge.smart(webpackConfig, userConfig)
40
+ }
35
41
 
36
42
  await fs.mkdir(this.outputDir, { recursive: true })
37
43
  const copyFiles = ['index.html', 'test-registry.js', 'page-run.js', 'common-run.js', this._runnerModule]
@@ -83,7 +89,12 @@ class Polendina {
83
89
  }
84
90
 
85
91
  _executeMode (mode) {
86
- const mount = st({ path: this.outputDir, index: 'index.html', url: '/' })
92
+ const mount = st({
93
+ path: this.outputDir,
94
+ index: 'index.html',
95
+ url: '/',
96
+ cache: false
97
+ })
87
98
  return new Promise((resolve, reject) => {
88
99
  const server = http.createServer((req, res) => {
89
100
  mount(req, res, () => {
@@ -1,28 +1,29 @@
1
- /* globals mocha Mocha */
2
-
3
1
  // in-browser setup and runner for Mocha, at end of bundle
4
2
 
5
- require('mocha/mocha.js')
3
+ const mochaExport = require('mocha/mocha.js')
6
4
  const { registry, executionQueue, log, setup } = require('./common-run')
7
5
 
8
6
  function runMocha () {
9
- mocha.setup({ reporter: registry.argv.mochaReporter, ui: 'bdd' })
7
+ // mocha@8 exports what we want, mocha@7 sets a global
8
+ const mochaLocal = global.mocha ? global.mocha : mochaExport
9
+ global._mocha = mochaLocal
10
+ mochaLocal.setup({ reporter: registry.argv.mochaReporter, ui: 'bdd' })
10
11
  // mocha@7 deprecated useColors()
11
- if (typeof mocha.color === 'function') {
12
- mocha.color(true)
13
- } else if (typeof mocha.useColors === 'function') {
14
- mocha.useColors(true)
12
+ if (typeof mochaLocal.color === 'function') {
13
+ mochaLocal.color(true)
14
+ } else if (typeof mochaLocal.useColors === 'function') {
15
+ mochaLocal.useColors(true)
15
16
  }
16
17
 
17
18
  // the well-behaved reporters, like spec, are easy to intercept
18
- Mocha.reporters.Base.consoleLog = log.info
19
+ mochaLocal.constructor.reporters.Base.consoleLog = log.info
19
20
 
20
21
  for (const mod of registry.tests) {
21
22
  mod.load()
22
23
  }
23
24
 
24
25
  let errors = 0
25
- mocha
26
+ mochaLocal
26
27
  .run((_errors) => { errors = _errors })
27
28
  .on('end', (...args) => {
28
29
  executionQueue(() => global.polendinaEnd(errors))
@@ -0,0 +1 @@
1
+ module.exports = 'polendina test'
@@ -0,0 +1,18 @@
1
+ {
2
+ "name": "fixture-mocha8",
3
+ "version": "1.0.0",
4
+ "description": "test-fixture",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "mocha test-*.js"
8
+ },
9
+ "author": "Rod <rod@vagg.org> (http://r.va.gg/)",
10
+ "license": "Apache-2.0",
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "https://github.com/rvagg/polendina.git"
14
+ },
15
+ "devDependencies": {
16
+ "mocha": "^8.0.0"
17
+ }
18
+ }
@@ -0,0 +1,14 @@
1
+ /* globals describe it */
2
+
3
+ const fixture = require('./')
4
+ const assert = require('assert')
5
+
6
+ describe('test suite 1', () => {
7
+ it('test case 1', () => {
8
+ assert.strictEqual(fixture, 'polendina test')
9
+ })
10
+
11
+ it('test case 2', () => {
12
+ assert.ok(true, 'all good')
13
+ })
14
+ })
@@ -0,0 +1,19 @@
1
+ /* globals describe it WorkerGlobalScope ServiceWorkerGlobalScope */
2
+
3
+ const assert = require('assert')
4
+
5
+ describe('test suite 2 - worker', () => {
6
+ if (typeof ServiceWorkerGlobalScope !== 'undefined' && global instanceof ServiceWorkerGlobalScope) {
7
+ it('is in serviceworker', () => {
8
+ assert.strictEqual(typeof ServiceWorkerGlobalScope, 'function')
9
+ })
10
+ } else if (typeof WorkerGlobalScope !== 'undefined' && global instanceof WorkerGlobalScope) {
11
+ it('is in worker', () => {
12
+ assert.strictEqual(typeof WorkerGlobalScope, 'function')
13
+ })
14
+ } else {
15
+ it('is not in worker', () => {
16
+ assert.strictEqual(typeof WorkerGlobalScope, 'undefined')
17
+ })
18
+ }
19
+ })
@@ -0,0 +1,14 @@
1
+ /* globals describe it */
2
+
3
+ const fixture = require('./')
4
+ const assert = require('assert')
5
+
6
+ describe('test suite 3', () => {
7
+ it('test case 1', () => {
8
+ assert.strictEqual(fixture, 'polendina test')
9
+ })
10
+
11
+ it('test case 2', () => {
12
+ assert.ok(true, 'all good')
13
+ })
14
+ })
@@ -13,6 +13,6 @@
13
13
  "url": "https://github.com/rvagg/polendina.git"
14
14
  },
15
15
  "devDependencies": {
16
- "tape": "^4.12.1"
16
+ "tape": "^5.0.1"
17
17
  }
18
18
  }
@@ -13,6 +13,6 @@
13
13
  "url": "https://github.com/rvagg/polendina.git"
14
14
  },
15
15
  "devDependencies": {
16
- "tape": "^4.12.1"
16
+ "tape": "^5.0.1"
17
17
  }
18
18
  }
@@ -0,0 +1 @@
1
+ module.exports = 'bare test fixture'
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "fixture-webpack-merge",
3
+ "version": "1.0.0",
4
+ "description": "test fixture",
5
+ "main": "index.js",
6
+ "scripts": {
7
+ "test": "node test.js"
8
+ },
9
+ "author": "Rod <rod@vagg.org> (http://r.va.gg/)",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/rvagg/polendina.git"
13
+ },
14
+ "license": "Apache-2.0"
15
+ }
@@ -0,0 +1,7 @@
1
+ const assert = require('assert')
2
+ const qs = require('querystring')
3
+
4
+ assert.strictEqual(typeof assert.ok, 'function')
5
+ console.log('assert.ok() is a function')
6
+ assert.strictEqual(typeof qs.parse, 'function')
7
+ console.log('querystring.parse() is a function')
@@ -0,0 +1,5 @@
1
+ module.exports = {
2
+ node: {
3
+ querystring: 'empty'
4
+ }
5
+ }
package/test/test-tape.js CHANGED
@@ -13,15 +13,15 @@ describe('basic tape', function () {
13
13
  TAP version 13
14
14
  # test suite 1
15
15
  # test case 1
16
- ok 1 should be equal
16
+ ok 1 should be strictly equal
17
17
  # test case 2
18
18
  ok 2 all good
19
19
  # test suite 2 - worker
20
20
  # is WORKER
21
- ok 3 should be equal
21
+ ok 3 should be strictly equal
22
22
  # test suite 3
23
23
  # test case 1
24
- ok 4 should be equal
24
+ ok 4 should be strictly equal
25
25
  # test case 2
26
26
  ok 5 all good
27
27
 
@@ -80,7 +80,7 @@ describe('failing tape', function () {
80
80
  TAP version 13
81
81
  # test suite 1 - worker
82
82
  # is WORKER
83
- ok 1 should be equal
83
+ ok 1 should be strictly equal
84
84
  # test suite 2 - failure
85
85
  # test case 1
86
86
  not ok 2 bork
@@ -0,0 +1,36 @@
1
+ /* globals describe it */
2
+
3
+ const assert = require('assert')
4
+ const path = require('path')
5
+ const { runCli } = require('./common')
6
+
7
+ const webpackMergeFixture = path.join(__dirname, 'fixtures/webpack-merge')
8
+
9
+ describe('basic webpack-merge', function () {
10
+ this.timeout(20000)
11
+ it('should run plain', async () => {
12
+ const expected = `
13
+ assert.ok() is a function
14
+ querystring.parse() is a function
15
+ ✔ test.js
16
+ `
17
+ const { stdout, code } = await runCli(webpackMergeFixture, '--runner=bare-sync')
18
+ assert.strictEqual(code, 0, 'exited with zero exit code')
19
+ assert.ok(stdout.includes(expected), 'stdout contains expected test output')
20
+ assert.ok(stdout.includes('Running bare-sync page tests with Puppeteer'), 'stdout contains expected output for running in page')
21
+ })
22
+
23
+ it('should fail with custom config', async () => {
24
+ const expectedStdout = `
25
+ assert.ok() is a function
26
+ ✘ test.js
27
+ `
28
+ const expectedStderr = '\'undefined\' === \'function\''
29
+
30
+ const { stdout, stderr, code } = await runCli(webpackMergeFixture, '--runner=bare-sync --webpack-config webpack.config.js')
31
+ assert.strictEqual(code, 1, 'exited with zero exit code')
32
+ assert.ok(stdout.includes(expectedStdout), 'stdout contains expected test output')
33
+ assert.ok(stderr.includes(expectedStderr), 'stderr contains expected test output')
34
+ assert.ok(stdout.includes('Running bare-sync page tests with Puppeteer'), 'stdout contains expected output for running in page')
35
+ })
36
+ })
@@ -1,21 +0,0 @@
1
- name: CI
2
-
3
- on: [push, pull_request]
4
-
5
- jobs:
6
- build:
7
-
8
- runs-on: ubuntu-latest
9
-
10
- steps:
11
- - name: Checkout
12
- uses: actions/checkout@v1
13
- with:
14
- fetch-depth: 1
15
-
16
- - name: Install and test
17
- uses: actions/setup-node@v1
18
- with:
19
- node-version: '12.x'
20
- - run: npm install
21
- - run: npm test