The easiest way of running code in a browser environment

Overview

browser-run

The easiest way of running code in a browser environment.

Bundles electronjs by default!

build status downloads

Usage

$ echo "console.log('Hey from ' + location); window.close()" | browser-run
Hey from http://localhost:53227/
$

Or use browser-run programmatically:

var run = require('browser-run');

var browser = run();
browser.pipe(process.stdout);
browser.end('console.log(location); window.close()');

Example with browserify

$ browserify main.js | browser-run

or

var browserify = require('browserify');
var browser = require('browser-run');

browserify('main.js').bundle().pipe(browser()).pipe(process.stdout);

CLI

$ browser-run --help
Run JavaScript in a browser.
Write code to stdin and receive console output on stdout.
Usage: browser-run [OPTIONS]

Options:
      --version  Show version number                                   [boolean]
  -b, --browser  Browser to use. Always available: electron. Available if
                 installed: chrome, firefox, ie, safari    [default: "electron"]
      --sandbox  Enable electron sandbox               [boolean] [default: true]
      --basedir  Set this if you need to require node modules in node mode
  -h, --help     Print help                                            [boolean]
  -p, --port     Starts listening on that port and waits for you to open a
                 browser
  -s, --static   Serve static assets from this directory
  -m, --mock     Path to code to handle requests for mocking a dynamic back-end
  -i, --input    Input type. Defaults to 'javascript', can be set to 'html'.
  -n, --node     Enable nodejs apis in electron

Custom html file

By using --input html or { input: 'html' } you can provide a custom html file for browser-run to use. Keep in mind though that it always needs to have <script src="/reporter.js"></script> above other script tags so browser-run is able to properly forward your console.logs etc to the terminal.

Dynamic back-end mock

By using --mock mock.js or { mock: 'mock.js'} 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:

module.exports = function(req,res){
  if (req.url === '/mock/echo') {
    req.pipe(res)
  }
}

API

run([opts])

Returns a duplex stream and starts a webserver.

opts can be:

  • port: If speficied, no browser will be started, so you can point one yourself to http://localhost/<port>
  • browser: Browser to use. Defaults to electron. Available if installed:
    • chrome
    • firefox
    • ie
    • safari
  • static: Serve static files from this directory
  • mock: Path to code to handle requests for mocking a dynamic back-end
  • input: Input type. Defaults to javascript, can be set to html.
  • node: Enable nodejs integration in electron
  • sandbox: Enable electron sandbox. Default: true.
  • basedir: Set this if you need to require node modules in node mode

If only an empty string is written to it, an error will be thrown as there is nothing to execute.

If you call window.close() inside the script, the browser will exit.

run#stop()

Stop the underlying webserver.

Headless testing

In environments without a screen, you can use Xvfb to simulate one.

GitHub Actions

This is a full example to run npm test. Refer to the last 2 lines in the YAML config:

on:
  - pull_request
  - push

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1
    - run: npm install
    - run: sudo apt-get install xvfb
    - run: xvfb-run --auto-servernum npm test

Travis

Add this to your travis.yml:

addons:
  apt:
    packages:
      - xvfb
install:
  - export DISPLAY=':99.0'
  - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
  - npm install

Full example.

Any gnu/linux box

$ sudo apt-get install xvfb # or equivalent
$ export DISPLAY=':99.0'
$ Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
$ browser-run ...

Docker

There is also an example Docker image. Source

Installation

With npm do

$ npm install browser-run    # for library
$ npm install -g browser-run # for cli

Sponsors

This module is proudly supported by my Sponsors!

Do you want to support modules like this to improve their quality, stability and weigh in on new features? Then please consider donating to my Patreon. Not sure how much of my modules you're using? Try feross/thanks!

License

(MIT)

Comments
  • `browser-launcher` is no longer maintained

    `browser-launcher` is no longer maintained

    substack hasn't updated browser-launcher for 2 years; bugs aren't getting fixed. So I can't run this, for example, with Chrome on Windows.

    I suggest using another package such as browser-launcher2 instead.

    opened by seangenabe 32
  • Ability to add additional script tags to html

    Ability to add additional script tags to html

    I'm testing a set of interdependent libraries using browserify. I'd like to load multiple <script> tags into <head>.

    Right now, static/index.html is loaded. I'd like the ability to use a custom html file and/or have a custom handler for GET /.

    opened by btakita 31
  • Issues to many xhr

    Issues to many xhr

    Hi,

    I am using tape-run to run mobx tests and I saw that in safari and chrome not all tests results are sent back to the node http server, therefore tests never finishes.

    tape_run_bug Taken from https://github.com/mobxjs/mobx/pull/590

    After some researching, I found out that for each console.log we issue POST request and it might be that we issue lots of requests and browser resources are exhausted.

    I can submit a pull request that will use websocket-stream (or socket-io so we can support old browsers?) to fix that.

    opened by yosiat 15
  • Use bleeding edge dependency to fix Firefox support

    Use bleeding edge dependency to fix Firefox support

    Fixes https://github.com/juliangruber/browser-run/issues/145 Fixes https://github.com/juliangruber/tape-run/issues/77

    Let's wait a bit for the original dependency to be published to npm instead. This is only for testing purposes.

    Tests are failing and will be fixed by #148

    opened by fregante 14
  • Usage on GitHub Actions with xvfb

    Usage on GitHub Actions with xvfb

    I tried to install/configure xvfb on GitHub actions to use browser-run/tape-run there, but I was not successful.

    If anyone finds a solution, please advise. This is the simplest configuration that's only missing xvfb

    on: push
    jobs:
      run:
        runs-on: ubuntu-latest
        steps:
        - uses: actions/setup-node@v1
        - run: npm install browser-run
        - run: echo 'console.log(9001); window.close()' | browser-run
    

    I wrote all of this and it exits with 0 but browser-run doesn't output anything. The code is not run at all, invalid JS will also result in browser-run exiting successfully.

    on: push
    jobs:
      run:
        runs-on: ubuntu-latest
        steps:
        - uses: actions/setup-node@v1
        - run: sudo apt-get install xvfb
        - run: export DISPLAY=':99.0'
        - run: Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
        - run: npm install browser-run
        - run: npm install electron # Without this, Electron complains it's not installed correctly
        - run: echo 'console.log(9001); window.close()' | ./node_modules/.bin/browser-run
    
    question 
    opened by fregante 11
  • Works in everything EXCEPT Electron

    Works in everything EXCEPT Electron

    I don't know what I could be getting wrong in my setup, but I can't seem to make this work using Electron.

    Running with cat build/index.html | browser-run --input html --static build

    Folder structure is

    build/
      bundle.js
      index.html
    
    css/
      ... source files ...
    
    html/
      ... source files ...
    
    js/
      ... source files ...
    
    node_modules/
      ... node modules ...
    
    package.json
    webpack.config.js
    

    index.html is

    <div id="app"></div>
    <script type="text/javascript" src="/reporter.js"></script>
    <script type="text/javascript" src="/bundle.js"></script>
    

    I've stripped down my bundle so that the only code going into it is some babel runtime code and:

    import test from 'tape'
    
    test.onFinish(function(){
      window.close();
    });
    
    test('test ok', function (t) {
      t.ok(true)
      t.end()
    })
    

    If I use the -b or --port options, everything works as expected. If I leave those options off, Electron tries to run but just outputs SyntaxError: Unexpected token < and immediately exits.

    Adding --basedir build causes Electron to create a file called .source.[timestamp].html and the contents of that file are:

    <body><script><div id="app"></div>
    <script type="text/javascript" src="/reporter.js"></script>
    <script type="text/javascript" src="/bundle.js"></script>
    </script></body>
    

    However, nothing is output and Electron just hangs until I hit Ctrl-C.

    Meanwhile, using a browser (-b or --port), I get exactly the output I expect:

    TAP version 13
    # okay
    ok 1 should be truthy
    
    1..1
    # tests 1
    # pass  1
    
    # ok
    
    opened by beverlycodes 11
  • Drop PhantomJS support

    Drop PhantomJS support

    opened by fregante 10
  • Add capability for defining a dynamic mock server

    Add capability for defining a dynamic mock server

    Sometimes you need more than static resources to run your tests against. I needed that for functional-testing xhr

    • I didn't add tests for the only reason I accept - I didn't know how. I would if there already was one for --static that I could mimic
    opened by naugtur 9
  • Use browser-launcher2.

    Use browser-launcher2.

    opened by timoxley 9
  • Consider removing electron

    Consider removing electron

    Hi, browser-run is awesome – thanks for building it! I have a request, would it be possible to remove the default browser and make the package smaller? Electron alone is ~41MB and not everyone needs it.

    opened by giuseppeg 7
  • Example with watch

    Example with watch

    Is there some way of getting this to work while watching for file changes?

    Currently I'm killing the process, then starting a new one on each change, but it feels a bit brute. Any ideas?

    opened by colindresj 7
  • output stream error

    output stream error

    Having issue with tape-run v6 upwards which base on browser-run 6.

    > webpack --config webpack.test.js
    
    TAP version 13
    # test success
    ok 1 should be equal
    Error: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'webpack://webpack-tape-run/./node_modules/tape/lib/test.js?'.
        at Array.<anonymous> (http://localhost:54901/reporter.js:6627:9)
        at http://localhost:54901/reporter.js:6604:24
        at retrieveSourceMapURL (http://localhost:54901/reporter.js:6675:14)
        at Array.<anonymous> (http://localhost:54901/reporter.js:6692:26)
        at http://localhost:54901/reporter.js:6604:24
        at mapSourcePosition (http://localhost:54901/reporter.js:6722:21)
        at wrapCallSite (http://localhost:54901/reporter.js:6894:20)
        at http://localhost:54901/reporter.js:6929:26
        at Array.map (<anonymous>)
        at Function.prepareStackTrace (http://localhost:54901/reporter.js:6928:24)
    # C:\Users\hotti\distro\webpack-tape-run\test.js: line 7, column 3-9
    
        t.end()
        ^^^^^^^
    
    # coverage: 13/14 (92.85 %)
    
    asset test.js 296 KiB [compared for emit] (name: main)
    runtime modules 221 bytes 1 module
    modules by path ./node_modules/ 241 KiB 48 modules
    ./test.js 1.39 KiB [built] [code generated]
    fs (ignored) 15 bytes [built] [code generated]
    ./util.inspect (ignored) 15 bytes [built] [code generated]
    buffer (ignored) 15 bytes [built] [code generated]
    util (ignored) 15 bytes [built] [code generated]
    buffer (ignored) 15 bytes [built] [code generated]
    util (ignored) 15 bytes [built] [code generated]
    buffer (ignored) 15 bytes [built] [code generated]
    
    ERROR in tests failed
    
    ERROR in test reporter non-zero exit code
    
    webpack 5.50.0 compiled with 2 errors in 2431 ms
    npm ERR! Test failed.  See above for more details.
    
    opened by syarul 4
  • Support import in scripts

    Support import in scripts

    Trying to come up with node ES module, working both in browser/node. It uses import. cat test.js | browser-run gives

    SyntaxError: Unexpected identifier
      at http://localhost:55133/bundle.js:1:8 
    

    Would that be reasonable to detect if input code uses import (see is-module) and include script as <script type="module"></script>?

    opened by dy 2
  • No output

    No output

    When I run the example echo "console.log('Hey from ' + location); window.close()" | browser-run I get no output, but also no error message. How can I debug this?

    opened by adjenks 8
  • Browsers other than electron don't close

    Browsers other than electron don't close

    I noticed when using tape-run that Firefox closed but Chrome stayed open (even though the tests completed anyway)

    However this doesn't close the tab and window either:

    echo "console.log('Hey from ' + location); window.close()" | browser-run --browser firefox
    

    ...nor any other browser I tested: chrome and safari.

    The interesting part is that this closed the tab once, but on a second call the tab and window stayed open:

    echo "var run = require('browser-run');
      var browser = run({browser: 'chrome'});
      browser.pipe(process.stdout);
      browser.end('console.log(location); window.close()');" | node
    

    I'm on macOS 10.15.2, Node v12.14.1

    opened by fregante 1
  • Add option to show electron window

    Add option to show electron window

    When testing in browser, I find it helpful at times to be able to view the window. This didn't appear possible when using electron as the browser. electron-stream already provides a show option, so I simply exposed the option via the bin script and updated the README.md.

    I assume this qualifies as a "trivial" update, so I am forgoing the process outlined in the contributing guidelines.

    opened by tylerjpeterson 2
Releases(v11.0.0)
  • v11.0.0(May 4, 2022)

  • v10.1.0(Apr 9, 2021)

  • v10.0.0(Apr 6, 2021)

  • v9.0.0(Jan 15, 2021)

    • swap in yargs for optimist and patch a few other security vulnerabilities (#157) dc1f389

    https://github.com/juliangruber/browser-run/compare/v8.0.0...v9.0.0

    Source code(tar.gz)
    Source code(zip)
  • v8.0.0(Jul 22, 2020)

    • remove makefile 40e3922
    • Bumping electron-stream to v8.0.0 (#156) 9046c3b

    https://github.com/juliangruber/browser-run/compare/v7.0.2...v8.0.0

    Source code(tar.gz)
    Source code(zip)
  • v7.0.2(May 6, 2020)

    • pkg: add release script 057388c
    • bump browser-launcher to 2.0.0 0a55479

    https://github.com/juliangruber/browser-run/compare/v7.0.1...v7.0.2

    Source code(tar.gz)
    Source code(zip)
Owner
Julian Gruber
Julian Gruber
Glob-aware two-way copying for git

ggcp git-glob-copy — glob-aware two-way copying for git Requirements Node.js >= 16 Install npm i git-glob-cp # or as a global package npm i -g ggcp U

Anton Golub 3 Jul 5, 2022
rtail(1) - Terminal output to the browser in seconds, using UNIX pipes.

rtail(1) Terminal output to the browser in seconds, using UNIX pipes. rtail is a command line utility that grabs every line in stdin and broadcasts it

Kilian Ciuffolo 1.6k Jan 6, 2023
A pipe to browser utility

node-bcat Pipe to the browser utility, Very useful for log tail fun :) node-bcat features auto scrolling (with enable/disable), ansi to html coloring

Yaniv Kessler 327 Dec 30, 2022
An npm module to run Snowflake in a headless browser to help censored users connect to the Tor network.

snowflake-cli An npm module to run Snowflake in a headless browser to help censored users connect to the Tor network. Note: depending on your environm

yan 8 Mar 24, 2022
🌟 JavaScript Style Guide, with linter & automatic code fixer

JavaScript Standard Style Sponsored by English • Español (Latinoamérica) • Français • Bahasa Indonesia • Italiano (Italian) • 日本語 (Japanese) • 한국어 (Ko

Standard JS 27.8k Dec 31, 2022
Find and fix problems in your JavaScript code.

ESLint Website | Configuring | Rules | Contributing | Reporting Bugs | Code of Conduct | Twitter | Mailing List | Chat Room ESLint is a tool for ident

ESLint 22k Jan 8, 2023
Detect copy-pasted and structurally similar code

Detect copy-pasted and structurally similar JavaScript code. Requires Node.js 6.0+, and supports ES6, JSX as well as Flow. Note: the project has been

Daniel St. Jules 3.5k Dec 26, 2022
ECMAScript code beautifier/formatter

esformatter ECMAScript code beautifier/formatter. Important This tool is still missing support for many important features. Please report any bugs you

Miller Medeiros 968 Nov 1, 2022
⚡️The Fullstack React Framework — built on Next.js

The Fullstack React Framework "Zero-API" Data Layer — Built on Next.js — Inspired by Ruby on Rails Read the Documentation “Zero-API” data layer lets y

⚡️Blitz 12.5k Jan 4, 2023
Easiest 1-click way to install and use Stable Diffusion on your own computer. Provides a browser UI for generating images from text prompts and images. Just enter your text prompt, and see the generated image.

Stable Diffusion UI Easiest way to install and use Stable Diffusion on your own computer. No dependencies or technical knowledge required. 1-click ins

null 3.5k Dec 30, 2022
A hackable C# based scripting environment for 3D modeling running in the web browser.

A hackable C# based scripting environment for 3D modeling running in the web browser. Background Script based 3D modeling software running in the web

Emil Poulsen 49 Nov 28, 2022
⚡️ The easiest way to build forms with Vue.

Documentation Website What is Vue Formulate? Vue Formulate is the easiest way to build forms with Vue. Please read the comprehensive documentation for

Braid 2.2k Dec 30, 2022
the easiest way to use Google Maps

Important If you're developer, I'm moving gmaps.js to NPM, you can give your opinion and check the migration progress in Issue #404 gmaps.js - A Javas

Gustavo Leon 7.1k Dec 28, 2022
the easiest way to use Google Maps

Important If you're developer, I'm moving gmaps.js to NPM, you can give your opinion and check the migration progress in Issue #404 gmaps.js - A Javas

Gustavo Leon 7.1k Apr 7, 2021
The easiest way to check who hasn't followed you back on Instagram

Instagram Unfollowers The easiest way to check who hasn't followed you back on Instagram is to do it manually, keeping track of the exact number of fo

Andrei Voicu 26 Dec 14, 2022
Easiest way to build documentation for your project. No config or build required, hosted on @netlify.

Hyperdocs is the simplest way you can create documentation for your project. It blends the best of all the other documentation tools in one. Hyperdocs

Lalit 76 Dec 22, 2022
EveryAuth is the easiest way for your app to access APIs like Slack, Salesforce, or Github.

EveryAuth EveryAuth is the easiest way for your app to access APIs like Slack, Salesforce, or Github. import everyauth from "@fusebit/everyauth-expres

Fusebit 13 Dec 12, 2022
Wonka JS is the easiest way to mint Metaplex's Candy Machine NFTs with APIs.

Wonka JS Wonka JS is the easiest way to mint from Candy Machine and fetch NFTs through JS APIs. You can see an end to end example in Next.js demo proj

Wonka Labs 71 Nov 3, 2022
🎊 The easiest way to use MineAPI.

@mineapi/sdk Do you need my help? Visit our Discord server. Node Version: 16.16.0 Installation npm i @mineapi/sdk --save # or yarn add @mineapi/sdk Us

MineAPI 5 Jul 29, 2022