Selenium 4新機能: Chrome DevTools Protocol
この記事はSelenium/Appium Advent Calendar 2019の14日目の記事です。[1]
3日目の記事ではSelenium 4の新機能をざっと紹介しました。11日目の記事では新機能のひとつであるRelative Locatorについて解説しました。
この記事ではもう一つの新機能であるChrome DevTools Protocol連携について解説したいと思います。
この記事の内容はalpha版にもとづいています。正式リリースまでに内容が変更となる可能性がありますのでご注意ください。
Chrome DevTools Protocolとは
Chrome DevTools Protocol (CDP)とはChromeの開発者向け機能を呼び出すためのAPIです。Chromeにバンドルされているデベロッパーツールの各機能や、SeleniumのChromeDriverやGoogleの自動化ツールであるPuppeteerも裏側でこのAPIを使用しています。
Chrome DevTools Protocol Viewer
CDPの詳細と各APIの解説は上記のサイトにまとまっています。
ChromeDriver
クラスのメソッド
ここからはCDPに関連した各メソッドを解説していきます。
executeCdpCommand
executeCdpCommand
メソッドはChromeDriver
から直接呼び出し可能なメソッドです。CDPのコマンドを指定して実行できます。
以下のコードでは Emulation.setGeolocationOverride メソッドを呼び出して位置情報の偽装を行っています。[2]
@Test
void testGeolocation() {
driver.get("https://the-internet.herokuapp.com/geolocation")
driver.findElement(By.cssSelector("div#content > div > button")).click();
assertEquals(35, Double.parseDouble(driver.findElement(By.id("lat-value")).getText()), 0.9d);
assertEquals(139, Double.parseDouble(driver.findElement(By.id("long-value")).getText()), 0.9d);
driver.executeCdpCommand("Emulation.setGeolocationOverride",
ImmutableMap.of("latitude", 51.500611d, "longitude", -0.124611d, "accuracy", 100));
driver.findElement(By.cssSelector("div#content > div > button")).click();
assertEquals(51.500611d, Double.parseDouble(driver.findElement(By.id("lat-value")).getText()));
assertEquals(-0.124611d, Double.parseDouble(driver.findElement(By.id("long-value")).getText()));
}
getDevTools
getDevTools
メソッドはChromeDriver
からDevTools
クラスのインスタンスを取得するメソッドです。後述のイベントリスナーを使う場合にはDevTools
クラスが必要になります。
var devTools = driver.getDevTools();
DevTools
クラスのメソッド
ここからはCDP連携のために新規追加されたDevTools
クラスについて解説します。
createSession
, createSessionIfThereIsNotOne
, close
セッションの新規作成および終了をおこなうメソッド群です。なお、セッション管理まわりは現在も調整が入っているようで、APIにも変更がある可能性があります。
send
send
はCDPのコマンドを実行するメソッドです。executeCdpCommand
がコマンドを文字列の形式で指定したのに対して、こちらはドメイン毎に定義済みのクラスとメソッドを使います。
以下のコードはNetwork.setExtraHTTPHeadersメソッドを使ってBASIC認証の情報をヘッダーに付加する例です。enable
およびdisable
はネットワークのトラッキングなどの機能を有効・無効にするメソッドです。
@Test
void testBasicAuth() {
var devTools = driver.getDevTools();
devTools.createSessionIfThereIsNotOne();
var userPass = Base64.getMimeEncoder().encodeToString("admin:admin".getBytes());
devTools.send(Network.setExtraHTTPHeaders(ImmutableMap.of("Authorization", "Basic " + userPass)));
devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
driver.get("https://the-internet.herokuapp.com/basic_auth");
assertEquals("Basic Auth", driver.findElement(By.tagName("h3")).getText());
devTools.send(Network.disable());
}
addListener
addListener
はCDPのうち「イベント」に分類されるコマンドを使うためのメソッドです。あるイベントの発生を契機に実行されるメソッドを登録します。
以下のコードはNetwork.responseReceivedイベントを使ってHTTPのレスポンスが発生した時にステータスコードを出力する例です。
@Test
void testHttpStatusCode() {
var devTools = driver.getDevTools();
devTools.createSessionIfThereIsNotOne();
devTools.addListener(Network.responseReceived(), (responseReceived -> {
var status = responseReceived.getResponse().getStatus();
var url = responseReceived.getResponse().getUrl();
System.out.println("HTTP status: " + url + ": " + status);
}));
devTools.send(Network.enable(Optional.empty(), Optional.empty(), Optional.empty()));
driver.get("https://selenium.dev/");
devTools.send(Network.disable());
}
まとめ
Selenium 4の新機能であるChrome DevTools Protocol連携について解説しました。私見ですが、まだalpha版ということもあり、各メソッドのインターフェイスも定まってない感が強いです。
なお、この記事のコードを試す際に使ったalpha-3ではCDPのコマンドに対応する各クラス・メソッド(この記事でのNetwork
クラスなど)は普通にJavaのクラスとして実装されていますが、コマンドの数が多いことやバージョンアップに追従する頻度[3]が増えることなどを理由にmasterブランチではJSON形式の仕様定義ファイルからコードを自動生成する方針で開発が進められています。
このような事情があるためbetaから正式リリースまでの間にインターフェイスが大きく変わる可能性もあります。その辺りはまたbetaが出るくらいのタイミングで記事を書こうかなを思っています。
以上です。では、春節(何年かはわからない)のリリースを楽しみに待ちましょう!
Discussion