# はじめに
E2EテストやWebスクレイビングするときに使うPuppeteerについて調べてみました。Googleのカンファレンスでも紹介されていたのとNode.jsを使うことがあるので、それに合わせてPuppeteerも使っていこうと思います。
# 準備
```bash
$ brew install yarn
$ yarn add puppeteer
$ yarn add -D [at]types/node typescript ts-node [at]types/puppeteer
```
# 最小限の構成
```json:package.json
{
"scripts": {
"test": "ts-node src/all.ts"
},
"dependencies": {
"puppeteer": "^5.2.1"
},
"devDependencies": {
"[at]types/node": "^14.6.4",
"[at]types/puppeteer": "^3.0.1",
"ts-node": "^9.0.0",
"typescript": "^4.0.2"
}
}
```
```json:tsconfig.json
{
"compilerOptions": {
"sourceMap": true,
"target": "es2017",
"module": "commonjs",
"lib": ["dom", "es2017"],
"outDir": "./dist",
"rootDir": "./src"
}
}
```
```typescript: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 = 'ttps://m.yahoo.co.jp'
await page.goto(url, {waitUntil: 'networkidle0'})
await page.screenshot({path: 'topPage.png', fullPage: true})
await browser.close()
})()
```
これらのファイルを置いて、以下を実行します。
```bash
$ 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テストも修正しないといけなくなり、無駄な工数がかかってしまうデメリットもあるので、適宜調節しつつテストを書いていくと良いかと思います。