Puppeteer provides a framework for building automated tests of websites, which also includes the ability to test Chrome Extensions. These are high-level end-to-end tests that test the functionality of a website or extension once it has been built into the final product. In this tutorial, we demonstrate how to write a basic test for an extension from our samples repository.
Before you start
Clone or download the chrome-extensions-samples repository. We'll use the history
API demo in api-samples/history/showHistory
as our test extension.
You'll also need to install Node.JS which is the runtime Puppeteer is built on.
Writing your test
Step 1: Start your Node.JS project
We need to set up a basic Node.JS project. In a new folder, create a package.json
file with the
following:
pacakge.json:
{
"name": "puppeteer-demo",
"version": "1.0"
}
Similar to an extension's manifest.json
file, this file is required by all Node projects.
Step 2: Install Puppeteer and Jest
Run npm install puppeteer jest
to add Puppeteer and Jest as dependencies. They will be
automatically added to your package.json
file.
It is possible to write standalone Puppeteer tests, but we'll use Jest as a test runner to provide some additional structure to our code.
Step 3: Create an entry point
Create a new file called index.test.js
and add the following code:
index.test.js:
const puppeteer = require('puppeteer');
const EXTENSION_PATH = '../../api-samples/history/showHistory';
const EXTENSION_ID = 'jkomgjfbbjocikdmilgaehbfpllalmia';
let browser;
beforeEach(async () => {
// TODO: Launch the browser.
});
afterEach(async () => {
// TODO: Close the browser.
});
Step 4: Launch the browser
Update beforeEach
and afterEach
to launch and close the browser. When running many tests, you
may wish to consider using the same browser. However, this is generally discouraged as it reduces
the isolation between your tests and may cause one test to impact the outcome of another.
index.test.js:
beforeEach(async () => {
browser = await puppeteer.launch({
headless: false,
args: [
`--disable-extensions-except=${EXTENSION_PATH}`,
`--load-extension=${EXTENSION_PATH}`
]
});
});
afterEach(async () => {
await browser.close();
browser = undefined;
});
Step 5: Add an alias
To make running the tests easier, add an alias to your package.json
file:
package.json:
{
"name": "puppeteer-demo",
"version": "1.0",
"dependencies": {
"puppeteer": "^21.3.6"
},
"scripts": {
"start": "jest ."
}
}
This will run all files ending in .test.js
in the current directory.
Step 6: Open the popup
Let's add a basic test that opens the popup in a new page. We need to do this because Puppeteer does not support accessing an extension popup from the popup window. Add the following code:
index.test.js:
test('popup renders correctly', async () => {
const page = await browser.newPage();
await page.goto(`chrome-extension://${EXTENSION_ID}/popup.html`);
});
Step 7: Assert the current state
Let's assert something, so that our test can fail if the extension isn't behaving as expected. We know that our popup should show recently visited pages, so let's check that we see one:
index.test.js:
test('popup renders correctly', async () => {
const page = await browser.newPage();
await page.goto(`chrome-extension://${EXTENSION_ID}/popup.html`);
const list = await page.$('ul');
const children = await list.$$('li');
expect(children.length).toBe(1);
});
Step 8: Run your test
To run the test, use npm start
. You should see output indicating that your test passed.
You can see the full project in our chrome-extensions-samples repository.
Next Steps
After mastering the basics, try building a test suite for your own extension. The Puppeteer API reference contains more information about what's possible - there are many capabilities not described here.