From 2b09fd706ce6842ff2d16f23c9e843aab2869cd4 Mon Sep 17 00:00:00 2001 From: Fumihiro Xue Date: Sun, 17 Dec 2017 03:44:23 +0800 Subject: [PATCH] docs: add jest-puppeteer example --- docs/Puppeteer.md | 112 ++++++++++++++++++++++++++++++++++++++++++ website/sidebars.json | 1 + 2 files changed, 113 insertions(+) create mode 100644 docs/Puppeteer.md diff --git a/docs/Puppeteer.md b/docs/Puppeteer.md new file mode 100644 index 000000000000..22c4a7e67bcb --- /dev/null +++ b/docs/Puppeteer.md @@ -0,0 +1,112 @@ +--- +id: puppeteer +title: Using with puppeteer +--- + +With the +[Global Setup/Teardown](https://facebook.github.io/jest/docs/en/configuration.html#globalsetup-string) +and +[Async Test Environment](https://facebook.github.io/jest/docs/en/configuration.html#testenvironment-string) +APIs, Jest can work smoothly with +[puppeteer](https://github.com/GoogleChrome/puppeteer). + +## A jest-puppeteer example + +The basic idea is to: + +1. launch & file the websocket endpoint of puppeteer with Global Setup +2. connect to puppeteer from each Test Environment +3. close puppeteer with Global Teardown + +Here's an example of the GlobalSetup script + +```js +// setup.js +module.exports = function() { + return new Promise((resolve, reject) => { + puppeteer.launch().then(browser => { + // store the browser instance so we can teardown it later + global.__BROWSER__ = browser; + + // file the wsEndpoint for TestEnvironments + mkdirp.sync(DIR); + fs.writeFileSync(path.join(DIR, 'wsEndpoint'), browser.wsEndpoint()); + resolve(); + }); + }); +}; +``` + +Then we need a custom Test Environment for puppeteer + +```js +// puppeteer_environment.js +class PuppeteerEnvironment extends NodeEnvironment { + constructor(config) { + super(config); + } + + async setup() { + await super.setup(); + // get the wsEndpoint + const wsEndpoint = fs.readFileSync(path.join(DIR, 'wsEndpoint'), 'utf8'); + if (!wsEndpoint) { + throw new Error('wsEndpoint not found'); + } + + // connect to puppeteer + this.global.__BROWSER__ = await puppeteer.connect({ + browserWSEndpoint: wsEndpoint, + }); + } + + async teardown() { + await super.teardown(); + } + + runScript(script) { + return super.runScript(script); + } +} +``` + +Finally we can close the puppeteer instance and clean-up the file + +```js +// teardown.js +module.exports = function() { + return new Promise((resolve, reject) => { + // close the browser instance + global.__BROWSER__.close(); + + // clean-up the wsEndpoint file + rimraf.sync(DIR); + resolve(); + }); +}; +``` + +With all the things set up, we can now write our tests like this: + +```js +// test.js +describe( + '/ (Home Page)', + () => { + let page; + beforeAll(async () => { + page = await global.__BROWSER__.newPage(); + await page.goto('https://google.com'); + }, timeout); + + it('should load without error', async () => { + let text = await page.evaluate(() => document.body.textContent); + expect(text).toContain('google'); + }); + }, + timeout, +); +``` + +Here's the code of +[full working example](https://github.com/xfumihiro/jest-puppeteer-example). diff --git a/website/sidebars.json b/website/sidebars.json index f54d4a763775..a21fda4eb703 100644 --- a/website/sidebars.json +++ b/website/sidebars.json @@ -27,6 +27,7 @@ "timer-mocks", "manual-mocks", "webpack", + "puppeteer", "migration-guide", "troubleshooting" ]