Easy browser testing with Poi and Puppeteer
Tags: test, puppeteer, poi, webpack
Published: 2018-12-16 14:06:32

---
title: Easy browser testing with Poi and Puppeteer
published: true
description: 
tags: 
 - test
 - puppeteer
 - poi
 - webpack
---

[Poi](https://poi.js.org) is a modular tooling for modern web development, a few days ago I released a Poi plugin called Puppet which runs your code inside a browser.

This plugin uses [Puppeteer](https://github.com/GoogleChrome/puppeteer) under the hood, it launches the existing Chrome browser on your machine to run tests.

## Getting Started with Puppet

If you don't have an existing Poi project, run following command to create one:

```bash
npx create-poi-app test-puppet
# You don't need to select any features from the CLI prompts
# Just press Enter
```

Then install this plugin in your project:

```bash
yarn add @poi/plugin-puppet --dev
```

Now you can run a new command `poi puppet` provided by this plugin like this:

```bash
yarn poi puppet --test --plugin @poi/puppet --framework mocha
```

<img src="https://thepracticaldev.s3.amazonaws.com/i/jl8gv6z7v1kripru8fek.png" width="600" alt="test error">

There's some error because `poi puppet` command will only bundle and run `**/*.test.js` in the browser, now let's create one.

`App.test.js`:

```js
import assert from 'assert'
import App from './App'

describe('App', () => {
  it('says hello', () => {
    assert(App.textContent === 'hello')
  })
})

```

`App.js`:

```js
const App = document.createElement('div')
App.textContent = 'hello'

export default App
```

Before we run the test command again, I would like to configure that in npm scripts  so we don't need to type such a long command every time:

```json
{
  "scripts": {
    "test": "poi puppet --test --plugin @poi/puppet --framework mocha",
    "build": "poi --prod",
    "dev": "poi --serve"
  }
}
```

Now it would be as simple as running `npm t`:

<img src="https://thepracticaldev.s3.amazonaws.com/i/ab101zv4k01qjko65ilu.png" alt="working test" width="600">


## Custom Assertion Library

We added `--framework mocha` flag in the above command we ran to use Mocha as the testing framework, Mocha doesn't come with a built-in assertion library so we are using Node.js's built-in `assert` module. However if you want more descriptive assertion messages, you can combine the `assert` module with [power-assert](https://github.com/power-assert-js/power-assert).

Let's tweak our test file to create a failing test:

```diff
import assert from 'assert'
import App from './App'

describe('App', () => {
  it('says hello', () => {
-   assert(App.textContent === 'hello')
+   assert(App.textContent === 'hello there')
  })
})
```

Run the test to see the default assertion message:

<img src="https://thepracticaldev.s3.amazonaws.com/i/6t183xp07127w0fens2k.png" alt="assert message default" width="600">

It's hard to tell what's actually going wrong in your tests from the error message, the only thing you get is `false !== true` which is kinda useless.

Now let's add `power-assert` by adding a Babel preset.

`babel.config.js`:

```js
module.exports = {
  presets: [
    // Add Poi's default preset first
    'poi/babel',
    'power-assert'
  ]
}
```

Don't forget to install `power-assert`:

```bash
yarn add power-assert babel-preset-power-assert --dev
```

Finally let's run the tests again:

<img src="https://thepracticaldev.s3.amazonaws.com/i/4jgbvkl1jxgxt98o1g28.png" width="600" alt="power assert message">

<small>_You can ignore the `Critical dependency: the request of a dependency is an expression` warning, [see this gist for how to suppress this warning](https://gist.github.com/egoist/82bd6c394f94fa301cc76477fc272244)._</small>


Failed again, but now you can actually get the actual and expected value of `App.textContent` from the error message, sweet!

## Links

- [Example code on GitHub](https://github.com/poi-bundler/examples/tree/master/examples/testing-with-puppet).
- [@poi/plugin-puppet Docs](https://poi.js.org/guide/plugin-puppet.html).