├── .gitignore
├── .travis.yml
├── README.md
├── cli.js
├── index.js
├── package.json
└── test
├── client-test.js
└── test.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - 'iojs'
4 | before_script:
5 | - export DISPLAY=:99.0; sh -e /etc/init.d/xvfb start
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # testron
2 | CI your client side tests with Electron
3 |
4 | [](https://travis-ci.org/shama/testron)
5 | [](https://badge.fury.io/js/testron)
6 | [](http://github.com/hughsk/stability-badges)
7 |
8 | # about
9 | This uses [Electron](https://github.com/atom/electron) to run tests in
10 | [Chromium](http://www.chromium.org/).
11 |
12 | # usage
13 |
14 | * Install to your project: `npm install testron --save-dev`
15 | * Install Electron: `npm install electron-prebuilt --save-dev`
16 | * Add a `test` script to your `package.json`:
17 | ```json
18 | {
19 | "name": "my-project",
20 | "scripts": {
21 | "test": "testron test/client.js"
22 | },
23 | }
24 | ```
25 | * Run `npm test` to run the test script in Electron
26 |
27 | ## writing tests
28 | Currently this only supports TAP. Here is an example test written using [tape](https://www.npmjs.com/package/tape):
29 |
30 | ```js
31 | var test = require('tape')
32 |
33 | test('test this', function (t) {
34 | t.plan(1)
35 | var ul = document.createElement('ul')
36 | var li = document.createElement('li')
37 | ul.appendChild(li)
38 | li.textContent = 'it works'
39 | t.equal(ul.outerHTML, '
')
40 | t.end()
41 | })
42 | ```
43 |
44 | It is recommended bundling your tests and piping to `testron`:
45 |
46 | ```json
47 | {
48 | "name": "my-project",
49 | "scripts": {
50 | "test": "browserify test/client.js | testron"
51 | },
52 | }
53 | ```
54 |
55 | ## travis-ci integration
56 | Add a `.travis.yml` file to your project:
57 |
58 | ```yml
59 | language: node_js
60 | node_js:
61 | - 'iojs'
62 | before_script:
63 | - export DISPLAY=:99.0; sh -e /etc/init.d/xvfb start
64 | ```
65 |
66 | ## API
67 | There is also an API:
68 |
69 | ```js
70 | var testron = require('testron')
71 | var tests = testron('test/client.js')
72 | tests.stdout.on('data', function (data) {
73 | console.log('line: ' + data.toString())
74 | })
75 | tests.on('exit', function () {
76 | console.log('Tests are done!')
77 | })
78 | ```
79 |
80 | ## similar projects
81 | These are similar projects that also (can) use Electron for testing:
82 |
83 | * [hihat](https://github.com/Jam3/hihat)
84 | small tool for running browser tests locally
85 | * [zuul](https://github.com/defunctzombie/zuul)
86 | multi-framework javascript browser testing
87 |
88 | # license
89 | (c) 2018 Kyle Robinson Young. MIT License
90 |
--------------------------------------------------------------------------------
/cli.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | process.title = 'testron'
4 | var path = require('path')
5 | var argv = require('minimist')(process.argv.slice(2))
6 | var testron = require('./index.js')
7 | var tests
8 |
9 | if (argv._.length > 0) {
10 | tests = testron(argv._[0])
11 | } else {
12 | process.stdin.resume()
13 | process.stdin.setEncoding('utf8')
14 | tests = testron()
15 | process.stdin.pipe(tests.stdin)
16 | }
17 |
18 | tests.stdout.pipe(process.stdout)
19 | if (argv['errors'] || argv['e']) {
20 | tests.stderr.pipe(process.stderr)
21 | }
22 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | if (process.versions['electron']) {
2 | module.exports = function (args) {
3 | var filename = args[1] || 'test.js'
4 | var old = process.stdout.write
5 | process.stdout.write = function (msg) {
6 | if (msg.toString().slice(0, 4) === '# ok' || msg.toString().slice(0, 6) === '# fail') {
7 | process.nextTick(function () {
8 | require('remote').require('app').quit()
9 | })
10 | }
11 | old.apply(process.stdout, arguments)
12 | }
13 | process.nextTick(function () {
14 | require(filename)
15 | })
16 | }
17 | } else {
18 | var fs = require('fs')
19 | var path = require('path')
20 | var through = require('through2')
21 | var tempfile = require('tempfile')
22 | var electronSpawn = require('electron-spawn')
23 |
24 | module.exports = function (filename) {
25 | if (filename) {
26 | return electronSpawn(__filename, filename)
27 | } else {
28 | return stream()
29 | }
30 | }
31 |
32 | function stream () {
33 | var tmpname = tempfile('.js')
34 | var s = {
35 | stdin: fs.createWriteStream(tmpname),
36 | stdout: through(),
37 | stderr: through()
38 | }
39 | s.stdin.on('close', function () {
40 | var electron = electronSpawn(__filename, tmpname)
41 | electron.stdout.pipe(s.stdout)
42 | electron.stderr.pipe(s.stderr)
43 | electron.on('exit', function () {
44 | fs.unlink(tmpname, function (err) {
45 | if (err) console.error(err)
46 | })
47 | })
48 | })
49 | return s
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "testron",
3 | "version": "1.2.1",
4 | "description": "CI your client side tests with Electron",
5 | "main": "index.js",
6 | "bin": {
7 | "testron": "cli.js"
8 | },
9 | "scripts": {
10 | "test": "node test/test.js"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "git+ssh://git@github.com/shama/testron.git"
15 | },
16 | "keywords": [
17 | "test",
18 | "client",
19 | "side",
20 | "runner",
21 | "electron",
22 | "ci"
23 | ],
24 | "author": "Kyle Robinson Young (http://dontkry.com)",
25 | "license": "MIT",
26 | "bugs": {
27 | "url": "https://github.com/shama/testron/issues"
28 | },
29 | "homepage": "https://github.com/shama/testron#readme",
30 | "dependencies": {
31 | "electron-spawn": "^3.0.0",
32 | "minimist": "^1.1.2",
33 | "tempfile": "^1.1.1",
34 | "through2": "^2.0.0"
35 | },
36 | "devDependencies": {
37 | "electron-prebuilt": "^0.30.0",
38 | "tape": "^4.0.1"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/test/client-test.js:
--------------------------------------------------------------------------------
1 | process.browser = true
2 | var test = require('tape')
3 |
4 | test('test that tests work', function (t) {
5 | t.plan(1)
6 | var ul = document.createElement('ul')
7 | var li = document.createElement('li')
8 | ul.appendChild(li)
9 | li.textContent = 'it works'
10 | t.equal(ul.outerHTML, '', 'client-test should have worked')
11 | t.end()
12 | })
13 |
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 | var test = require('tape')
2 | var path = require('path')
3 | var testron = require('../index.js')
4 |
5 | test('runs some tests on client side', function (t) {
6 | t.plan(1)
7 | var tests = testron(path.resolve(__dirname, 'client-test.js'))
8 | var result = []
9 | tests.stdout.on('data', function (data) {
10 | result.push(data.toString())
11 | })
12 | tests.on('exit', function () {
13 | result = result.join('')
14 | t.ok(result.indexOf('client-test should have worked') != -1, 'should have been notified it worked')
15 | t.end()
16 | })
17 | })
18 |
--------------------------------------------------------------------------------