Skip to content

Instantly share code, notes, and snippets.

@twilson63
Created April 29, 2019 15:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save twilson63/89601cdd3940fb03140c8d10bc09c98e to your computer and use it in GitHub Desktop.
Save twilson63/89601cdd3940fb03140c8d10bc09c98e to your computer and use it in GitHub Desktop.
Setup for Frontend Tests - tape - puppeteer - rollup

Testing Front End code

Testing front end code using rollup, tape-modern, and puppeteer.

These are just some notes for me to write down so that I have a good cheatsheet to set this up in the future.

Using rollup to build front end code is the way to go, it is small and provides tree shaking and the plugins are easy to manage. Using rollup to build a test bundle and using puppeteer to run the test bundle will create a chromium head browser and give you similar results as if you are running it in the browser.

Getting started

We need to install our dependencies

npm install --save-dev rollup tape-modern puppeteer
npm install --save-dev rollup-plugin-node-resolve
npm install --save-dev rollup-plugin-commonjs
npm install --save-dev sirv tape-browser-color

We need to setup our test directory:

mkdir test
mkdir test/public test/src
npx @twilson63/html test/public/index.html
touch test/src/main.js

modify the index.html to work for the test suite

rollup.config.js

create a separate rollup config pipeline

import resolve from 'rollup-plugin-node-resolve'
import commonjs from 'rollup-plugin-commonjs'

export default [{
  ...
}, {
  input: 'test/src/main.js',
  output: {
    file: 'test/public/bundle.js',
    format: 'iife',
    name: 'tests'
  },
  plugins: [
    resolve(),
    commonjs()
  ]
}]

Here we are creating a new rollup build pipeline this pipeline will use the main.js in our test/src folder which should contain our tape tests.

main.js

write main.js as you would any tape tests or it can be an aggregate file for calling all of your test files.

import { test, done } from 'tape-modern'
import color from 'tape-browser-color'
import mymodule from '../..'

color() // add your test print out to the page for visual debugging

test('my first test', t => {
  t.ok(true)
})


window.done = done // for puppeteer

runner.js

We need to create a runner file to run the tests using puppeteer.

touch test/runner.js

const http = require('http');
const ports = require('port-authority');
const sirv = require('sirv');
const puppeteer = require('puppeteer');

async function go() {
        const port = await ports.find(1234);
        console.log(`found available port: ${port}`);

        const server = http.createServer(sirv('test/public'));
        server.listen(port);

        await ports.wait(port).catch(() => {}); // workaround windows gremlins

        const browser = await puppeteer.launch({args: ['--no-sandbox']});
        const page = await browser.newPage();

        page.on('console', msg => {
                console[msg.type()](msg.text());
        });

        await page.goto(`http://localhost:${port}`);

        await page.evaluate(() => done);
        await browser.close();
        server.close();
}

go();

The nice thing about this code is that it is completely agnostic and should work with all projects using this setup.

Npm Scripts

{
  ...
  "scripts: {
    "build": "rollup -c",
    "autobuild": "rollup -cw",
    "test:browser": "npm run build && w3 test/public",
    "test": "node test/runner.js",
    "pretest": "npm run build"
  }
}

fin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment