ProtractorをInternet Explorer 11で動かしてスクショをたくさん撮る


# やりたいこと

E2Eテストのときのエビデンスとして、IEでスクショたくさん撮ります

# 動作環境

Windows 10 1803
Internet Explorer 11

これよりも古い環境については動かないかもしれません。

# ざっくりした動かし方のゴール

```powershell
cd /path/to/project/root
npm install
# webdriverを動かす
npm run-script monitor
# テストを動かす
npm test
```

これで動かせるようにするところを目指します。

# 必要なもの

- node.js
- JRE

Protractorはjsで書かれたテストツールなのでnode.jsをインストールします。
また、Protractorの依存ライブラリであるSeleniumを動かすのにJavaが必要なので、JREも入れておきましょう。

# IEの設定

2018年12月現在だと、レジストリは操作しなくても大丈夫でした。
全てのゾーンで「保護モードを有効にする」にチェックを入れるだけで準備OKです。
変更のやり方は以下を参考にするとよいと思います。

[Internet Explorerの保護モードとは？ (1/2)： Tech TIPS - @IT](http://www.atmarkit.co.jp/ait/articles/1405/16/news128.html#change)

また、ズームが100%になっていないとテストが起動しません。
`Ctrl+0` でズーム倍率を100%にできるので、動かす前にやっておきましょう。

# 設定ファイルの更新

package.json のscriptsの部分を次のように修正します。 `prepare` は `install` でライブラリをインストールしたあとに続けて呼んでくれるようです。
余談ですが、Selenium driverの起動でエラーが起きて動かなくなったときに個別で実行してあげると高い確率で動くようになります。

```package.json
  "scripts": {
    "test": "protractor conf.js",
    "monitor": "webdriver-manager start",
    "prepare": "webdriver-manager update --ignore_ssl --ie"
  }
```

続けて、conf.js を次のように修正します。
IEはDirectConnectに対応していないのでオプションごと外しておきます。

```conf.js
exports.config = {
  seleniumAddress: 'http://localhost:4444/wd/hub',

  capabilities: {
   'browserName': 'internet explorer'
  },
  specs: ['test/myapp_spec.js'],

  jasmineNodeOpts: {
    showColors: true,
    defaultTimeoutInterval: 30000
  }
};
```

# スクリーンショットを撮る

いよいよスクリーンショットを撮ってみましょう。
なお、ProtractorはAngularに特化していますが別にAngularアプリでなくても使えます。
というわけで、Qiitaのこの記事を表示してスクリーンショットを撮るには次のようにします。

```myapp_spec.js

describe('take screenshot', function() {
  browser.get('https://qiit.com/4da49bca2620f3f48d02');

  browser.takeScreenshot().then(png => saveScreenshot(png, 'screenshot.png'));
});

function saveScreenshot(data, name) {
    var stream = fs.createWriteStream(process.env.NODE_SNAPSHOT_PATH + filename);
    stream.write(new Buffer(data, 'base64'));
    stream.end();
}
```

# 長いページのスクリーンショット

下のようなメソッドを書いて、ブラウザーをスクロールして、撮影範囲をずらすことで撮影していく手法を取っています。
今回は横方向へのスクロールが必要なかったので、縦方向のみずらしています。

```takeAllPage.js
function takeAllScreenshot(browser, filename) {
    // ファイル名の作成
    const file = filename.split(".");
    const extension = "." + file.pop();
    const path = file.join(".");

    // ページを取得する
    return browser.executeScript('return [document.body.scrollHeight, window.innerHeight];').then(result => {
        const contentHeight = result[0];
        const windowHeight = result[1];
        const pages = Math.ceil((1.0 * contentHeight) / windowHeight);
        console.log(`windowHeight: ${windowHeight}, contentHeight: ${contentHeight}`);
    
        for(let i = 0; i < pages ; i++) {
            browser.executeScript(`window.scrollTo(0,${windowHeight * i});`).then(() => {
                browser.takeScreenshot().then(data => saveScreenshot(data, `${path}_${i}${extension}`));
            });
        }
        return pages;
    });
}
```

# CSVを読み込んでケースを増やす

これだと1ケースしかないので、CSVを読み込んでケース数を増やしてみましょう。

この辺を参考にケース数を増やしています。

[jasmineでcsvからテストデータを読み込み、ロジックテスト。 by miz21358](https://qiita.com/miz21358/items/efe6e54acc7ec5501b52)

# 実際やってみると

手作業の1.5倍速くらいでスクショがたくさん撮れました。撮影中にも何かできるし、アサーションも当然書けるので頑張ればしっかり検証することもできます。せっかくテストツールを使っているので、期待結果と表示箇所がわかりやすいところだけでもアサーションをかけてやるといいでしょう。

# この方法での制約

**PowerShellが２つ必要です。** WebDriverを動かす用とProtractorを動かす用の2つが必要になります。
頑張ったら1つでできるようになると思いますが、やり方はまだわからない・・・
ちなみに、FirefoxとChromeだとDirectConnectが使えるのでPowerShellは1つで大丈夫です。
**あらかじめCSVファイルのケース数を知っておく必要あります。** 動的にテストケースを読み込んで件数を自動設定しようと思ったもののうまくいかず、ケース数を定数でコードに書いてお茶を濁しています。いい方法がないかしりたい…