E2Eテストの始め方 TestCafe③ -スクリーンショット編-

[E2Eテストの始め方 TestCafe① -導入編-](https://qiita.com/natsu_mikan/items/8f623ce3b0f518432bbf)
[E2Eテストの始め方 TestCafe② -セレクタについて-](https://qiita.com/natsu_mikan/items/c02ad4761670f7e61856)

今回はTestcafeでスクリーンショットを撮る方法について書いていきたいと思います！

#基本設定

```test.js
fixture('topページ')
  .page('http://example.com')
test('topスクショ', async t => {
  await t
    .takeScreenshot({
      path:'sample/top.png'
    })
})
```

```package.json
"screenshot": "testcafe chrome test.js --page-load-timeout 5000"
```

```
$ npm run screenshot
```


| オプション | 説明 |デフォルト値|
|:-----------|:------------|:------------|
| path       | スクリーンショットファイルの相対パスと名前       | ./screenshots        |

上記サンプルの場合、`./screenshots/sample/top.png`で保存されます。
基本はこれでスクショが撮れます。

##ページ全体のスクショを撮る

上記までの設定だと、画面で表示されている部分しか撮ってくれず、上から下までフルサイズを撮りたい場合にはオプションを追加してあげる必要があります。

| オプション | 説明 |デフォルト値|
|:-----------|:------------|:------------|
| fullPage       | オーバーフローのために表示されないコンテンツを含む、ページ全体をキャプチャする。       | false        |

```
.takeScreenshot({
  path:'sample/top.png',
  fullPage: true
})
```

##使えるプロパティ
その他用意されているプロパティは、

| オプション | 説明 |デフォルト値|
|:-----------|:------------|:------------|
| includeMargins       | ターゲット要素のmarginを含めるかどうか。<br>trueにすると`scrollTargetX`、上と左(または下と右)のmarginが交差するコーナーから、`scrollTargetY`および`crop`長方形の座標が計算される      | false        |
| includePaddings       | ターゲット要素のpaddingを含めるかどうか。<br>trueにすると`scrollTargetX`、`scrollTargetY`との`crop`。四角形の座標は、要素のコンテンツ領域の上端と左端(または下端と右端)が交差する角から計算される      | true        |
|scrollTargetX、scrollTargetY|ターゲット要素が大きすぎてブラウザウィンドウに収まらない場合は、ページがスクロールされ、このポイントがビューポートの中心に配置される。このポイントの座標は、ターゲット要素を基準にして計算される。数値が正の場合、ポイントは要素の左上隅を基準に配置される。<br>数値が負の場合、ポイントは右下隅を基準に配置。ターゲット要素がブラウザウィンドウに収まる場合、これらのプロパティは無視される。|要素の中心|
| crop       | スクリーンショットのターゲット要素をトリミングする     | 要素全体、またはビューポートに収まらない場合はその表示部分を切り抜く        |

`crop`プロパティに割り当てられたオブジェクトには、`top`、`left`、`bottom`、`right`があり、数値で指定します。

```test.js
test('topスクショ', async t => {
  await t
    .takeScreenshot({
      path:'sample/top.png',
      includeMargins: true,
      crop: {
        top: -100,
        left: 10,
        bottom: 30,
        right: 200
      }
    })
})
```

上記の「その他用意されているプロパティ」として紹介したものは、ボタンとか1セクションなどページの一部分を撮るような時に有効なプロパティかなと思います。

##アニメーションがあるページのスクショ

スクロールアニメーションが使われているページだとスクロールさせて要素を表示させてからスクショを撮らないと上手く写ってくれません。
そういう場合には別途処理を書いてあげる必要があります。


```test.js
import { ClientFunction } from 'testcafe';

// 下までスクロール
const scrollBottom = ClientFunction(function() {
  const elementHtml = document.documentElement
  const bottom = elementHtml.scrollHeight - elementHtml.clientHeight
  window.scroll(0, bottom)
})

// 一応、上までスクロールしたい場合も
const scrollTop = ClientFunction(function() {
window.scrollTo(0, 0)
})


fixture('topページ')
  .page('http://example.com')
test('topスクショ', async t => {
  await scrollBottom();
  await t
    .takeScreenshot({
      path:'sample/top.png',
    })
})
```

こんな感じでスクショ撮る前に処理を書いてあげれば良いかと。

その他に、アニメーションが終わってから処理をしたいなど**「指定された間、一時停止(待ち)たい」**こともあるかと思います。
その際には、`t.wait()`メソッドが有効です。


| メソッド | タイプ |説明|
|:-----------|:------------|:------------|
| t.wait( timeout )       | Number       | ミリ秒単位の一時停止期間        |


```test.js
test('topスクショ', async t => {
  await scrollBottom();
  await t
    .wait(5000)
    .takeScreenshot({
      path:'sample/top.png',
    })
})
```

##スマホサイズのスクショを撮る

PCとスマホ両方のスクショは撮りたいですよね！
そういう時に便利なメソッドも用意されています。

`t.resizeWindowToFitDevice( deviceName [, options] )`


| パラメータ | タイプ |説明|
|:-----------|:------------|:------------|
| deviceName       | String       | デバイスの名前        |
|options|Object|デバイスに関する追加情報

対応デバイスはiphone,ipad,galaxy,xperiaなどなど、かなりたくさんのデバイスがサポートされているので、
こちらの[デバイスリスト](https://github.com/DevExpress/device-specs/blob/master/viewport-sizes.json)からご確認ください。


`options`は次のプロパティを含めることができます。

| プロパティ | タイプ |説明|
|:-----------|:------------|:------------|
| portraitOrientation       | Boolean       | true : 縦向きの画面<br>false : 横向きの画面         |


```test.js
test('topスクショ', async t => {
  await t
    .resizeWindowToFitDevice('iphonexs', {
      portraitOrientation: true
    })
    .takeScreenshot({
      path:'sample/top.png',
    })
})
```

##ブラウザウィンドウサイズを指定 or 最大化する

###ウィンドウサイズを指定する
「任意のウィンドウサイズを指定したいな〜」って時にもメソッドがあります。

`t.resizeWindow( width, height )`

| パラメータ | タイプ |説明|
|:-----------|:------------|:------------|
| width       | Number       | ピクセル単位の新しい幅         |
| height       | Number       | ピクセル単位の新しい高さ         |


```test.js
test('topスクショ', async t => {
  await t
    .resizeWindow(300, 500)
    .takeScreenshot({
      path:'sample/top.png',
    })
})
```

###ウィンドウサイズを最大化する

こちらも使用しているモニターなどに合わせた、最大化されたウィンドウサイズの状態にしてくれるメソッドがあります。

`t.maximizeWindow( )`

```test.js
test('topキャプチャ', async t => {
  await t
    .maximizeWindow()
    .takeScreenshot({
      path:'sample/top.png',
    })
})
```


以上、Testcafeでスクリーンショットを撮る方法について書いてみました。
私も絶賛勉強中ですので、もっと良い方法がありましたら教えていただけると嬉しいです！