Vagrant + Selenium + node.js(CodeceptJS)でIE, Chrome, FirefoxのマルチブラウザE2Eテスト

# なぜこの文章を書いたか？
普段PHPで色々なプログラムを書いていて、puppeteerを使った事はあるものの、そういえばSeleniumって避けて通っていたなと今更ながら環境構築をしてみようと思い立ったのでした。
でもいざ環境構築をしようとすると情報が分散されていてまとまっているところが少なかったので。

# 環境
OS : macOS Mojave (10.14.3)
VirtualBox : 6.0.4
Vagrant : v2.2.3
node.js : 10.15.1

# インストール
## IE11 on Win81
### boxファイルのダウンロード
以下のURLから`IE11 on Win81 (x86) > Vagrant`のZIPをダウンロード
https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/

### boxファイルの展開
ダウンロードしたらZIPを展開し、box追加を実行。

```bash

$ vagrant box add IE11-Win81 ./IE11\ -\ Win81.box
```

### Vagrantfileの作成
以下のVagrantfileを作成

```ruby
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
  config.vm.box = "IE11-Win81"
  config.vm.guest = :windows
  config.vm.communicator = "winrm"
  config.vm.network "private_network", ip: "192.168.33.200"
  config.vm.network "forwarded_port", guest: 4444, host: 4444
  config.vm.provider "virtualbox" do |vb|
    vb.memory = 4096
    vb.cpus = 2
    vb.gui = true
    vb.customize [
      "modifyvm", :id,
      "--vram", "256",
      "--clipboard", "bidirectional",
    ]
  end
end
```

### Windows8.1の起動

```bash
$ vagrant up
```

### Guest Additionsのインストール

`メニュー > Devices > Insert Guest Additions CD Image...` を選択
マウントされたらエクスプローラからCDをダブルクリックしてGuest Additionsのインストール

### JREのインストール
以下のURLからJREをダウンロードしてインストール
https://www.java.com/ja/download/manual.jsp

### Selenium Server Standalone, IEDriverServer_Win64のダウンロード
以下のURLからSelenium Server StandalneとIEDriverServer_Win64をダウンロード
https://www.seleniumhq.org/download/
IEDriverServer.exeは展開し、`C:\Windows\`直下（もしくはPATHの通っている場所）に移動

### ChromeとFirefoxをインストール
（省略）

### ChromeDriverのインストール
以下のURLからChromeDriverをダウンロード
http://chromedriver.chromium.org/downloads
chromedriver.exeは展開し、`C:\Windows\`直下（もしくはPATHの通っている場所）に移動

### geckodriverのインストール
以下のURLからgeckodriverをダウンロード
geckodriver.exeは展開し、`C:\Windows\`直下（もしくはPATHの通っている場所）に移動

### IEのセキュリティ設定
`IE > Internet Options > Security > （各ゾーン） > Enable Protected Mode`のチェックを入れる

### レジストリの修正
`regedit.exe`を起動し、以下に`iexplore.exe`を`REG_DWORD`で`0`として追加。

```
\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BFCACHE
```

## node.jsの設定（ローカルマシン上）
### npm init

適当なフォルダを準備して、そこで`npm init`を実行。（Vagrantfileのあるフォルダ直下で実行しても良い）

```bash
$ npm init -y
```

### Codecept.jsのインストール

```bash
$ npm install codeceptjs --save-dev
```

### Codecept.jsの初期化

```bash
$ npx codeceptjs init


  Welcome to CodeceptJS initialization tool
  It will prepare and configure a test environment for you

Installing to /Users/xxxx/IE11.Win81.Vagrant/test
? Where are your tests located? ./*_test.js
? What helpers do you want to use? WebDriver
? Where should logs, screenshots, and reports to be stored? ./output
? Would you like to extend I object with custom steps? Yes
? Do you want to choose localization for tests? ja-JP
? Where would you like to place custom steps? ./steps_file.js
2019-03-04T16:40:22.830Z DEBUG @wdio/config: @wdio/sync not found, running tests asynchronous
Configure helpers...
? [WebDriver] Base url of site to be tested http://localhost
? [WebDriver] Browser in which testing will be performed chrome
Steps file created at /Users/xxxx/IE11.Win81.Vagrant/test/steps_file.js
Config created at /Users/xxxx/IE11.Win81.Vagrant/test/codecept.conf.js
Directory for temporary output files created at `_output`
Almost done! Create your first test by executing `codeceptjs gt` (generate test) command
```

# Selenium Serverの起動
jarフィルをダウンロードしたディレクトリで２つのコマンドプロンプトを起動し、以下のコマンドを実行（jarのバージョンが3.141.59とした場合）

```bash
java -jar selenium-server-standalone-3.141.59.jar -role hub
```

```bash
java -jar selenium-server-standalone-3.141.59.jar -role node -hub http://localhost:4444/grid/register
```

# テストの作成

```bash
$ npx codeceptjs gt
Creating a new test...
----------------------
? Filename of a test github
? Feature which is being tested Github
Test for github was created in /Users/xxxx/IE11.Win81.Vagrant/test/github_test.js
```

github_test.js を以下のように書き換え

```javascript
Feature('Github');

Scenario('test something', (I) => {
  I.amOnPage('https://github.com');
  I.see('GitHub');
});
```

# テストの起動

```bash
$ npx codeceptjs run --steps
2019-03-04T16:47:59.215Z DEBUG @wdio/config: @wdio/sync not found, running tests asynchronous
CodeceptJS v2.0.6
Using test root "/Users/xxxx/IE11.Win81.Vagrant/test"

Github --
  test something
    私は ページを移動する "https://github.com"
    私は テキストがあるか確認する "GitHub"
  ✔ OK in 4103ms


  OK  | 1 passed   // 7s
```

# IE, Chrome, Firefoxを使い分ける
`codecept.config.js`を修正する

```javascript
exports.config = {
  tests: './*_test.js',
  output: './output',
  helpers: {
    WebDriver: {
      url: 'http://localhost',
      browser: process.profile || 'internet explorer',
    }
  },
  include: {
    I: './steps_file.js'
  },
  bootstrap: null,
  mocha: {},
  name: 'test',
  translation: 'ja-JP'
}
```

## テスト起動

デフォルト（IEが起動）

```bash
$ npx codeceptjs run --steps
```

IEを明示的に指定

```
$ npx codeceptjs run --steps --profile 'internet explorer'
```

Chromeを指定

```
$ npx codeceptjs run --steps --profile chrome
```

Firefoxを指定

```
$ npx codeceptjs run --steps --profile firefox
```

## npm run testで起動できるように設定
`packege.json`を以下のように修正

```json
{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "npm run test:ie; npm run test:chrome; npm run test:firefox;",
    "test:ie": "codeceptjs run --steps --profile 'internet explorer'",
    "test:chrome": "codeceptjs run --steps --profile chrome",
    "test:firefox": "codeceptjs run --steps --profile firefox"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "codeceptjs": "^2.0.6"
  }
}
```

## npm run testから起動
IEを指定

```
$ npm run test:ie
```

Chromeを指定

```
$ npm run test:chrome
```

Firefoxを指定

```
$ npm run test:firefox
```

全部のせ

```
$ npm run test
```

# 終わりに

`vagrant up`がタイムアップしてしまう、`vagrant halt`が効かない、Windowsの設定を自動化していない、Selenium Serverの起動を自動化していない、などの問題が残っているので、どかで修正したいところ。