curlで覚えるWebDriver (1/2)

    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 idPOST /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 で体験したいと思います。

    参考


    Profile picture

    Shin'ya Ueoka

    B2B向けSaaSを提供する会社の、元Webエンジニア。今はエンジニアリング組織のマネジメントをしている。