Chrome Headless を Selenium/Java から使う

遅れてスミマセン

[Chromium Browser Advent Calendar 2017](https://qiita.com/advent-calendar/2017/chromium)の7日目の記事です。

# 背景

E2E テストの構成をあらためて作り直す中で、最新の Chrome Headless を Java 環境で使うための手段が気になりました。

環境は Mac を前提としていますが、幸い Linux でも動作に問題は無いはずです。

記事は 2017/12 ベースの最新バージョンを利用しています。
今日ベースの最新は

* [Selenide](http://selenide.org/): 4.9
* Selenium Java Driver (org.seleniumhq.seleniu.selenium-chrome-driver): [3.8.1](https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java/3.8.1)
* SeleniumWebDriver 2.34

です。

結論から言うと、少なくとも現時点では ChromeWebDriver Java 版も対応が終わっており、更に言語に応じた適切な Selenide ラッパーを使えば、chromedriver ダウンロードの手順も省略できました。


# 1. Selenide (Selenium Java Wrapper) を利用する。

以下のような build.gradle ファイルを作って、[Selenide (selenide.org)](http://selenide.org/) ライブラリを利用可能な状況に持っていきます。 

```groovy:build.gradle
apply plugin: 'idea'
apply plugin: 'java'

repositories {
    mavenCentral();
}

sourceCompatibility = targetCompatibility = 1.8

dependencies {
    compile 'com.codeborne:selenide:4.9'
    compile 'org.springframework.boot:spring-boot-starter-logging:1.5.9.RELEASE'
}

configurations.all {
    exclude group: 'log4j'
    exclude module: 'log4j-over-slf4j'
    exclude module: 'slf4j-log4j12'
    exclude module: 'slf4j-jdk14'
    exclude module: 'commons-logging'
}

```

# 2. 実行コードを書く

Selenium を通じた Chrome の起動方法は、この場合はページロード前に static 変数に入れていきます。

```java:ChromeHeadlessApplication.java
package holdings.ozaki.matsudak;

import static com.codeborne.selenide.Selenide.open;
import static com.codeborne.selenide.Selenide.screenshot;

import org.slf4j.bridge.SLF4JBridgeHandler;

import com.codeborne.selenide.Configuration;
import com.codeborne.selenide.WebDriverRunner;


public class ChromeHeadlessApplication {
    static {
        // ログを Slf4j の方に流します
        SLF4JBridgeHandler.removeHandlersForRootLogger();
        SLF4JBridgeHandler.install();

        // ChromeDriver を headless モードで利用
        Configuration.browser = WebDriverRunner.CHROME;
        Configuration.headless = true;
        Configuration.reportsFolder = "build/reports";
        Configuration.browserSize = "1024x768";
    }

    public static void main (final String...args) {
        // google.com のスクリーンショットを撮って終了
        open("https://google.com");
        screenshot("google.com");
    }
}
```

# 3. 実行
まず chrome を実行するためのブリッジとなるドライバですが、次の用に勝手に `io.github.bonigarcia.wdm.Downloader` がダウンロードしてくれます。

```text:log
2017-12-24 20:13:55 [main] INFO  i.g.bonigarcia.wdm.BrowserManager - Reading https://chromedriver.storage.googleapis.com/ to seek [chromedriver]
2017-12-24 20:13:55 [main] INFO  i.g.bonigarcia.wdm.BrowserManager - Latest version of [chromedriver] is 2.34
2017-12-24 20:13:55 [main] DEBUG io.github.bonigarcia.wdm.Downloader - Downloading https://chromedriver.storage.googleapis.com/2.34/chromedriver_mac64.zip to /Users/jp20217/.m2/repository/webdriver/chromedriver/mac64/2.34/chromedriver_mac64.zip
2017-12-24 20:13:56 [main] INFO  i.g.bonigarcia.wdm.BrowserManager - Exporting webdriver.chrome.driver as /Users/matsudak/.m2/repository/webdriver/chromedriver/mac64/2.34/chromedriver
```

main 文実行中に ps -A すると、Chrome が `--headless` & `--disable-gpu` で起動されていることが確認できます

```text:ps　-A
50321 ??         0:00.30 /Applications/Google Chrome.app/Contents/MacOS/Google Chrome --disable-background-networking --disable-client-side-phishing-detection --disable-default-apps --disable-gpu --disable-hang-monitor --disable-popup-blocking --disable-prompt-on-repost --disable-sync --disable-web-resources --enable-automation --enable-logging --force-fieldtri
als=SiteIsolationExtensions/Control --headless --ignore-certificate-errors --load-extension=/var/folders/wn/s9lbdlj56rd4bl2b6k54v_z80000gp/T/.org.chromium.Chromium.hg9Dpt/internal --log-level=0 --metrics-recording-only --no-first-run --no-sandbox --password-store=basic --remote-debugging-port=12986 --test-type=webdriver --use-mock-keychain --user-data-dir=/var/
folders/wn/s9lbdlj56rd4bl2b6k54v_z80000gp/T/.org.chromium.Chromium.76jzQ6 data:,
```
# 結果

|![google.com.png](https://qiita-image-store.s3.amazonaws.com/0/52956/b513ce3a-ebf2-a81d-5e0f-46c64de7d833.png)|
|:-:|

# まとめ
Chrome Headless が使えないので、PhantomJS 、、だと色々制約が大きいので xvid 経由で Chrome を立ち上げていた環境が多いと思います。

2017年〜は、xvid を挟まずに Chrome Headless を使っていけばよさそうな雰囲気です。


# その他 Chrome Headless でテストをされている情報
* [Python - https://dev.classmethod.jp/](https://dev.classmethod.jp/tool/eclipse/windows-selenium-headless-chrome/)
* [Ruby - RubyとSeleniumでHeadless chromeを動かす on Ubuntu/Linux](https://qiita.com/meguroman/items/41ca17e7dc66d6c88c07)