Selenium Grid Hub+appiumの環境を作ったときのメモ

## はじめに
appiumはモバイルアプリケーションのためのテストフレームワークです。
テストを実行するとappiumを経由してAndiroidやiOSのシミュレーターの中でテストに書いた操作が実行されます。
今回はSelenium Grid Hubとappiumを組み合わせで使うときのMacでの環境構築をしたときのメモです。
(homebrewが入っている前提)

## ゴール
selenium webdriverで書いた操作をappium経由でiOSのシミュレーターとAndroidのシミュレーターで動くようにする。

(※Xcode8.1+iOS10の環境で動かす方法は調べきれていません。
http://appium.io/slate/en/v1.6.0/?ruby#testing-using-xcode-8-including-ios-10-with-xcuitest
これを見ると、どうもcarthageを使う方法があるみたいなんですがよくわからんかったです。教えてエロい人)


## 環境
| ソフトウェア | バージョン       |
|:-:|:-:|
| OS | Mac OS X El Capitan |
| appium | 1.6.0 |
| node.js | 7.2.0 |
| Selenium Standalone Server | 3.0.1 |
| Android Studio | 2.2.2 |
| JDK | 8 |
| Xcode | 7.3.1 |
| ruby | 2.3.1p112 |
| selenium-webdriver | 3.0.3 |


## 必要になるものをインストール
### brew cask
```bash:bash
brew tap caskroom/cask
```
### Selenium Standalone Server
下記URLからSelenium Standalone Serverをダウンロード
http://www.seleniumhq.org/download/

### JDK
```bash:bash
brew cask install java
```

### Android Studio
```bash:bash
brew cask android-studio
```
Android Studioの設定は省略

### Xcode
7.3.1をダウンロード
https://developer.apple.com/download/more/

dmgをダウンロードしてインストールしますが、僕の環境ではXcode8.1も入っているため"Xcode_7.3.1"にリネームしました
![スクリーンショット 2016-12-04 13.25.12.png](https://qiita-image-store.s3.amazonaws.com/0/2282/3b39bd7b-c1f6-af85-a6d2-42ab38c44db3.png)

### carthage
```bash:bash
brew install carthage
```

### node.js
```bash:bash
brew install node
```

### appium
```bash:bash
npm install appium@1.6.0
```

### appium-doctor
```bash:bash
npm install appium-doctor
```

### selenium-webdriver
```bash:bash
gem install selenium-webdriver --no-document
```

## 事前準備
### appium-doctorを実行
```bash:bash
appium-doctor
```

### 環境変数を設定
bashrcとかに書いといたらいいと思います

```bash:bash
export JAVA_HOME="/Library/Java/Home"
export PATH="$JAVA_HOME/bin:$PATH"
export ANDROID_HOME="/Users/kytiken/Library/Android/sdk"
```
ANDROID_HOMEの値はAndroid StudioのPreferencesに書いてあった。
![スクリーンショット_2016-12-04_14_31_35.png](https://qiita-image-store.s3.amazonaws.com/0/2282/fa43fcf5-53df-0ceb-41d3-b1b0bd193cb5.png)


### Selenium Grid Hubを起動
```bash:bash
java -jar selenium-server-standalone-3.0.1.jar -role hub
```
(参考)http://docs.seleniumhq.org/docs/07_selenium_grid.jsp

## iOSで動かす
nodeconfig.jsonファイルを作る

```json:nodeconfig.json
{
  "capabilities":
  [
    {
      "platformName": "iOS",
      "platformVersion": "9.3",
      "deviceName": "iPhone 6s",
      "browserName": "Safari",
      "language": "ja",
      "maxInstances": 1,
      "platform": "MAC"
    }
  ],
  "configuration":
  {
    "cleanUpCycle":2000,
    "timeout":30000,
    "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
    "url":"http://localhost:4723/wd/hub",
    "host": "localhost",
    "port": 4723,
    "maxSession": 1,
    "register": true,
    "registerCycle": 5000,
    "hubPort": 4444,
    "hubHost": "localhost"
  }
}
```
(参考)http://appium.io/slate/en/v1.6.0/?ruby#appium-server-capabilities

appiumを起動

```bash:bash
export DEVELOPER_DIR=/Applications/Xcode_7.3.1.app
appium --nodeconfig nodeconfig.json
```

selenium-webdriverを使う

```rb:ios_sample.rb
require 'selenium-webdriver'

SERVER_URL = 'http://localhost:4444/wd/hub'
capabilities = {
  'platformName' => 'iOS',
  'browserName' => 'Safari',
  'deviceName' => 'iPhone 6s'
}
driver = Selenium::WebDriver.for(:remote, :desired_capabilities => capabilities, :url => SERVER_URL)
driver.navigate.to "http://google.co.jp"

puts driver.title

driver.quit
```
(参考)https://github.com/SeleniumHQ/selenium/wiki/Ruby-Bindings#remote

```bash:bash
ruby ios_sample.rb
```

## Androidで動かす
AVDマネージャからシミュレーターを起動
![スクリーンショット_2016-12-04_14_45_32.png](https://qiita-image-store.s3.amazonaws.com/0/2282/d14dd684-cf83-285a-62f4-4ef03d145905.png)

<img width="518" alt="スクリーンショット 2016-12-04 14.48.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/2282/1f49610b-f000-5441-3011-a8f469ea38b5.png">


nodeconfig.jsonファイルを作る

```json:nodeconfig.json
{
  "capabilities":
  [
    {
      "platformName": "Android",
      "platformVersion": "7.1.1",
      "deviceName": "Nexus 5",
      "browserName": "Chrome",
      "language": "ja",
      "maxInstances": 1,
      "platform": "Android"
    }
  ],
  "configuration":
  {
    "cleanUpCycle":2000,
    "timeout":30000,
    "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
    "url":"http://localhost:4723/wd/hub",
    "host": "localhost",
    "port": 4723,
    "maxSession": 1,
    "register": true,
    "registerCycle": 5000,
    "hubPort": 4444,
    "hubHost": "localhost"
  }
}
```
(参考)http://appium.io/slate/en/v1.6.0/?ruby#appium-server-capabilities

appiumを起動

```bash:bash
appium --nodeconfig nodeconfig.json
```

selenium-webdriverを使う

```rb:android_sample.rb
require 'selenium-webdriver'

SERVER_URL = 'http://localhost:4444/wd/hub'
capabilities = {
  'platformName' => 'Android',
  'browserName' => 'Chrome',
  'deviceName' => 'Nexus 5'
}
driver = Selenium::WebDriver.for(:remote, :desired_capabilities => capabilities, :url => SERVER_URL)
driver.navigate.to "http://google.co.jp"

puts driver.title

driver.quit
```
(参考)https://github.com/SeleniumHQ/selenium/wiki/Ruby-Bindings#remote

```bash:bash
ruby android_sample.rb
```

## nodeconfigの書き方
説明のために分けて書きましたが１つに書いたらいいです

```json:nodeconfig.json
{
  "capabilities":
  [
    {
      "platformName": "iOS",
      "platformVersion": "9.3",
      "deviceName": "iPhone 6s",
      "browserName": "Safari",
      "language": "ja",
      "maxInstances": 1,
      "platform": "MAC"
    },
    {
      "platformName": "Android",
      "platformVersion": "7.1.1",
      "deviceName": "Nexus 5",
      "browserName": "Chrome",
      "language": "ja",
      "maxInstances": 1,
      "platform": "Android"
    }
  ],
  "configuration":
  {
    "cleanUpCycle":2000,
    "timeout":30000,
    "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
    "url":"http://localhost:4723/wd/hub",
    "host": "localhost",
    "port": 4723,
    "maxSession": 1,
    "register": true,
    "registerCycle": 5000,
    "hubPort": 4444,
    "hubHost": "localhost"
  }
}
```
(参考)http://appium.io/slate/en/v1.6.0/?ruby#appium-server-capabilities

## さいごに
ものぐさな人(自分)のためにansible-playbookを作りました
https://github.com/kytiken/selenium_grid_hub_and_appium_sample