Run JavaScript in a browser, forward browser console log to stdout, great for running unit tests in browser.
npm install browser-doRun JavaScript in a browser, forward browser console log to stdout, great for running unit tests in browser.
``bash`
npm i -D browser-do
> Requires minimum Node.js v10.13+.
browser-do is an alternative implementation of browser-run and tape-run, with better Windows support, supports running mocha, jasmine, tape, zora unit tests out of the box.
browser-do offers:
1. Browser detection borrowed from various karma browser launchers. Simpler and more reliable on Windows than browser-launcher.
2. TAP output support.
3. Kept browser-run options -p, --port, -b, --browser browser-name, -s, --static, and -m, --mock.--input html
4. Removed as browser-do auto detects input format.-n, --node
5. Removed and --basedir as browser-do doesn't want to support Node.js code. (In original browser-run, Node.js code only works with electron anyway)-t, --tap
6. Added options to handle generic TAP output.--jasmine
7. Added and --mocha to conveniently support jasmine/mocha (setup global vars, switch to TAP reporter).-k, --keep-open
8. Added (inherited from tap-run) to keep browser running after TAP finished.
browser-do is simple and flexible. Just pipe your code to browser-do with a browser of your choice (default to a headless electron).
`bash`
browserify test/all-my-tape-tests.js | browser-do --tap
browserify test/all-my-zora-tests.js | browser-do --tap
browserify test/all-my-jasmine-tests.js | browser-do --jasmine
browserify test/all-my-mocha-tests.js | browser-do --mocha --browser chrome-headless
> Note browserify doesn't support glob, that's why we cannot use browserify 'test/*/.spec.js' here.
You don't need to use browserify with browser-do. You can prepare a JavaScript bundle with any bundler, then just pipe it to browser-do.
`bash`
cat dist/my-test-bundle.js | browser-do --tap # or jasmine/mochaor avoid "cat" on windows
browser-do --tap < dist/my-test-bundle.jsOr in PowerShell
Get-Content dist/my-test-bundle.js | browser-do --tap # or jasmine/mocha
One more tip, because browser-do normalises jasmine/mocha into TAP output, plus the default TAP output from tape/zora, you can further pipe the output to any TAP pretty reporters
`bash`
browserify test/all-my-jasmine-tests.js | browser-do --jasmine | tap-dot
electron is the always available default.
| | macOS | Linux | Windows |
|--------------------|-------|-------|---------|
| electron (default) | Yes | Yes | Yes |
| chrome | Yes | Yes | Yes |
| chrome-headless | Yes | Yes | Yes |
| chromium | Yes | Yes | Yes |
| chromium-headless | Yes | Yes | Yes |
| firefox | Yes | Yes | Yes |
| firefox-headless | Yes | Yes | Yes |
| edge | Yes | | Yes |
| edge-headless | Yes | | Yes |
| safari | Yes | | |
> browser-do v4+ dropped support of Microsoft IE. To work with IE, please use browser-do v3.
> browser-do v2+ only supports Chromium based Microsoft Edge. To work with old Microsoft Edge, please use browser-do v1.
`
Usage: browser-do [options]
Options:
-V, --version output the version number
-b, --browser
-p, --port
-s, --static
-m, --mock
-t, --tap Treat output as TAP test result, automatically exit when TAP finishes
--jasmine Support jasmine test, uses jasmine TAP reporter, implicitly turns on option "tap", automatically exit when TAP finishes
--mocha Support mocha test, assumes BDD setup, uses TAP reporter, implicitly turns on option "tap", automatically exit when TAP finishes
-k, --keep-open Only for -t, --tap, --jasmine and --mocha, leave the browser open for debugging after running tests
-h, --help output usage information
Available browsers if installed (for -b, --browser
electron (embedded, default choice), chrome, chrome-headless, chromium, chromium-headless, firefox, firefox-headless, edge, edge-headless, safari
There is some tolerance on browser name, for example:
-b ChromeHeadless
-b chromeHeadless
-b chrome_headless
-b "chrome headless"
all work just like -b chrome-headless
`
Your can provide a custom html file for browser-do to use. Keep in mind it always needs to have above other script tags so browser-do is able to properly forward your console.logs etc to the terminal.
> Different from browser-run, you don't need --input html, browser-do detects the input automatically.
> You would need to combine custom html file with --static some-dir or --mock mock-code.js in order to have some way to load your JavaScript code.
By using --mock mock.js (or { mock: 'mock.js'} in code) you can provide a custom server-side implementation and handle all requests that are sent to paths beginning with /mock
mock.js needs to export a function that accepts req and res arguments for handling requests.
Example:
`js`
module.exports = function(req, res){
if (req.url === '/mock/echo') {
req.pipe(res);
}
};
API: run(opts), all the opts have same meaning as the command line options.
port, browser, static, mock, tap, jasmine, mocha, and keepOpen.
`js
var run = require('browser-do');
var browser = run();
browser.pipe(process.stdout);
browser.end('console.log(location); window.close()');
`
> Note window.close() will quit the default electron browser, but it would not work with some other browsers. Because many browsers reject window.close() for a window not opened by JavaScript. (In browser perspective, it opened a URL, although browser-do programmatically did that.)
When using browser-do in code with a browser not electron, you have to close the window manually (only if you didn't use tap, jasmine or mocha option).
`js
var run = require('browser-do');
var browser = run({browser: 'chrome'});
browser.pipe(process.stdout);
browser.end('console.log(location);');
setTimeout(function() { browser.stop(); }, 5000);
`
Follow example takes unit test JS code from stdin, capture final result (either pass or fail).
`js
var run = require('browser-do');
var browser = run({tap: true}); // or jasmine: true, or mocha: true
process.stdin.pipe(browser).pipe(process.stdout);
browser.on('exit', code => {
// the code is 0 for passed tests, 1 for failed tests
});
`
> Note browser-do only generates a simple pass/fail result from the whole TAP output. browser-do retains original TAP output, so if you need detailed TAP output parsing, further pipe the stream to tap-parser.
browser-do conveniently supports running mocha, jasmine, tape unit tests out of the box.
#### Tape
Tape is easy to support, as it doesn't pollute global variables. All browser-do needs to do is to parse TAP output and automatically exit when tests finish.
`bash`
browserify some-tap-test.js | browser-do -t # or --tap
#### Zora
Zora is the same story as Tape.
`bash`
browserify some-zora-test.js | browser-do -t # or --tap
#### Jasmine
browser-do helps jasmine test by setup global vars before running your code.
``
browserify some-jasmine-test.js | browser-do --jasmine
You don't need to load jasmine before running your code, browser-do does that automatically, as long as you did npm i -D jasmine-core.
FYI, here is the special index.html browser-do provided for jasmine. Showing here only to help you to understand how browser-do does the magic.
`html`
#### Mocha
browser-do helps mocha test by setup global vars before running your code.
``
browserify some-mocha-test.js | browser-do --mocha
You don't need to load mocha before running your code, browser-do does that automatically, as long as you did npm i -D mocha.
FYI, here is the special index.html browser-do provided for mocha. Showing here only to help you to understand how browser-do does the magic.
Note we use default BDD style in mocha.
`html`
> The default mocha setup uses "tap" reporter so browser-do can understand tests result.
> Only for mocha, when -k, --keep-open option is on, it switches setup to use "html" reporter. Because mocha doesn't support multiple reporters, and we want to show user a nice result in browser window. As a result, browser-do cannot detect the final test result in keepOpen mode.
If you want to use different setup of mocha, just pipe a custom html file to browser-do
`bash`
cat my-mocha-index.html | browser-do --mocha --static .or avoid "cat" on windows
browser-do --mocha --static . < my-mocha-index.html
In your special html file:
1. you need above any script tags.
2. you need retain most of the above html file, just modify the mocha setup part.
2. you need something like to replace , you need to make sure you generated that bundle file before using browser-do.--static .
3. The option is to let browser-do to access all the local files including the dist/my-prepared-bundle.js.
When running unit tests with browser-do, you need xvfb on Linux.
`yml`
- run: xvfb-run -a npm test
if: runner.os == 'Linux'
- run: npm test
if: runner.os != 'Linux'
You may also need to enlarge xvfb default screen size (640x480x8) for your tests.
`sh`
xvfb-run -a -s '-screen 0 1024x768x24' npm test
To use browser-do on travis, add this to your .travis.yml:
`yml`
addons:
apt:
packages:
- xvfb
before_install:
- export DISPLAY=':99.0'
- Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
If you run travis with multiple OS including windows:
`yml`
os:
- linux
- windows
- osx
addons:
apt:
packages:
- xvfb
before_install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then export DISPLAY=':99.0' ; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & fi
browser-do supports code coverage in a humble way. To understand how browser-do supports it, first we need to understand how nyc/Istanbul works internally.
To generate code coverage report, when in Node.js environment, nyc/Istanbul needs to
1. instrument source code. It injects special code into your source code in order to gather code coverage information.
2. when running unit tests, those instrumented source code writes code coverage information into an intermediate JavaScript object global.__coverage__. This becomes window.__coverage__ in browser.global.__coverage__
3. nyc automatically writes object to a local json file in .nyc_output/ folder.
4. nyc then uses various reporters to turn the json file into human readable report (text summary, or html file).
When running browser-do, your unit tests is running in browser. All browser-do does is:
1. if your source code is instrumented, it will generate window.__coverage__ object. browser-do does nothing here.window.__coverage__
2. when tape/jasmine/mocha tests finished, browser-do check whether there is . If so, it will write the object to .nyc_output/out.json (the default nyc output file).
You then can follow it up with another command to turn that json file into readable report!
`bash`
npx nyc report --reporter=lcov --reporter=text
Here browser-do does the bare minimum job: only writes window.__coverage__ into .nyc_output/out.json when window.__coverage__ exits.
The task of instrumenting is not handled by browser-do, nor should (as browser-do is the consumer of a piece of JavaScript, not the creator).
For projects using babel, you can easily turn on babel-plugin-istanbul in test environment. That plugin will instrument your code.
> I have not found out what's the native way to instrument TypeScript file. But if you use babel to compile ts files, you can continue to use babel-plugin-istanbul.
For example on babel-plugin-istanbul + browser-do + nyc, try to create a SPA app with dumberjs skeleton:
`bash``
npx makes dumberjs
Choose Aurelia or Vue (but not .vue single file component), babel, jasmine/mocha/tape, (not jest. jest runs in Node.js, not browser, is irrelevant here).
Then follow the README file on code coverage. Note the React non-jest setup has some trouble in code coverage right now.
browser-do is licensed under the MIT license.
browser-do borrowed code from many projects, details in ACKNOWLEDGEMENT.