DEV Community

EGOIST
EGOIST

Posted on

Easy browser testing with Poi and Puppeteer

Poi 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 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:

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

Then install this plugin in your project:

yarn add @poi/plugin-puppet --dev
Enter fullscreen mode Exit fullscreen mode

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

yarn poi puppet --test --plugin @poi/puppet --framework mocha
Enter fullscreen mode Exit fullscreen mode

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:

import assert from 'assert'
import App from './App'

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

Enter fullscreen mode Exit fullscreen mode

App.js:

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

export default App
Enter fullscreen mode Exit fullscreen mode

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:

{
  "scripts": {
    "test": "poi puppet --test --plugin @poi/puppet --framework mocha",
    "build": "poi --prod",
    "dev": "poi --serve"
  }
}
Enter fullscreen mode Exit fullscreen mode

Now it would be as simple as running npm t:

working test

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.

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

import assert from 'assert'
import App from './App'

describe('App', () => {
  it('says hello', () => {
-   assert(App.textContent === 'hello')
+   assert(App.textContent === 'hello there')
  })
})
Enter fullscreen mode Exit fullscreen mode

Run the test to see the default assertion message:

assert message default

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:

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

Don't forget to install power-assert:

yarn add power-assert babel-preset-power-assert --dev
Enter fullscreen mode Exit fullscreen mode

Finally let's run the tests again:

power assert message

You can ignore the Critical dependency: the request of a dependency is an expression warning, see this gist for how to suppress this warning.

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

Links

Top comments (4)

Collapse
 
aarmora profile image
Jordan Hansen

Hey Egoist!

Thanks for the post.

Do you think this would be something where you could test against something you didn't have the code for? Like what if you just pointed puppeteer at a deployed environment and kind of mounted mocha against that.

What have you here seems to go that direction.

Collapse
 
maininfection profile image
Ricardo Machado

Nice post.
Since you're using yarn you can run yarn create poi-app test-puppet.

Thanks, will definitely check it up! 👍

Collapse
 
egoist profile image
EGOIST

You're right, I've no idea why I used npx in the example 😂 npm init poi-app test-puppet should also work.

Collapse
 
mattauckland profile image
Mat

I'm surprised at how little the regular assert tells you 🤔
Nice write up