最近puppeteerを使ったテストコードを書いたのでアウトプットしてみる

#初めに
皆さんこんにちは。
最近フロントのテストコードを書く経験をさせてもらっているので、アウトプットしたいと思います。
主にコードの書き方など具体的な内容になりますので、puppeteererの人は是非参考にしてみてください。
（読み方が未だにわからない・・・　パペッティア？パペティア？？）

#puppeteerとは
まずはpuppeteerとはなにかです。
公式には下記のように書かれています。

>
Puppeteerは、DevToolsプロトコル上でChromeやChromiumを制御するための高水準APIを提供するNodeライブラリです。Puppeteerはデフォルトではヘッドレスで動作しますが、完全な（ヘッドレスでない）ChromeやChromiumを動作させるように設定することができます。

要するに、Chromeブラウザ上でテキストいれたりボタン押したりできるよ〜〜ってことですね。
具体的に何ができるのか？

###何ができるのか

>
ブラウザで手動でできることのほとんどは、Puppeteerを使って行うことができます!
ここでは、いくつかの例をご紹介します。

>
・ページのスクリーンショットやPDFを作成する。
・SPA（シングルページアプリケーション）をクロールし、プリレンダリングコンテンツを生成（例：「SSR」（サーバーサイドレンダリング））。
・フォーム送信、UIテスト、キーボード入力などを自動化する。
・最新の自動テスト環境を構築します。最新バージョンのChromeで、最新のJavaScriptとブラウザの機能を使用して、テストを直接実行できます。
・サイトのタイムライン・トレースを取得し、パフォーマンスの問題点の診断に役立てることができます。
・Chromeの拡張機能をテストします。

https://github.com/puppeteer/puppeteer

なるほど。
ユーザーが操作することはあらかたできるようですね。
人力でやっていたリリース前のテスト入力とか楽になりそうです。

#使い方
公式のREADRE.mdに書いてありますね。

```javascript
yarn add puppeteer
or
npm i puppeteer
```

でインストールしてください。
実際にpuppeteer書いていきます。
後ほど解説いたします。
※公式参考

```javascript:test.js
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch(); //　→①
  const page = await browser.newPage(); // →②
  await page.goto('https://google.com'); // →③
  await page.screenshot({ path: 'example.png' }); //　→④

  await browser.close();　// →⑤
})();
```

```javascript
node test.js
```

で実行できます。
実行すると、グーグルのサイトに飛んで、スクリーンショットを撮影し、「example.png」で保存します。

では、①〜⑤の順番で細かく見ていきましょう。

このpuppeteerは非同期で実行するので、awaitを多用します。
そのため、非同期の理解が中途半端だと苦労します。※筆者はクソほど苦労しました

######①②の実行
```javascript
  const browser = await puppeteer.launch(); //　→①
  const page = await browser.newPage(); // →②
```

``puppeteer.launch()``でブラウザを起動します。
このメソッドの引数に色々設定することが出来、非常に面白いポイントになります。

①で定義し、②でブラウザを実際に起動しています。
下記にも記載してますが、
``headless: false``
にすると実際にブラウザが自動で立ち上がります。

書き方としてはこんな感じです。

```javascript
const browser = await puppeteer.launch({
  headless: false, /* ヘッドレスモードで起動するかどうか。デバッグ段階では false を設定することで動きを目視で確認できる */
  slowMo: 1000, /* 各操作の前に入れる遅延(ms)を設定 */
  defaultViewport: {
    /* 画面のサイズを設定。スクリーンショットを撮る場合は設定しておいたほうが良い */
    width: 1920,
    height: 1080,
  },
  timeout: 10000, /* ブラウザの開始を待つ最長時間(ms)を設定。タイムアウトを無効にする場合 0 を設定*/
  args: [
    '--incognito', /* ブラウザをシークレットモードで起動 */
  ],
});
```

簡単にまとめたのでいろいろ試してみてください。

|パラメータ|説明|
|:-----:|:---|
|headless|ブラウザをヘッドレスモードで実行するかどうか。 devtools オプションが true でない限りデフォルトは true 。|
|slowMo|Puppeteerの動作を指定されたミリ秒単位で遅らせる。何が起こっているかを見ることができて役に立つ。|
|devtools|各タブに DevTools パネルを自動的に開くかどうか。このオプションが true だと headless オプションは false に設定される。|
|dumpio|ブラウザの process stdout と stderr を process.stdout と process.stderr にパイプするかどうか。デフォルトは false 。|
|timeout|ブラウザインスタンスの開始を待つ最大時間（ミリ秒単位）。デフォルトは 30000 （30秒）。タイムアウトを無効にするには 0 を渡す。|
|args|ブラウザインスタンスに渡す追加の引数。|


|args オプション|説明|
|:-----:|:---|
|--no-startup-window|起動時にブラウザウィンドウを自動的に開かない（バックグラウンドアプリをホスティングする目的で Chrome を起動するときに使用される）|
|--no-referrers|HTTP-Referer ヘッダーを送信しない|
|--incognito|ブラウザをシークレットモードで直接起動する|
|--no-default-browser-check|デフォルトのブラウザチェックを無効にするデフォルトのブラウザ情報バーが表示されないようにするUI/ブラウザテストに役立つ|
|--hide-scrollbars|スクリーンショットのスクロールバーを非表示にする|
|--disable-infobars|一時廃止されたが復活した|
|--enable-automation|ユーザーにブラウザが自動テストによって制御されていることを通知する|

######③④の実行
```javascript
  await page.goto('https://google.com'); // →③
  await page.screenshot({ path: 'example.png' }); //　→④
```

③はgotoメソッドを用いて、引数のURLへ飛ぶことを指定しています。
④はscreenshotで画面のスクショを撮影してpathで保存するnameを指定することが出来ます。

pageからはいろいろなことができるのでちょっとまとめてみます。

|メソッド|説明|
|:---:|:-----------|
|page.type()|第一引数に``#id``や``.class``などを指定し、第二引数に``文字``を入れると指定したdomに入力してくれます。<br>ちなみに、idからたどることも可能です。<br>【例】<br>``page.type('#id > div > input[name="test"]', 'testと書いてみる')``<br>とするとinput name=testに「testと書いてみる」と入力されます。|
|page.select()|``await page.select('select[name="birthday_month"]', '12');``<br>value="12"のoption要素を選択します|
|page.click|page.click('a[href^="index.php?query="]');<br>正規表現も使えるので^=って書くと前方一致で探せます。index.php?query=から始まるhref属性を持つaタグをクリックしてくれます|

その他色々あるので下記参考してみてください！

https://qiita.com/go_sagawa/items/85f97deab7ccfdce53ea

https://qiita.com/rh_taro/items/32bb6851303cbc613124


ありがとうございましたーー！