ChromeDriverで起動したGoogle Chromeでユーザーデータを使って、パスワード入力を省く

ChromeDriverで起動したGoogle Chromeでパスワード入力画面に来たとき、パスワードをコードに書くのははばかれるし、入力処理を書くのも面倒なので、ユーザーデータのパスワードを使うようにする[^1]。

まず、ChromeDriverを[Downloads - ChromeDriver - WebDriver for Chrome](https://sites.google.com/a/chromium.org/chromedriver/downloads)からダウンロードする。

ダウンロードしたChromeDriverを起動する。

```
$ ./chromedriver
Starting ChromeDriver 2.25.426935 (820a95b0b81d33e42712f9198c215f703412e1a1) on port 9515
Only local connections are allowed.
```

ポート番号9515で待ち受けるので、curlでリクエストを送る[^2]。

```
$ curl -X POST \
       -H "Content-Type: application/json" \
       -d '{"desiredCapabilities":{"browserName":"chrome"}}' \
       http://localhost:9515/session
{
  "sessionId": "e106d40aa97073eaf2cfc4b7341935d2",
  "status": 0,
  "value": {
    "acceptSslCerts": true,
    "applicationCacheEnabled": false,
    "browserConnectionEnabled": false,
    "browserName": "chrome",
    "chrome": {
      "chromedriverVersion": "2.25.426935 (820a95b0b81d33e42712f9198c215f703412e1a1)",
      "userDataDir": "/var/folders/8s/2xqcrr5j45dgtkx3jmnc3clr0000gn/T/.org.chromium.Chromium.HVoScs"
    },
    "cssSelectorsEnabled": true,
    "databaseEnabled": false,
    "handlesAlerts": true,
    "hasTouchScreen": false,
    "javascriptEnabled": true,
    "locationContextEnabled": true,
    "mobileEmulationEnabled": false,
    "nativeEvents": true,
    "networkConnectionEnabled": false,
    "pageLoadStrategy": "normal",
    "platform": "Mac OS X",
    "rotatable": false,
    "takesHeapSnapshot": true,
    "takesScreenshot": true,
    "version": "55.0.2883.75",
    "webStorageEnabled": true
  }
}
```

Google Chromeがバックグラウンドが立ち上がる（レスポンスは見やすいように整形している）。レスポンスのuserDataDirが

```
"userDataDir":"/var/folders/8s/2xqcrr5j45dgtkx3jmnc3clr0000gn/T/.org.chromium.Chromium.HVoScs"
```

となっていて、通常使っているユーザーデータディレクトリとは違っている[^3]。そのため、起動したGoogle Chromeで、例えば https://qiita.com にアクセスすると、当然、ログインフォームは空になっている。

ここでユーザ名＆パスワードを入力してログイン、終了。再度ChromeDriverでGoogle Chromeを起動すると、先程のuserDataDirとは別のディレクトリが使われるため、先程のデータが使えない。

そこで、ユーザーデータディレクトリを指定して固定することにする。しかし、通常使っているユーザーデータディレクトリを指定すると、悪影響が出る可能性があるので、別のディレクトリを指定する[^4]。

```
$ curl -X POST \
       -H "Content-Type: application/json" \
       -d '{
             "desiredCapabilities": {
               "browserName": "chrome",
               "chromeOptions": {
                 "args": [
                   "user-data-dir='"$HOME/.cache/chromedriver/user-data-dir"'"
                 ]
               }
             }
           }' \
       http://localhost:9515/session
```

ここではユーザーデータディレクトリを`$HOME/.cache/chromedriver/user-data-dir`にした。

起動したGoogle Chromeでパスワードを記憶できるように、まず、「設定」の「詳細情報を表示...」-「パスワードとフォーム」の「パスワードの保存を確認する」にチェックを入れる。

その後、 https://qiita.com に移動し、ユーザ名＆パスワードを入力してログイン。「Google Chromeでこのサイトのパスワードを保存しますか？」で「保存」を指定する。

Qiitaはブラウザを閉じてもログイン状態を保つようなので、一旦ログアウトして、Google Chromeを終了。再度、上記のcurlを実行してGoogle Chromeを起動、ログインフォームでパスワードが入力済みなのを確認する。

これで、パスワード入力を省くことができるようになったので、後はお好みのライブラリを使用するなどして、Google Chromeを操作すればOK。

例えば、[Nightwatch.js](http://nightwatchjs.org/)を使う場合

```
$ npm install nightwatch
$ mkdir -p ~/tmp/nightwatch
$ cd ~/tmp/nightwatch
```

以下、カレントディレクトリは`~/tmp/nightwatch`とする。

ChromeDriverを`bin`以下に置く。
http://selenium-release.storage.googleapis.com/index.html から最新の`selenium-server-standalone-{VERSION}.jar`をダウンロードして、`bin`以下に置く。
以下のnightwatch.jsonを置く。

```json:nightwatch.json
{
  "src_folders" : ["tests"],
  "output_folder" : "reports",
  "custom_commands_path" : "",
  "custom_assertions_path" : "",
  "page_objects_path" : "",
  "globals_path" : "",

  "selenium" : {
    "start_process" : true,
    "server_path" : "./bin/selenium-server-standalone-3.0.1.jar",
    "log_path" : "",
    "port" : 4444,
    "cli_args" : {
      "webdriver.chrome.driver" : "./bin/chromedriver"
    }
  },

  "test_settings" : {
    "default" : {
      "launch_url" : "http://localhost",
      "selenium_port"  : 4444,
      "selenium_host"  : "localhost",
      "silent": true,
      "screenshots" : {
        "enabled" : false,
        "path" : ""
      },
      "desiredCapabilities": {
        "browserName": "chrome",
        "chromeOptions": {
          "args": [
            "user-data-dir=/path/to/.cache/chromedriver/user-data-dir"
          ]
        }
      }
    }
  }
}
```

Selenium Serverのjarファイルのバージョンとuser-data-dirは適宜変更する。

テストを書く。

```js:tests/qiita.js
module.exports = {
  'Demo test Qiita' : function (browser) {
    browser
      .url('https://qiita.com')
      .waitForElementVisible('input[name=commit]', 1000)
      .click('input[name=commit]')
      .pause(1000)
      .end();
  }
};
```

Qiitaからログアウトした状態で、

```
$ nightwatch
```

すると、ログインフォームにはすでにインプットされているので、ログインボタンをクリックするだけで、ログインできるのが確認できる。

- - -
[^1]: ただしこれをやると当然まっさらな状態で起動しなくなるので、毎回まっさらな状態で始めたいテストの用途には向いていない。また、どうもGoogle Chromeがバックグラウンドで起動しなくなるようだ。
[^2]: [入門、Selenium - Seleniumの仕組み | CodeGrid](https://app.codegrid.net/entry/selenium-1)
[^3]: 通常使っているディレクトリはChromeでchrome://version/にアクセスすることで確認できる
[^4]: POSTで指定するまとまった情報が無いように思うが、ここでは[Chrome Setup · nightwatchjs/nightwatch Wiki](https://github.com/nightwatchjs/nightwatch/wiki/Chrome-Setup)の「Command Line Switches」のnightwatch.jsonの部分と、[Capabilities & ChromeOptions - ChromeDriver - WebDriver for Chrome](https://sites.google.com/a/chromium.org/chromedriver/capabilities)を参考にした。