WebDriver について調べる機会があったので簡単にまとめました。 この記事では curl を使って、WebDriver によるブラウザ操作をしてみます。
WebDriver と Selenium の歴史
Selenium は現在最も広く使われている、Web ブラウザの自動化・テストフレームワークです。 多くの言語をサポートしており、Java や C#などの言語から、Web ページを開いたり要素の検証ができます。 そのため Web サービスの End-to-end (E2E) テストの自動化で主に利用されています。
Selenium 1 (Selenium RC) と呼ばれていた時代は、ブラウザを操作するために Selenium Core という JavaScript をブラウザ上でロードしてました。 しかしブラウザのセキュリティ強化により、Selenium Core の JavaScript 実行が難しくなったため、モダンブラウザでは Selenium Core が動かなくなりました。
Selenium のヘビーユーザーだった Google は、Selenium Core とは別のアプローチをとるため、WebDriver というプロジェクトをスタートしました。 WebDriver は JavaScript ではなく、各ブラウザが実装する ドライバ によってブラウザを操作します。 クライアントは標準化された API によってブラウザを制御できます。
のちに WebDriver プロジェクトと Selenium プロジェクトは統合され、それが現在の Selenium 2.0 になります。 Selenium 2.0 は Selenium RC の問題を解決するだけでなく、より洗練された API を提供します。 現在は Selenium 2.0 が E2E テストのフレームワークのデファクトスタンダードになっています。
WebDriver の仕様と実装
WebDriver API は JSON ベースの REST API です。 WebDriver API の仕様は、W3C で仕様化が進められています。
それぞれのブラウザドライバは、この仕様に則った API を提供します。 ChromeDriver (Google Chrome/Chromium)、FirefoxDriver (Firefox)、InternetExplorerDriver (Internet Explorer)、SafariDriver (Safari)、PhantomJSDriver(Phantom JS) などのブラウザドライバが存在します。 WebDriver API を叩くためのクラスが Selenium 本体に組み込まれてますが、curl などの HTTP クライアントからも利用できます。
ドライバが実際どのようにブラウザを操作するかは、それぞれのブラウザの実装に依存します。 たとえば geckodriver はMarionette remote protocolとよばれる TCP ベースのプロトコルで Firefox を制御します。 しかしエンドユーザはブラウザ固有のプロトコルを知らずとも、WebDriver API さえ使えば、おなじインターフェイスで Firefox や Chromium を操作できます。
curl で WebDriver を操作する
前置きが長くなりましたが、本記事の目的である curl で WebDriver を操作してみます。
WebDriver を起動する
この記事では Firefox 用の geckodriver と、Chrome 用の chromedriver を使用します。 ダウンロードはそれぞれ以下のリンクからできます。
それぞれ特にオプションなしで起動します。
# Firefox
geckodriver
# Chromium/Google Chrome
chromedriver
geckodriver はデフォルトポートは 4444、chromedriver はデフォルトポートは 9515 で起動します。
現在のドライバの状態はGET /status
で取得できます。
# geckodriver
curl -sSL localhost:4444/status
# chromedriver
curl -sSL localhost:9515/status
レスポンスは JSON で返されます。
ドライバが利用可能になってると "ready": true
がセットされます。
またドライバ固有のメッセージが "message"
に含まれます。
以下は geckodriver が返す JSON の例です。
{
"value": {
"message": "",
"ready": true
}
}
セッションを作成する
起動されるブラウザは、ドライバ内でセッションという形で管理されます。
ブラウザを起動するにはPOST /sesion
からセッションを作成します。
# geckodriver
curl -sSL -XPOST -H'Content-Type: application/json' -d '{}' localhost:4444/session
# chromedriver
curl -sSL -XPOST -H'Content-Type: application/json' -d '{ "capabilities": {} }' localhost:9515/session
"capabilities"
フィールドはブラウザのオプションを指定します。
指定可能な Capabilities の一部は標準化されてます。
またブラウザ固有の Capabilities もあり、geckodriver と chromedriver の Capabilities はそれぞれ以下のドキュメントから確認できます。
作成されたセッションの情報は JSON で返され、セッションの情報は"value"
フィールドに格納されます。
各セッションには一意のセッション ID が付与され、"sessionId"
フィールドから確認できます。
また起動したブラウザの Capabilities は"capabilities"
フィールドにセットされてます。
以下は geckodriver が返す JSON の例です。
{
"value": {
"sessionId": "75765ef8-73e3-449d-920d-d48bd3838a35",
"capabilities": {
"acceptInsecureCerts": false,
"browserName": "firefox",
"browserVersion": "70.0",
"moz:accessibilityChecks": false,
"moz:buildID": "20190905174512",
"moz:geckodriverVersion": "0.24.0",
"moz:headless": false,
"moz:processID": 22557,
"moz:profile": "/tmp/rust_mozprofile.2dpoXOgM4Lb5",
"moz:shutdownTimeout": 60000,
"moz:useNonSpecCompliantPointerOrigin": false,
"moz:webdriverClick": true,
"pageLoadStrategy": "normal",
"platformName": "linux",
"platformVersion": "5.2.11-arch1-1-ARCH",
"rotatable": false,
"setWindowRect": true,
"strictFileInteractability": false,
"timeouts": {
"implicit": 0,
"pageLoad": 300000,
"script": 30000
},
"unhandledPromptBehavior": "dismiss and notify"
}
}
}
セッションを終了する
ブラウザを終了するには、DELETE /session/{session id}
からセッションを破棄します。
session id は POST /session
のレスポンスに含まれるセッション ID です。
# geckodriver
curl -XDELETE localhost:4444/session/8985eb04-54a7-4a43-b847-4c7d4423a00b
# chromedriver
curl -XDELETE localhost:9515/session/814aefbd9b2d0605f6203a1a3336c935
まとめ
WebDriver は現代の E2E テスト自動化フレームワークのデファクトスタンダードになってます。 Vim Vixen でも E2E テストを自動化するために、WebDriver を利用してます。 その中身はシンプルな REST API で、curl からもブラウザを制禦できます。
この記事ではセッションの作成・削除まで説明しました。 次回はページを開いたりユーザー操作(クリックやキー入力)を発火し、そして要素の検証までを curl で体験したいと思います。