iPhone SimulatorでJavaScriptの自動テストを動かす

Karma, Jasmine のテストコードを，Appium, Protractor を用いてiPhone Simulatorで動かす．

# 前提・検証環境
* OS X Yosemite 10.10.5
* Xcodeがインストールされていること
* 関連記事: [【Grunt + Karma + Jasmine】CoffeeScriptの開発環境を構築する](http://qiita.com/tanakaworld/items/cefeaf5c122210d362c9)

# Appiumの設定

npmでインストールする

```
$ npm install -g appium
$ appium -v
=> 1.4.13
```


シミュレータへのアクセスを許可する

```
$ authorize_ios
```

設定チェック

```
$ appium-doctor
```

![image](https://qiita-image-store.s3.amazonaws.com/0/31862/ef293b80-c4de-da1f-9604-db57cf7a104c.png)

今回はAndroidでは検証しないので「iOS checks were successful. 」だけ表示されればおｋ．


# JSプロジェクトの設定

## package.json

```
$ npm install grunt-contrib-connect --save-dev
$ npm install protractor --save-dev
$ npm install grunt-protractor-runner --save-dev
```

E2Eのテストフレームワーク [protractor](https://github.com/angular/protractor) を使用する．
AngularJS向けのフレームワークだが，Angularを用いてないJSプロジェクトでも使用できる．

protractorはv3.0.0以上だと，テスト実行時にエラーが発生する可能性がある．
[protractor Bug bug when started](https://github.com/angular/protractor/issues/2731)

![image](https://qiita-image-store.s3.amazonaws.com/0/31862/4b9074b0-2073-81ed-fcc8-0421aa4c4641.png)


そのため，v2.x系のバージョンに変更する．

```json:package.json
"devDependencies": {
  "protractor": "^2.5.1"
}
```

## protractor.conf.coffee

protractorの設定ファイルを新規作成する．

```coffeescript:protractor.conf.coffee
exports.config =
  seleniumAddress: 'http://localhost:4723/wd/hub',

  capabilities:
    browserName: 'safari'
    'appium-version': '1.4.13'
    platformName: 'iOS'
    platformVersion: '9.2'
    deviceName: 'iPhone 5'

  framework: 'jasmine2'
  specs: [
    'spec/e2e/**/*.coffee'
  ]
  baseUrl: 'http://localhost:9000'
  jasmineNodeOpts:
    showColors: true
    defaultTimeoutInterval: 30000
```
`'appium-version'` はインストールしたappiumのバージョンを，`platformVersion`, `deviceName` はマシンにインストールされているシミュレータのバージョンを指定しないとテストが実行できない．

# Gruntfile.coffee



```coffeescript:Gruntfile.coffee
connect:
      options:
        open: true
      e2e: options:
        open: false
        port: 9000
 protractor:
      options:
        keepAlive: true
        noColor: false
      e2e:
        options:
          configFile: 'protractor.conf.coffee'

grunt.loadNpmTasks 'grunt-contrib-connect'
grunt.loadNpmTasks 'grunt-protractor-runner'

grunt.registerTask 'spec-e2e', ['connect:e2e', 'protractor:e2e']
 ```

## テストコード

```html:spec/e2e/spec.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta content="width=device-width,initial-scale=1.0,minimum-scale=1.0,user-scalable=0" name="viewport" />
    <title>E2E template</title>
</head>
<body style="padding:0; margin:0">
<h1 id="title">E2E tempalte</h1>
</body>
</html>
```

```coffeescript:spec/e2e/e2eSpec.coffee
describe 'E2E', ->
  describe 'Verify', ->
    beforeEach ->
      browser.ignoreSynchronization = true
      browser.driver.get('http://localhost:9000/spec/e2e/e2e-template.html')

    it 'should have title', ->
      expect(browser.driver.getTitle()).toEqual('E2E template')
```

# テスト実行

Appniumを起動

```
$ appium &
```
![image](https://qiita-image-store.s3.amazonaws.com/0/31862/c505e004-bf66-c490-2bda-3b7f6454fdc5.png)

(別コンソールで)テストコマンド実行

```
$ grunt spec-e2e
```

シミュレータが起動しすると，Welcomeページ(Lets's browser!)が表示された後，beforeEachで実行しているページ(e2e-template.html)が表示されテストが実行される．

<img src="https://qiita-image-store.s3.amazonaws.com/0/31862/6d582808-0d80-5424-537c-20a8cad6e2b6.png" width="200"> -> <img src="https://qiita-image-store.s3.amazonaws.com/0/31862/87520188-e18f-39ec-3994-37f95db4c888.png" width="200"> -><img src="https://qiita-image-store.s3.amazonaws.com/0/31862/b217c8a4-a5e6-a9f9-964c-04684d639e53.png" width="200"> -> <img src="https://qiita-image-store.s3.amazonaws.com/0/31862/8479919b-06ae-291f-1461-a4524254d16c.png" width="200"> -> <img src="https://qiita-image-store.s3.amazonaws.com/0/31862/a12ba136-9fa6-7ef2-f14d-cbce17ec37a9.png" width="200">


![image](https://qiita-image-store.s3.amazonaws.com/0/31862/12163e67-8f53-22ef-232c-b11858120509.png)


# Appiumの実行終了する場合

```
$ killall -9 node
```

# 課題
現状，諸々の理由でプロダクションでは使用できていない．

* テスト実行が遅い
* Lets's browser!の画面で停滞してしまう時がある
* bodyタグ内のDOM要素がうまく取得できない

# 参考

* [Sample on GitHub](https://github.com/tanakaworld/coffeescript-project-sample/tree/protractor)
* [Setting Up Protractor with Appium - iOS/Safari](https://github.com/angular/protractor/blob/master/docs/mobile-setup.md#setting-up-protractor-with-appium---iossafari)