Latest news about Bitcoin and all cryptocurrencies. Your daily crypto news habit.
Last year a tool called āPuppeteerā was released by the Chrome Developers team. This tool is a headless Chrome, which means that with it you can interact with and visit websites programmatically. This is a powerful concept that has manyĀ uses.
CodeSandbox uses Puppeteer extensively nowadays. I want to explain in 2 posts how we use Puppeteer. In this post I will explain why and how we use Puppeteer for our test suite. In the next post I will cover how we use Puppeteer and serverless functions to generate previews and metadata for sandboxes (projects).
But Why?
In CodeSandbox we do all bundling of the sandbox code in the browser, Iāve built a custom bundler to do this. We still make changes and add features to this bundler, so itās crucial that we extensively test if the changes affect existing sandboxes built byĀ users.
Before
Iāve always kept a list of ātestā sandboxes and would load every sandbox manually to see if they still worked. As you can probably expect, this proved to be very time consuming as the list kept growing beyond 20 sandboxes and we started getting more contributions. Puppeteer to theĀ rescue!
Solution
Puppeteer has a really nifty function called screenshot (you can try it here). The function does exactly what it describes: it takes a screenshot of the current webpage and returns the Buffer of the screenshot. For CodeSandbox we can use this as a snapshot tool: after every commit we take a screenshot of all test sandboxes and compare them with the previously stored screenshots. If thereās a difference of more than 1% we fail the testĀ suite.
Implementation
I decided to use Jest for running all tests. We start by setting up an array of sandboxes toĀ test:
This is a list of sandbox ids, of which some have extra options like a more tolerant threshold. We iterate this list to create testĀ cases:
The biggest question was how to take a screenshot of a single sandbox. This turned out to be quite simple, we already support opening a sandbox as a separate page by going to https://:id.codesandbox.io (example: https://vue.codesandbox.io). So the only thing left for me was adding this functionality to the development server, so we can create screenshots with the new code. I ended up changing our webpack config to have a ātestā mode, this mode will only build the sandbox bundler and host it at http://localhost:3001#:id (example: http://localhost:3001#vue). Note that we set the id as a hash, this way we donāt interfere with the routing of theĀ sandbox.
A generated screenshot of a todo reduxĀ example
After having this set up it was fairly straightforward to build the rest. Thereās already a library for comparing screenshots called jest-image-snapshot. This library exposes toMatchImageSnapshot on expect, which works almost exactly the same as toMatchSnapshot.
The final implementation looks likeĀ this:
You can see in the code that we expose a function called window.__puppeteer__. The bundler calls window.__puppeteer__ when itās finished, this function is exposed by puppeteer so we can exactly know when we can take the screenshot. The generated screenshots are then saved in the GitHub repo. You can find themĀ here.
We run these tests using CircleCI, but we need to generate the initial screenshots locally. To ensure that we generate similar screenshots as CircleCI we generate screenshots using a docker container. We have a simple script which we just run to generate new screenshots:
I have set up a simple workflow for CircleCI to start the test server and simultaneously run the tests. These tests are run in a docker container that has Puppeteer preinstalled.
The workflow of CodeSandbox, notice the test-integrations step
We save all diffs as artifacts, so we can easily compare the screenshots. You can see a list of artifacts of a recent test run here: https://circleci.com/gh/CompuIves/codesandbox-client/4291#artifacts/containers/0.
A diff artifact: the arrows are different
Conclusion
The implementation turned out to be quite simple, but it has saved me a lot of time already. We now test a little over 20 sandboxes for every commit and PR. I also noticed that Iām more inclined to add sandboxes to the test suite too, which made the bundler more stable inĀ general.
In the next post I will cover how we use Puppeteer with serverless functions to generate metadata and oEmbed tags for sandboxes. You can follow my Twitter @CompuIves or @codesandboxapp to stay up toĀ date!
If youāre interested in the code; all code that was described here (and of CodeSandbox) is open source on GitHub. You can find the main repository here:
I hope you found the post interesting, donāt hesitate to respond with more ideas and uses for Puppeteer!
How CodeSandbox uses Puppeteer & Jest to test sandbox functionality was originally published in Hacker Noon on Medium, where people are continuing the conversation by highlighting and responding to this story.
Disclaimer
The views and opinions expressed in this article are solely those of the authors and do not reflect the views of Bitcoin Insider. Every investment and trading move involves risk - this is especially true for cryptocurrencies given their volatility. We strongly advise our readers to conduct their own research when making a decision.