はじめに
E2EテストやWebスクレイビングするときに使うPuppeteerについて調べてみました。Googleのカンファレンスでも紹介されていたのとNode.jsを使うことがあるので、それに合わせてPuppeteerも使っていこうと思います。
Puppeteerのソースを見たい方は、こちらです。
準備
$ brew install yarn
$ yarn add puppeteer
$ yarn add -D @types/node typescript ts-node @types/puppeteer
最小限の構成
package.json
{
"scripts": {
"test": "ts-node src/all.ts"
},
"dependencies": {
"puppeteer": "^5.2.1"
},
"devDependencies": {
"@types/node": "^14.6.4",
"@types/puppeteer": "^3.0.1",
"ts-node": "^9.0.0",
"typescript": "^4.0.2"
}
}
tsconfig.json
{
"compilerOptions": {
"sourceMap": true,
"target": "es2017",
"module": "commonjs",
"lib": ["dom", "es2017"],
"outDir": "./dist",
"rootDir": "./src"
}
}
src/all.ts
import { launch } from 'puppeteer'
(async () => {
const puppeteer = require('puppeteer')
const browser = await launch({
headless: true
})
const page = await browser.newPage()
await page.emulate(puppeteer.devices['iPhone X'])
const url = 'https://m.yahoo.co.jp'
await page.goto(url, {waitUntil: 'networkidle0'})
await page.screenshot({path: 'topPage.png', fullPage: true})
await browser.close()
})()
これらのファイルを置いて、以下を実行します。
$ yarn test
launchで使えるオプション
オプション | 型 | 説明 |
---|---|---|
headless | boolean | ヘッドレスブラウザで起動するかどうか |
args | string[] | ブラウザに渡す引数 |
userDataDir | string | ユーザディレクトリのパス |
devtools | boolean | Chrome DevToolsを開くかどうか。 これをtrueにするとheadlessは、falseとなる。 |
ignoreHTTPSErrors | boolean | HTTPSのエラーを無視するかどうか |
defaultViewport.width | number | ブラウザの横幅 |
defaultViewport.height | number | ブラウザの縦幅 |
defaultViewport.deviceScaleFactor | number | 拡大率 |
defaultViewport.isMobile | boolean | モバイルかどうか |
defaultViewport.hasTouch | boolean | タッチをサポートするかどうか |
defaultViewport.isLandscape | boolean | 横画面にするかどうか |
slowMo | number | Puppeteerの操作を何ms遅らせるか |
timeout | number | タイムアウト(ms) |
page.gotoで使えるオプション
オプション | 型 | 説明 |
---|---|---|
referer | string | 付与するreferer |
waitUntil | string | どのイベントが発火されたら操作を開始するか。"load" or "domcontentloaded" or"networkidle0" or "networkidle2" |
page.screenshotで使えるオプション
オプション | 型 | 説明 |
---|---|---|
path | string | スクショを出力するパス |
type | string | 拡張子。"json" or "png" |
quality | number | 画像のクオリティ。0~100で指定する。 |
fullPage | boolean | 画面全体のスクショとするか |
clip.x | number | 切り取るときのx座標 |
clip.y | number | 切り取るときのy座標 |
clip.width | number | 切り取るときの横幅 |
clip.height | number | 切り取るときの縦幅 |
omitBackground | boolean | 白色のバックグラウンドカラーをつけるか |
encoding | string | 画像のエンコーディング。"base64" or "binary" |
おわりに
ユニットテストだけではテストしきれない部分があったり、いろいろなデバイス・環境で同じ操作のテストをしたいといったりE2Eテストには用途はたくさんあるかと思います。また、1度作ってしまえば、別の言語・FWに置き換えることになってもUIが変わらない限り使いまわせるメリットもあります。しかし、あまり細かく書いてしまうと改修を入れるたびにE2Eテストも修正しないといけなくなり、無駄な工数がかかってしまうデメリットもあるので、適宜調節しつつテストを書いていくと良いかと思います。
参考