Angular2を使ったサイトのテストで　protractorを使うときの備忘録

#初めに
この環境でテストスクリプトを作っていくことになったので調査開始
とりあえず、チュートリアルを元に拡張していく手順で

#Could not find testability for element
　チュートリアルにあるサイトはAngularJSで作成されたサイトなのでAngularJS2を使ったサイトに切り替えたところ

```
Failed: Error while waiting for Protractor to sync with the page: "Could not find testability for element."
```
いきなりこんなメッセージが。困った。


##対応方法
調べたところ　configに下記の設定が追加が必要とのこと

```
  useAllAngular2AppRoots: true
```

公式のどこに載っているのか検索したところ

https://github.com/angular/protractor/blob/master/lib/config.ts

使用例も説明もない気がする・・・

実際には下記のように記述

```js:confg.js
exports.config = {
  seleniumAddress: 'http://127.0.0.1:4444/wd/hub'
  ,specs: ['spec.js']
  ,capabilities:{
    browserName:'chrome'
  }
  , useAllAngular2AppRoots: true
}
```

これで実行したところ期待通りに動きました。

```bash
> protractor test/conf.js

[13:00:30] I/hosted - Using the selenium server at http://127.0.0.1:4444/wd/hub
[13:00:30] I/launcher - Running 1 instances of WebDriver
Started
.


1 spec, 0 failures
Finished in 4.668 seconds
```

#Webdriver
## バージョン問題
まだインストールされるseleniumが３になっていない・・・・

```
$ webdriver-manager status
[14:26:04] I/status - selenium standalone version available: 2.53.1 [default]
[14:26:04] I/status - chromedriver version available: 2.25 [default]
[14:26:04] I/status - geckodriver version available: v0.9.0 [default]
[14:26:04] I/status - android-sdk is not present
[14:26:04] I/status - appium is not present
```

- selenium3で起動しないと　safariやFireFoxに対応できない。

12/26時点でのそれぞれのバージョン


| name | Ver |
|:--|:--|
| selenium|3.0.1|
| geckodriver|0.11.1|

- 実行時の動きを見てみる

```bash
$ webdriver-manager start
[17:47:52] I/start - Starting appium server
[17:47:52] I/start - java -Dwebdriver.chrome.driver=/usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.25 -Dwebdriver.gecko.driver=/usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/geckodriver-v0.9.0 -jar /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/selenium-server-standalone-2.53.1.jar
[17:47:52] I/start - seleniumProcess.pid: 2564
17:47:54.400 INFO - Launching a standalone Selenium Server
17:47:54.508 INFO - Java: Oracle Corporation 25.60-b23
17:47:54.508 INFO - OS: Mac OS X 10.11.6 x86_64
17:47:54.549 INFO - v2.53.1, with Core v2.53.1. Built from revision a36b8b1
17:47:54.689 INFO - Driver provider org.openqa.selenium.ie.InternetExplorerDriver registration is skipped:
registration capabilities Capabilities [{ensureCleanSession=true, browserName=internet explorer, version=, platform=WINDOWS}] does not match the current platform MAC
17:47:54.689 INFO - Driver provider org.openqa.selenium.edge.EdgeDriver registration is skipped:
registration capabilities Capabilities [{browserName=MicrosoftEdge, version=, platform=WINDOWS}] does not match the current platform MAC
17:47:54.690 INFO - Driver class not found: com.opera.core.systems.OperaDriver
17:47:54.690 INFO - Driver provider com.opera.core.systems.OperaDriver is not registered
17:47:54.694 INFO - Driver class not found: org.openqa.selenium.htmlunit.HtmlUnitDriver
17:47:54.694 INFO - Driver provider org.openqa.selenium.htmlunit.HtmlUnitDriver is not registered
17:47:55.350 INFO - RemoteWebDriver instances should connect to: http://127.0.0.1:4444/wd/hub
17:47:55.350 INFO - Selenium Server is up and running
```

よく見ると普通に起動コマンドを叩いているっぽい。
最新のドライバーを落としてきて、webdriver-managerコマンドに頼らず自分で叩いてみる・・・

```bash
$ java -Dwebdriver.chrome.driver=/usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.25 -Dwebdriver.gecko.driver=/Users/y/Downloads/geckodriver-v0.11.1 -jar /Users/y/Downloads/selenium-server-standalone-3.0.1.jar
```

動かせますね。（ただ、テスト結果がFだらけだったのは内緒だ　号泣）

そもそもは、落としてくるバージョンを最新版にしてくれれば良い話。

それっぽいファイルを書き換えてみる

```bash
$ cd /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager
$ cat config.json
{
  "webdriverVersions": {
    "selenium": "3.0.1",
    "chromedriver": "2.25",
    "geckodriver": "v0.11.1",
    "iedriver": "2.53.1",
    "androidsdk": "24.4.1",
    "appium": "1.5.3"
  },
  "cdnUrls": {
    "selenium": "https://selenium-release.storage.googleapis.com/",
    "chromedriver": "https://chromedriver.storage.googleapis.com/",
    "geckodriver": "https://github.com/mozilla/geckodriver/releases/download/",
    "iedriver": "https://selenium-release.storage.googleapis.com/",
    "androidsdk": "http://dl.google.com/android/"
  }
}
```

- アップデートしてみる

```bash
$ webdriver-manager update 
[18:32:26] I/update - chromedriver: file exists /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.25mac64.zip
[18:32:26] I/update - chromedriver: unzipping chromedriver_2.25mac64.zip
[18:32:26] I/update - chromedriver: setting permissions to 0755 for /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.25
[18:32:26] I/update - chromedriver: v2.25 up to date
[18:32:27] I/update - selenium standalone: file exists /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/selenium-server-standalone-2.53.1.jar
[18:32:27] I/update - selenium standalone: v2.53.1 up to date
[18:32:28] W/file_manager - geckodriver-v0.9.0-mac.tar.gz expected length undefined, found 1096885
[18:32:28] W/file_manager - removing file: /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/geckodriver-v0.9.0-mac.tar.gz
[18:32:28] I/downloader - geckodriver: downloading version v0.9.0
[18:32:28] I/downloader - curl -o /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/geckodriver-v0.9.0-mac.tar.gz https://github.com/mozilla/geckodriver/releases/download/v0.9.0/geckodriver-v0.9.0-mac.tar.gz
[18:32:30] I/update - geckodriver: unzipping /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/geckodriver-v0.9.0-mac.tar.gz
[18:32:30] I/update - geckodriver: setting permissions to 0755 for /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/geckodriver-v0.9.0
$
```

？？？？？ダメでした・・・
って、実は別に設定がある？

```
$ find ./ -name '*.json' -exec grep "selenium" {} /dev/null \;
.//built/config.json:    "selenium": "2.53.1",
.//built/config.json:    "selenium": "https://selenium-release.storage.googleapis.com/",
.//built/config.json:    "iedriver": "https://selenium-release.storage.googleapis.com/",
.//built/package.json:  "description": "A selenium server and browser driver manager for your end to end tests.",
.//built/package.json:    "selenium",
.//built/package.json:    "selenium-webdriver"
.//config.json:    "selenium": "3.0.1",
.//config.json:    "selenium": "https://selenium-release.storage.googleapis.com/",
.//config.json:    "iedriver": "https://selenium-release.storage.googleapis.com/",
.//package.json:  "description": "A selenium server and browser driver manager for your end to end tests.",
.//package.json:    "selenium",
.//package.json:    "selenium-webdriver"
```

そっち？
バックアップして書き換えてみる

```
$ cp built/config.json built/config.json.bk
$ vi built/config.json
```


クリアしてから

```
$ webdriver-manager clean
[18:42:46] I/file_manager - removed chromedriver_2.25
[18:42:46] I/file_manager - removed chromedriver_2.25mac64.zip
[18:42:46] I/file_manager - removed geckodriver-v0.9.0
[18:42:46] I/file_manager - removed geckodriver-v0.9.0-mac.tar.gz
[18:42:46] I/file_manager - removed selenium-server-standalone-2.53.1.jar
```

いざ！

```
$ webdriver-manager update 
[18:42:56] I/downloader - selenium standalone: downloading version 3.0.1
[18:42:56] I/downloader - curl -o /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/selenium-server-standalone-3.0.1.jar https://selenium-release.storage.googleapis.com/3.0/selenium-server-standalone-3.0.1.jar
[18:42:56] I/downloader - chromedriver: downloading version 2.25
[18:42:56] I/downloader - curl -o /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.25mac64.zip https://chromedriver.storage.googleapis.com/2.25/chromedriver_mac64.zip
[18:42:56] I/downloader - geckodriver: downloading version v0.11.1
[18:42:56] I/downloader - curl -o /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/geckodriver-v0.11.1-mac.tar.gz https://github.com/mozilla/geckodriver/releases/download/v0.11.1/geckodriver-v0.11.1-mac.tar.gz
[18:42:56] E/downloader - Error: Got code 404 from https://github.com/mozilla/geckodriver/releases/download/v0.11.1/geckodriver-v0.11.1-mac.tar.gz
[18:42:57] I/update - chromedriver: unzipping /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.25mac64.zip
[18:42:57] I/update - chromedriver: setting permissions to 0755 for /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.25
[18:42:57] E/downloader - Error: Got error Error: ENOENT: no such file or directory, stat '/usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/geckodriver-v0.11.1-mac.tar.gz' from https://github.com/mozilla/geckodriver/releases/download/v0.11.1/geckodriver-v0.11.1-mac.tar.gz
```


そうでした。名前変わったんですよね。どこで　mac.tar.gzを付与しているかいるか探してみる

```
$ find ./ -name '*' -exec grep "mac.tar.gz" {} /dev/null \;
.//built/lib/binaries/gecko_driver.js:        'Darwin': '-mac.tar.gz',
```

そのまま書き換える

```
$ vi built/lib/binaries/gecko_driver.js
```

一旦クリアして・・・

```
$ webdriver-manager clean
[18:46:51] I/file_manager - removed chromedriver_2.25
[18:46:51] I/file_manager - removed chromedriver_2.25mac64.zip
[18:46:51] I/file_manager - removed selenium-server-standalone-3.0.1.jar
```

再度アップデートしてみる

```
$ webdriver-manager update 
[18:46:56] I/downloader - selenium standalone: downloading version 3.0.1
[18:46:56] I/downloader - curl -o /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/selenium-server-standalone-3.0.1.jar https://selenium-release.storage.googleapis.com/3.0/selenium-server-standalone-3.0.1.jar
[18:46:56] I/downloader - chromedriver: downloading version 2.25
[18:46:56] I/downloader - curl -o /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.25mac64.zip https://chromedriver.storage.googleapis.com/2.25/chromedriver_mac64.zip
[18:46:56] I/downloader - geckodriver: downloading version v0.11.1
[18:46:56] I/downloader - curl -o /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/geckodriver-v0.11.1-macos.tar.gz https://github.com/mozilla/geckodriver/releases/download/v0.11.1/geckodriver-v0.11.1-macos.tar.gz
[18:47:00] I/update - chromedriver: unzipping /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.25mac64.zip
[18:47:01] I/update - chromedriver: setting permissions to 0755 for /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.25
[18:47:03] I/update - geckodriver: unzipping /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/geckodriver-v0.11.1-macos.tar.gz
[18:47:03] I/update - geckodriver: setting permissions to 0755 for /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/geckodriver-v0.11.1
```

- お！バージョンが上がった！！

```
$ webdriver-manager start
[18:56:53] I/start - java -Dwebdriver.chrome.driver=/usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.25 -Dwebdriver.gecko.driver=/usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/geckodriver-v0.11.1 -jar /usr/local/lib/node_modules/protractor/node_modules/webdriver-manager/selenium/selenium-server-standalone-3.0.1.jar
[18:56:53] I/start - seleniumProcess.pid: 3392
18:56:54.511 INFO - Selenium build info: version: '3.0.1', revision: '1969d75'
18:56:54.513 INFO - Launching a standalone Selenium Server
2016-12-26 18:56:54.609:INFO::main: Logging initialized @885ms
18:56:54.796 INFO - Driver provider org.openqa.selenium.ie.InternetExplorerDriver registration is skipped:
 registration capabilities Capabilities [{ensureCleanSession=true, browserName=internet explorer, version=, platform=WINDOWS}] does not match the current platform MAC
18:56:54.797 INFO - Driver provider org.openqa.selenium.edge.EdgeDriver registration is skipped:
 registration capabilities Capabilities [{browserName=MicrosoftEdge, version=, platform=WINDOWS}] does not match the current platform MAC
18:56:54.798 INFO - Driver class not found: com.opera.core.systems.OperaDriver
18:56:54.798 INFO - Driver provider com.opera.core.systems.OperaDriver registration is skipped:
Unable to create new instances on this machine.
18:56:54.798 INFO - Driver class not found: com.opera.core.systems.OperaDriver
18:56:54.799 INFO - Driver provider com.opera.core.systems.OperaDriver is not registered
2016-12-26 18:56:54.930:INFO:osjs.Server:main: jetty-9.2.15.v20160210
2016-12-26 18:56:55.021:INFO:osjsh.ContextHandler:main: Started o.s.j.s.ServletContextHandler@9629756{/,null,AVAILABLE}
2016-12-26 18:56:55.157:INFO:osjs.ServerConnector:main: Started ServerConnector@34023cae{HTTP/1.1}{0.0.0.0:4444}
2016-12-26 18:56:55.158:INFO:osjs.Server:main: Started @1435ms
18:56:55.164 INFO - Selenium Server is up and running
```

無事起動を確認！
公式はいつあげてくれるのかなぁ・・・

##Element locatorの調査方法

コマンドラインで確かめながら調査する方法が用意されています
(グローバルにインストールしているため呼び出しコマンドラインが長い・・・）

```bash
$ node /usr/local/lib/node_modules/protractor/bin/protractor ---elementexplorer
[15:27:21] I/local - Starting selenium standalone server...
[15:27:23] I/local - Selenium standalone server started at http://192.168.1.163:62670/wd/hub
[15:27:28] I/protractor -
[15:27:28] I/protractor - ------- Element Explorer -------
[15:27:28] I/protractor - Starting WebDriver debugger in a child process. Element Explorer is still beta, please report issues at github.com/angular/protractor
[15:27:28] I/protractor -
[15:27:28] I/protractor - Type <tab> to see a list of locator strategies.
[15:27:28] I/protractor - Use the `list` helper function to find elements by strategy:
[15:27:28] I/protractor -   e.g., list(by.binding('')) gets all bindings.
[15:27:28] I/protractor -
Starting debugger agent.
Debugger listening on [::]:5858
> browser . get ( 'http://www.angularjs.org' ) 
> element ( by . css ( 'h1' ) ) . getText ( ) 
[15:33:43] W/element - more than one element found for locator By(css selector, h1) - the first result will be used
HTML enhanced for web apps!
```

この状態で、ブラウザが起動するのでここでコマンドを打ちこみながら調査ができます。
これは便利そう。

が、これを　Angular2のサイトで試してみると・・・

```
> browser.getTitle()
Error: Error while waiting for Protractor to sync with the page: "Could not find testability for element."
```

どこかで見たことあるぞこのエラー

```
> browser.useAllAngular2AppRoots=true;
> browser
　　　：　中略
  useAllAngular2AppRoots: true }
> browser.getTitle()
Error: Error while waiting for Protractor to sync with the page: "Could not find testability for element."
```

パラメータをセットしてみたがダメだった・・・どういうこと？！

再調査！！
コマンドラインで　config設定をしてみる

```js:exconf.js
exports.config = {
  capabilities:{
    browserName:'chrome'
  }
  , useAllAngular2AppRoots: true
}
```

これでOKでした。やれやれ

```bash
$ node /usr/local/lib/node_modules/protractor/bin/protractor exconf.js --elementExplorer

> browser.get('http://demo.grapecity.com/wijmo/5/Angular2/Explorer/Explorer/#/grid/intro')
> browser.getTitle()
Wijmo 5エクスプローラ for Angular 2
```



参考
http://blog.ng-book.com/interactive-protractor-repl-with-elementexplorer/

##スクリーンショット
画面上に表示されないエリアも撮ってくれるかは別途調査が必要
これはブラウザドライバ側の仕様だけれど。

```
// at the top of the test spec:
var fs = require('fs');

// ... other code

// abstract writing screen shot to a file
function writeScreenShot(data, filename) {
    var stream = fs.createWriteStream(filename);

    stream.write(new Buffer(data, 'base64'));
    stream.end();
}

// ...

// within a test:
browser.takeScreenshot().then(function (png) {
    writeScreenShot(png, 'exception.png');
});
```

## console log
こうすればコンソールログに出力できるとある
 promisesが分かっていれば理解でくるということ？（現時点で理解できていません）

```js
browser.manage().logs()
  .get('browser').then(function(browserLog) {
  console.log('log: ' + 
    require('util').inspect(browserLog));
});
```

##VisualCode で debug 

公式に書いてあるがVisualCodeに組み込まれているnode.jsのデバックを使うことができる
Portractorで使うには

1.左端のデバックアイコンをクリック
2.デバック環境の選択をする。今回はもちろんnode.js
3.launch.json ファイルが作成表示されるので下記を追記する

```
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "プログラムの起動",
            "program": "${workspaceRoot}/index.js",    
            "cwd": "${workspaceRoot}"
        },
```

これを

```
    "version": "0.2.0",
    "configurations": [
        {
            "type": "node",
            "request": "launch",
            "name": "プログラムの起動",
　　　　　　　　　　　　　　　　　　　　　　 "program": "${workspaceRoot}/node_modules/protractor/bin/protractor",
  　　　　　　　　　　　　　　　　　　　　"args": ["${workspaceRoot}/conf.js"],
            "cwd": "${workspaceRoot}"
        },
```

パスとファイル名は適宜修正が必要（args で指定するのは　conf.jsであってデバック対象のjsファイルではない）
この設定で、ブレークポイントや、ステップ実行ができるようになる。

conf.js はこんな感じ

```
exports.config = {
  seleniumAddress: 'http://localhost:4444/wd/hub',
  specs: ['test/spec.js']
}
```

>Angular2 + Typescript + Visual Studio Codeでデバックするには“Debugger for Chrome“というのが要る?

(未検証だがこれを入れないと歯車アイコンが出てこなかった)

# とりあえず
いろいろと手探り状態なので、都度追記していこうと思います


##参考
http://ramonvictor.github.io/protractor/slides/#/

http://blog.ng-book.com/10-protractor-tips-for-better-e2e-tests/