プログラミング言語の選択

Selenium 2.0 と WebDriver??

注:これらの文書はまだ完成途上のものです。情報には正確を期していますがまだ執筆中のものであるということをご承知下さい。執筆の進行と共に情報を追加し、内容をより堅固なものにしていきます。

Selenium 2.0 機能??

Selenium 2.0 では Selenium 1 に多くの新しいエキサイティングな機能と改良が追加されました。これらは公式 Selenium ブログでのリリースアナウンスメントで発表されたものの最初のものです。

主要な新しい機能は WebDriver API の統合です。簡単なプログラミングインタフェースを提供することによって多くの問題を取り払うことができます。オブジェクト指向の API を開発することによって多くのブラウザをサポートし、今日のウェブアプリテストでの高度な問題に対処するのが目標です。

注:これから Selenium 2.0 の新しい機能を説明します。まずはリリースアナウンスメントの文章から引用します。

Selenium サーバー – 使うか使わないか??

Selenium サーバーを使っても良いし、使わなくても良いのです。あなたが Selenium をどう使うかによって Selenium サーバーが必要かどうかが決まります。WebDriver API を全面的に使うならば、Selenium サーバーは必要ありません。Selenium の WebDriver はブラウザが自動化のために用意しているネイティブなコールを直接使用します。コールの方法は使用しているブラウザによって異なります。各ブラウザでの実装については後に述べる情報をご覧ください。

Selenium サーバが必要な場合 -
  • 複数のマシンや VM での分散テストのために Selenium Grid を使っている場合
  • ローカルのマシンにないバージョンのブラウザを使用するためにリモートのマシンに接続する場合
  • Java バインディングを使用せず、 HtmlUnit ドライバを使用する場合

Selenium-WebDriver プロジェクトのセットアップ??

Selenium をインストールした後、Selenium を使用するプログラムを開発するためのプロジェクトを設定することになります。その方法はあなたのプログラミング言語と開発環境に依存します。

Java??

Selenium 2.0 Java プロジェクトの最も簡単な設定方法は、Maven を使用することです。Maven は Maven pom.xml (プロジェクト設定) ファイルを使用してJava バインディング(Selenium 2.0 Java クライアントライブラリ)及び依存関係にある全てのライブラリをダウンロードします。その後、IntelliJ IDEA や Eclipse などのあなたの開発環境にプロジェクをインポートできます。

まず Selenium プロジェクトを入れるためのフォルダを作成してください。次に Maven を使用するためには pom.xml ファイルが必要です。これはテキストエディタで作成できます。既に優れたリファレンスがあるのでここでは pom.xml ファイルの詳細や Maven の使用方法については述べません。出来上がった pom.xml ファイルは次のようなものになるでしょう。それをあなたのプロジェクトのフォルダの中に置いてください。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>MySel20Proj</groupId>
        <artifactId>MySel20Proj</artifactId>
        <version>1.0</version>
        <dependencies>
            <dependency>
                <groupId>org.seleniumhq.selenium</groupId>
                <artifactId>selenium-java</artifactId>
                <version>2.14.0</version>
            </dependency>
        </dependencies>
</project>

最新のバージョンを指定するように注意してください。この記事を書いている時点では上記のバージョンが最新のものでしたが Selemiun 2.0 のリリースの後、頻繁な更新がなされています。Maven のダウンロードページで最新のリリースを確認して上記の内容を修正してください。

次に、コマンドラインからプロジェクトのディレクトリに cd して次のMaven のコマンドを実行します。

mvn clean install

これは Selenium 及びその依存関係にある全てのものをダウンロードし、プロジェクトに追加します。

最後に、あなたの開発環境にプロジェクトをインポートしてください。 不慣れ方のために、次の内容が付録にあります。

IntelliJ IDEA への Maven プロジェクトのインポート. Eclipse への Maven プロジェクトのインポート.

C#??

現在、Selenium 2.2.0は依存関係にある他の全ての dll と共にデジタル署名付きの dll として配布されています。2.2.0 以前ではデジタル署名は付けられていませんでした。プロジェクトに Selenium を入れるには https://code.google.com/p/selenium/downloads/list から最新の Selenium.zip ファイルをダウンロードするだけです。Windows Vista またはそれ以降を使用されている場合は zip ファイルを解凍する前に unblock する必要があります。zip ファイルを右クリックし、次に「プロパティ」をクリック、「Unblock」をクリック、「OK」をクリックしてください。

zipファイルの内容を解凍し、解凍されたdll のそれぞれへの参照をVisual Studio(またはあなたのIDE)中のプロジェクトに追加してください。

公式 NuGet パッケージ: RC WebDriver WebDriverBackedSelenium Support

Python??

テストの自動化に Python を使用されているなら、多分 Python での開発には精通されているでしょう。Selenium を Python の環境に追加するには、コマンドラインから以下のコマンドを実行します。

pip install selenium

pip をインストールしておく必要があります。又、pip と依存関係にある setuptools も必要です。

Python での開発自体について述べるのはこの文書の範疇ではありません。Python については既に多くのリソースがありますし、あなたの組織の中に手助けしてくれる開発者もいるでしょう。

Ruby??

テストの自動化に Ruby を使用されているなら、多分 Ruby での開発には精通されているでしょう。Selenium を Ruby の環境に追加するには、コマンドラインから以下のコマンドを実行します。

gem install selenium-webdriver

Ruby での開発自体について述べるのはこの文書の範疇ではありません。Ruby については既に多くのリソースがありますし、あなたの組織の中に手助けしてくれる開発者もいるでしょう。

Perl??

Perl のサポートはサードパーティによって行われています。インストール及びそれ以降についてはそれらのドキュメントをご覧ください。現時点ではその一つとして Perl binding があります。

PHP??

PHP のサポートはサードパーティによって行われています。インストール及びそれ以降についてはそれらのドキュメントをご覧ください。現時点ではそれぞれ ChibimagicLukasz KolczynskiFacebook による三つのものがあります。

Selenium 1.0 からの移行??

既に、Selenium 1.0 を使用したテスト環境を持っている方のために、私達はどのようにして既存のコードを Selenium 2.0 に移行させるかについて秘訣を提供します。Selenium 2.0 のリーダー開発者であるサイモン・ステュワートが Selenium 1.0 からの移行について書いていますのでそれを付録につけました。

Selenium RC から Selenium WebDriverへの移行

Selenium-WebDriver の基礎??

WebDriverは、ウェブアプリケーションのテストを自動化、特にそれが予期したように動作する事を確認するためのツールです。Selenium RC 1.0 の API より簡単に理解でき使いこなせるフレンドリーな API を提供し、テストを、より読みやすく保守しやすいものにすることを目指しています。特定のフレームワークに紐付けられておらず、単体テストや旧来の "main" メソッド の使用でどこでも同じようにうまく動作します。このセクションでは WebDriver のAPI を導入し、それに慣れることを手助けします。まだしていないならまずは、WebDriver プロジェクトを設定することから始めてください。これは、前の章、「Selenium-WebDriver プロジェクトの設定」で説明してあります。

プロジェクトの設定が終わったら、WebDriver が普通のライブラリのように動作するのがわかるでしょう。それは完全に自己完結型のもので、Selenium-RC の場合、プロキシサーバを実行しておくことが必要だったのに対して、あなたは事前にいかなるプロセスやインストーラも実行しておく必要がありません。

注: Chrome ドライバーOpera ドライバーAndroid ドライバーiPhone ドライバーでは追加の処理が必要です。

さあ、あなたはコードを書く準備ができました。スタートのための簡単な方法はこの例から始めることです。これは Google上で「Cheese」という単語を検索し、結果として得られたページのタイトルをコンソール上に出力します。

package org.openqa.selenium.example;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;

public class Selenium2Example  {
    public static void main(String[] args) {
        // Firefox driver の新しいインスタンスを作成
        // 以降のコードは実装ではなくインターフェースに基づいて
        // いるということに注意して下さい。
        WebDriver driver = new FirefoxDriver();

        // これを使用して Google のサイトに行きます。
        driver.get("http://www.google.com");
        // 次のように記述しても同じことができます。
        // driver.navigate().to("http://www.google.com");

        // テキスト入力エレメントを名前で見付けます。
        WebElement element = driver.findElement(By.name("q"));

        // 検索する単語を入力します。
        element.sendKeys("Cheese!");

        // フォームをサブミットします。
        // WebDriver はエレメントからフォームを知ります。
        element.submit();

        // ページのタイトルをチェックします。
        System.out.println("Page title is: " + driver.getTitle());
        
        // Google の検索結果は JavaScript によってダイナミックに
        // 出力されます。
        // ページがロードされ終わるまで待ちます。
        // 10秒のタイムアウトを設定します。
        (new WebDriverWait(driver, 10)).until(new ExpectedCondition<Boolean>() {
            public Boolean apply(WebDriver d) {
                return d.getTitle().toLowerCase().startsWith("cheese!");
            }
        });

        // "cheese! - Google 検索" の結果が見れるでしょう。
        System.out.println("Page title is: " + driver.getTitle());
        
        // ブラウザを閉じます。
        driver.quit();
    }
}
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium;

class GoogleSuggest
{

    static void Main(string[] args)
    {
        IWebDriver driver = new FirefoxDriver();

        //特定の方法が Java 版とは少し異なります。
        //'get' が C# のキーワードであることが理由です。
        driver.Navigate().GoToUrl("http://www.google.com/");
        IWebElement query = driver.FindElement(By.Name("q"));
        query.SendKeys("Cheese");
        System.Console.WriteLine("Page title is: " + driver.Title);
        // ここに wait を追加する必要あり。
        driver.Quit();
    }

}
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait # 2.4.0 から使用可能
import time

# Firefox ドライバーの新インスタンスを作成
driver = webdriver.Firefox()

# google のホーム・ページに行く。
driver.get("http://www.google.com")

# 名前属性が q (google の検索ボックス名)の要素を見つける。
inputElement = driver.find_element_by_name("q")

# 検索語彙をタイプする。
inputElement.send_keys("Cheese!")

# フォームのサブミット (現在、 google はサブミットなしでも自動的に検索を行いますが)
inputElement.submit()

# このページは AJAX を使用しており、タイトルは始めは次のようです。:
print driver.title

try:
    # ページが更新されるまで待ちます。最後にタイトルが更新されるようです。
    WebDriverWait(driver, 10).until(lambda driver : driver.title.lower().startswith("cheese!"))

    # "cheese! - Google Search" が現れるでしょう。
    print driver.title

finally:
    driver.quit()
require 'rubygems'
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :firefox
driver.get "http://google.com"

element = driver.find_element :name => "q"
element.send_keys "Cheese!"
element.submit

puts "Page title is #{driver.title}"

wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until { driver.title.downcase.start_with? "cheese!" }

puts "Page title is #{driver.title}"
driver.quit

これからの章ではブラウザの履歴から前方や後方にナビゲートしたり、フレームやウィンドウを使用した Webサイトのテストする方法等、WebDriver についてもっと詳しく学習を進めます。またより詳細な説明と例を提供します。

WebDriver ドライバー はじめに??

WebDriver はテストを記述さするためのキーとなるインターフェース名ですが、いくつかの実装があります。以下のものがあります:

HtmlUnit ドライバー??

現在最も高速で軽量の WebDriver の実装です。名前からわかるように HtmlUnit をベースにしています。HtmlUnit は GUI を持たない WebBrowser の Java ベースの実装です。Java 以外の言語でこのドライバーを使用するには Selenium サーバーが必要です。

使用法??

WebDriver driver = new HtmlUnitDriver();
IWebDriver driver = new RemoteWebDriver(new Uri("http://127.0.0.1:4444/wd/hub"),
                                        DesiredCapabilities.HtmlUnit());
driver = webdriver.Remote("http://localhost:4444/wd/hub", webdriver.DesiredCapabilities.HTMLUNIT)
driver = Selenium::WebDriver.for :remote, :url => "http://localhost:4444/wd/hub", :desired_capabilities => :htmlunit

長所??

  • WebDriver の最も高速な実装です。
  • 純粋な Java の解釈でプラットフォームに依存しません。
  • JavaScript をサポートします。

短所??

  • 他のブラウザの JavaScript のエミュレーション(以下をご覧ください)

HtmlUnit ドライバーにおける JavaScript??

ポピュラーなブラウザはどれも HtmlUnit によって使われている JavaScript エンジン (Rhino)を使用していません。HtmlUnitを使って、JavaScript をテストした場合、結果はそれらのブラウザとはかなり異なるかもしれません。

"JavaScript" と言うと、実際には "JavaScript と DOM" を意味します。 DOM は W3C によって定義されていますが、各ブラウザにそれ自身の変な癖や DOM の実装の中での、そして JavaScript がどのようにそれらと相互作用しているかにおける違いがあります。HtmlUnit は DOM の完全と思われる実装を持っていて、JavaScript を使う上での良いサポートもありますが、他のどのようなブラウザとも全く変わりません:他のブラウザをまねする能力にもかかわらず、W3C 標準と主要なブラウザの DOM の実装の両方から見て、それ自身の変な癖と違いがあります。

WebDriver において、私達は選択をする必要がありました;HtmlUnit の JavaScript 機能を有効にし、実装の違いによる問題にチームが遭遇するであろうというリスクを冒すのか、それとも JavaScript に依存している数多くのサイトがあると知っていて、JavaScript を使用不可にしておくか?私達は保守的なアプローチを取り、デフォルトでは HtmlUnitを使う時には JavaScript を使用不可にしました。WebDriver と HtmlUnit 両方の各リリース時において私達はこの決定の再評価を行います:私達はいつかの時点で HtmlUnit においてデフォルトで JavaScript を有効にできることを望んでいます。

JavaScript を有効にする??

もし、あなたがそれまで待てないならば、JavaScript のサポートを有効にするのは非常に簡単です。

HtmlUnitDriver driver = new HtmlUnitDriver(true);
WebDriver driver = new RemoteWebDriver(new Uri("http://127.0.0.1:4444/wd/hub"),
                       DesiredCapabilities.HtmlUnitWithJavaScript());
caps = Selenium::WebDriver::Remote::Capabilities.htmlunit(:javascript_enabled => true)
driver = Selenium::WebDriver.for :remote, :url => "http://localhost:4444/wd/hub", :desired_capabilities => caps
driver = webdriver.Remote("http://localhost:4444/wd/hub", webdriver.DesiredCapabilities.HTMLUNITWITHJS)

これは HtmlUnit ドライバーにデフォルトで Firefox 3.6 の JavaScript の処理をエミュレートさせます。

Firefox ドライバー??

Firefox プラグインを使用して、Firefox ブラウザを制御します。 Firefox プロファイルはインストールされたものから Selenium WebDriver.xpi (プラグイン)だけを含むように縮小されたものが使用されます。その他に幾つかの設定もデフォルトで変更されています。(内容についてはソースをご覧ください。)Firefox ドライバーは Windows, Mac, Linux 上で動作し、テストされています。現在のバージョンは 3.0, 3.6, 5, 6, 7, と 8 です。

使用法??

WebDriver driver = new FirefoxDriver();
IWebDriver driver = new FirefoxDriver();
driver = webdriver.Firefox()
driver = Selenium::WebDriver.for :firefox

長所??

短所??

Firefox プロファイルの変更??

あなたが、ユーザーエージェントの文字列を(上のように)修正したいとしても、FireFox プロファイルにはその他に飾り立てられた数十の有益な拡張があります。このプロファイルを取得するには二つの方法があります。プロファイルが、Firefox のプロファイルマネジャー (firefox -ProfileManager)を使って作成されているならば:

ProfileIni allProfiles = new ProfilesIni();
FirefoxProfile profile = allProfiles.getProfile("WebDriver");
profile.setPreferences("foo.bar", 23);
WebDriver driver = new FirefoxDriver(profile);

もしくは、プロファイルが Firefox にまだ登録されていないならば:

File profileDir = new File("path/to/top/level/of/profile");
FirefoxProfile profile = new FirefoxProfile(profileDir);
profile.addAdditionalPreferences(extraPrefs);
WebDriver driver = new FirefoxDriver(profile);

Firefox ドライバーの開発は続けられていますので次第に新機能が使えるようになります。その一つとして Linux 上の FireFox のネイティブ・イベントが安定するまでその使用はデフォルトでは無効にされています。これを有効にするには:

FirefoxProfile profile = new FirefoxProfile();
profile.setEnableNativeEvents(true);
WebDriver driver = new FirefoxDriver(profile);

情報??

最新の情報については wiki ページの Firefox の章をご覧ください。

Internet Explorer ドライバー??

このドライバーは .dll によって実行され、そのため Windows OS 上でしか動作しません。各 Selenium リリースのコアの部分は XP 上の バージョン 6, 7, 8 及び Windows7 上のバージョン 9 でテストされています。

使用法??

WebDriver driver = new InternetExplorerDriver();
IWebDriver driver = new InternetExlorerDriver();
driver = webdriver.Ie()
driver = Selenium::WebDriver.for :ie

長所??

  • 実際のブラウザの中で動作し、奇妙な動きも含めてエンドユーザが見た通りの JavaScript をサポートします。

短所??

  • 明らかですが、Internet Explorer Driver は Windows 上でのみ動作します。!
  • 比較的低速です。(かなり活発ではありますが:)
  • 殆どのバージョンで XPath はネイティブにはサポートされていません。Sizzle が自動的に埋め込まれますが他のブラウザに比べて顕著に遅く、同じブラウザでの CSS セレクタに比べても低速です。
  • バージョン 6 と 7 では CSS はネイティブにはサポートされていません。代わりに Sizzle が埋め込まれます。
  • IE 8 と 9 では CSS セレクタはネイティブにサポートされています。しかし CSS3 は完全にはサポートされていません。

情報??

最新の情報については Wiki ページの Internet Explorer の章をご覧ください。必要な設定の章に留意してください。

Chrome ドライバー??

Chrome ドライバーは Chromium プロジェクト自身によってサポート、メンテナンスされています。WebDriver は Chrome ブラウザ自体の中にあります。WebDriver は chromedriver (chromium プロジェクトのダウンロードページにあります。)を通して Chrome に働きかけます。chromedriver と、対応するバージョンの Chrome ブラウザをインストールする必要があります。chromedriver は WebDriver が自動的に見つけることのできるシステムパス上に置く必要があります。Chrome ブラウザ自身は chromedriver によってデフォルトのインストレーションパス上から見つけられます。どちらのパスも環境変数を書き換えることによって変更可能です。その他の情報についてはについては wiki をご覧ください。

使用法??

WebDriver driver = new ChromeDriver();
IWebDriver driver = new ChromeDriver();
driver = webdriver.Chrome()
driver = Selenium::WebDriver.for :chrome

長所??

  • 実際のブラウザの中で動き、JavaScript をサポートします。
  • Chrome は Webkit ベースのブラウザなので、Chrome ドライバーを使用してあなたのサイトが Safari においても動作することを確認することができるでしょう。Chrome は、Safari の Nitro エンジンではなく、自身の V8 JavaScript エンジンを使うので、JavaScript の実行については違いがあるかもしれないことに注意してください。

短所??

情報??

最新の情報については私達の wiki をご覧ください。ダウンロードページにも情報があります。

Chrome ドライバーを使用する??

Chrome ドライバーをダウンロードし、 wiki ページの情報に従ってください。

Opera ドライバー??

Opera ドライバーについては Selenium Wiki 中の Opera ドライバーについての wiki の文章をご覧ください。

iPhone ドライバー??

iPhone ドライバー??

Mac iOS ドライバーの使用については Selenium Wiki 中の iPhone ドライバーについての wiki 文章をご覧下さい。

Android ドライバー??

Android ドライバーの使用については Selenium Wiki 中の Android ドライバーについての wiki の文章をご覧ください。

コマンドと操作??

ページの取得??

あなたが、WebDriver で最初にする事は特定のページにナビゲートすることでしょう。通常これは "get" をコールすることによって実行されます。:

driver.get("http://www.google.com");
driver.Url = "http://www.google.com";
driver.get "http://www.google.com"
driver.get("http://www.google.com")

WebDriverは、ページが完全にロードされるまで(即ち、"onload" イベントが発生するまで)待ってから、制御をテストまたはスクリプトに戻します。AJAX を多用しているページの場合は WebDriver にはページがいつ完全にロードされたかわからないことに注意して下さい。そのような場合、ページが完全にロードされたことを確実にするためには明示または暗黙の Wait を使用します。

UI 要素(WebElements) の特定??

WebDriver での要素の特定は WebDriver のインスタンス自身もしくは WebElement に対して行われます。各言語用に “Find Element” と “Find Elements” のメソッドが用意されています。前者は見つけた WebElement のオブジェクトを返すか、もしくは見つからなかった場合、例外を投げます。後者は見つけた WebElement のリストを返し、どの DOM エレメントもマッチしなかった場合は空のリストを返します。

“Find” メソッドは “By” というロケータ若しくは照会オブジェクトを使用します。“By” の使用方法について以降に説明します。

By ID??

要素を特定するのに最も有用で推奨される方法です。UI の開発者が共通して陥る落とし穴は同じページに一意でない id を割り振ったり、自動作成された id を使用することです。どちらも避けなければなりません。自動作成された id より HTML 要素のクラスを使用する方が適切です。

検索の方法の例を以下に示します。:

<div id="coolestWidgetEvah">...</div>
WebElement element = driver.findElement(By.id("coolestWidgetEvah"));
IWebElement element = driver.FindElement(By.Id("coolestWidgetEvah"));
element = driver.find_element(:id, "coolestWidgetEvah")
element = driver.find_element_by_id("coolestWidgetEvah")

もしくは

from selenium.webdriver.common.by import By
element = driver.find_element(by=By.ID, value="coolestWidgetEvah")

By クラス名??

「クラス」はここでは DOM 要素の属性を指します。同じクラス名の DOM 要素が複数存在するのが常であるため、最初の要素を検索するよりは複数の要素を一度に検索する方が実用的です。

検索の方法の例を以下に示します。:

<div class="cheese"><span>Cheddar</span></div><div class="cheese"><span>Gouda</span></div>
List<WebElement> cheeses = driver.findElements(By.className("cheese"));
IList<IWebElement> cheeses = driver.FindElements(By.ClassName("cheese"));
cheeses = driver.find_elements(:class_name, "cheese")

もしくは

cheeses = driver.find_elements(:class, "cheese")
cheeses = driver.find_elements_by_class_name("cheese")

もしくは

from selenium.webdriver.common.by import By
cheeses = driver.find_elements(By.CLASS_NAME, "cheese")

By タグ名??

要素の DOM タグ名

検索の方法の例を以下に示します。:

<iframe src="..."></iframe>
WebElement frame = driver.findElement(By.tagName("iframe"));
IWebElement frame = driver.FindElement(By.TagName("iframe"));
frame = driver.find_element(:tag_name, "iframe")
frame = driver.find_element_by_tag_name("iframe")

もしくは

from selenium.webdriver.common.by import By
frame = driver.find_element(By.TAG_NAME, "iframe")

By 名前??

名前属性の一致する入力要素を見つけます。

検索の方法の例を示します。:

<input name="cheese" type="text"/>
WebElement cheese = driver.findElement(By.name("cheese"));
IWebElement cheese = driver.FindElement(By.Name("cheese"));
cheese = driver.find_element(:name, "cheese")
cheese = driver.find_element_by_name("cheese")

もしくは

from selenium.webdriver.common.by import By
cheese = driver.find_element(By.NAME, "cheese")

By CSS??

名前からわかるように CSS による特定の方法です。デフォルトでブラウザがネイティブにサポートしている機能が使用されます。 従って使用可能な CSS セレクタのリストについては w3c css selectors <http://www.w3.org/TR/CSS/#selectors> を参照して下さい。ブラウザが CSS による照会をネイティブにサポートしていない場合は Sizzle が使用されます。 IE 6,7 と FF3.0 では現在、 Sizzle が CSS 照会エンジンとして使用されています。

全てのブラウザが同じように作られているわけではないので、あるバージョンでは動作しても他のバージョンでは動作しない CSS もあるかも知れないことに注意してください。

cheese を検索する方法の例を示します。:

<div id="food"><span class="dairy">milk</span><span class="dairy aged">cheese</span></div>
WebElement cheese = driver.findElement(By.cssSelector("#food span.dairy.aged"));
IWebElement cheese = driver.FindElement(By.CssSelector("#food span.dairy.aged"));
cheese = driver.find_element(:css, "#food span.dairy.aged")
cheese = driver.find_element_by_css_selector("#food span.dairy.aged")

もしくは

from selenium.webdriver.common.by import By
cheese = driver.find_element(By.CSS_SELECTOR, "#food span.dairy.aged")

By XPATH??

ハイレベルで、WebDriver はブラウザにネイティブの XPath 機能があるならそれを使用します。ネイティブで XPath のサポートを持っていないブラウザには私達自身が実装を提供しています。このように xpath エンジンの実装は様々なものがあるのでそれらの違いに注意しないと予期せぬ結果を引き起こすことになります。

ドライバー タグと属性名 属性値 XPath のネイティブサポート
HtmlUnit ドライバー 小文字のみ検知 HTML 中の値 Yes
Internet Explorer ドライバー 小文字のみ検知 HTML 中の値 No
Firefox ドライバー 大文字、小文字両方検知 HTML 中の値 Yes

次の HTML はちょっとした例です。:

<input type="text" name="example" />
<INPUT type="text" name="other" />
List<WebElement> inputs = driver.findElements(By.xpath("//input"));
IList<IWebElement> inputs = driver.FindElements(By.XPath("//input"));
inputs = driver.find_elements(:xpath, "//input")
inputs = driver.find_elements_by_xpath("//input")

もしくは

from selenium.webdriver.common.by import By
inputs = driver.find_elements(By.XPATH, "//input")

一致する個数は以下のようになります。

XPath 式 HtmlUnit ドライバー Firefox ドライバー Internet Explorer ドライバー
//input 1 (“example”) 2 2
//INPUT 0 2 0

HTML 要素では属性値を明示的に指定する必要はないため、それらが指定されずにデフォルト値が採用される場合があります。例えば、"input" タグでは "type" 属性を指定する必要はなく、指定されない場合、デフォルト値として "text" が採用されます。WebDriver において xpath を使うための経験則の一つとして、これらの暗黙の属性に対して一致することを期待すべきではありません。

JavaScript の使用??

任意の JavaScript を実行して要素を検索することができ、返された DOM 要素は自動的に WebElement オブジェクトに変換されます。

jQuery がロードされたページでの簡単な例です。:

WebElement element = (WebElement) ((JavascriptExecutor)driver).executeScript("return $('.cheese')[0]");
IWebElement element = (IWebElement) ((IJavaScriptExecutor)driver).ExecuteScript("return $('.cheese')[0]");
element = driver.execute_script("return $('.cheese')[0]")
element = driver.execute_script("return $('.cheese')[0]")

ページ内の全ての入力要素を検索します。:

List<WebElement> labels = driver.findElements(By.tagName("label"));
List<WebElement> inputs = (List<WebElement>) ((JavascriptExecutor)driver).executeScript(
    "var labels = arguments[0], inputs = []; for (var i=0; i < labels.length; i++){" +
    "inputs.push(document.getElementById(labels[i].getAttribute('for'))); } return inputs;", labels);
IList<IWebElement> labels = driver.FindElements(By.TagName("label"));
IList<IWebElement> inputs = (IList<IWebElement>) ((IJavaScriptExecutor)driver).ExecuteScript(
    "var labels = arguments[0], inputs = []; for (var i=0; i < labels.length; i++){" +
    "inputs.push(document.getElementById(labels[i].getAttribute('for'))); } return inputs;", labels);
labels = driver.find_elements(:tag_name, "label")
inputs = driver.execute_script(
    "var labels = arguments[0], inputs = []; for (var i=0; i < labels.length; i++){" +
    "inputs.push(document.getElementById(labels[i].getAttribute('for'))); } return inputs;", labels)
labels = driver.find_elements_by_tag_name("label")
inputs = driver.execute_script(
    "var labels = arguments[0], inputs = []; for (var i=0; i < labels.length; i++){" +
    "inputs.push(document.getElementById(labels[i].getAttribute('for'))); } return inputs;", labels)

ユーザーインプット - フォームへの埋め込み??

テキストエリアやテキストフィールドにテキストを入力する方法については解りました。他の要素についてはどうでしょうか?チェックボックスの状態をトグルしたり、OPTION タグのようなものをクリックしたりすることができます。SELECT タグの処理はそんなに難しくありません。:

WebElement select = driver.findElement(By.tagName("select"));
List<WebElement> allOptions = select.findElements(By.tagName("option"));
for (WebElement option : allOptions) {
    System.out.println(String.format("Value is: %s", option.getAttribute("value")));
    option.click();
}
IWebElement select = driver.FindElement(By.TagName("select"));
IList<IWebElement> allOptions = select.FindElements(By.TagName("option"));
foreach (IWebElement option in allOptions)
{
    System.Console.WriteLine("Value is: " + option.GetAttribute("value"));
    option.Click();
}
select = driver.find_element(:tag_name, "select")
all_options = select.find_elements(:tag_name, "option")
all_options.each do |option|
  puts "Value is: " + option.attribute("value")
  option.click
end
select = driver.find_element_by_tag_name("select")
allOptions = select.find_elements_by_tag_name("option")
for option in allOptions:
    print "Value is: " + option.get_attribute("value")
    option.click()

これはページの最初の "SELECT" 要素を見つけて、その全ての OPTION について順番にプリント出力しながらセレクトしていくことを繰り返します。お分かりでしょうが、これは SELECT 要素を扱う最も効率的な方法ではありません。WebDriver でサポートされているクラスには "SELECT" というのがあり、これを使うともっと良い処理ができます。

Select select = new Select(driver.findElement(By.tagName("select")));
select.deselectAll();
select.selectByVisibleText("Edam");
SelectElement select = new SelectElement(driver.FindElement(By.TagName("select")));
select.DeselectAll();
select.SelectByText("Edam");
# available since 2.12
from selenium.webdriver.support.ui import Select
select = Select(driver.find_element_by_tag_name("select"))
select.deselect_all()
select.select_by_visible_text("Edam")

これはページの最初の SELECT からその中の全ての OPTION を選択解除し、それから"Edam" のテキストの表示された OPTION を選択します。

フォームへの記入が終わったら次にそれをサブミットしたいでしょう。一つの方法は "submit" ボタンを見つけてそれをクリックすることです。

driver.findElement(By.id("submit")).click();

別の方法として WebDriver は全ての要素について便利な "submit" というメソッドを提供しています。フォームの中の要素でこのメソッドを呼び出せば WebDriver はそれが含まれているフォームを検出するまで DOM を起動し、そこで submit を呼び出します。要素がフォームの中になかった場合は NoSuchElementException 例外が投げられます。:

element.submit();

ウィンドウ、フレーム間の移動??

ウェブアプリケーションの中には複数のフレームやウィンドウを使っているものがあります。WebDriverは、"switchTo" メソッド を使って名前付きのウィンドウ間の移動をサポートします:

driver.switchTo().window("windowName");

ドライバーへのすべての呼び出しはこれ以降特定のウィンドウに向けられます。しかし、どのようにしてウィンドウの名前を知ればいいでしょう?それを開いた時の javascript やリンクの中を見てください:

<a href="somewhere.html" target="windowName">新しいウィンドウを開くためにここをクリックしてください。</a>

別の方法として、「ウィンドウハンドル」を "switchTo().window()" メソッドに渡すこともできます。これを知っていると次のように全ての開かれたウィンドウの上で繰返すことができます。:

for (String handle : driver.getWindowHandles()) {
    driver.switchTo().window(handle);
}

フレームからフレームに(またはiframesの中へ)移動することもできます:

driver.switchTo().frame("frameName");

ドットによる階層表現を使用することでサブフレームにアクセスすることが可能で、インデックスによってフレームを指定することもできます。 それは以下のようなものです:

driver.switchTo().frame("frameName.0.child");

"frameName" と呼ばれるフレームの最初のサブフレームの "child"という名のフレームに行きます。全てのフレームはトップのフレームからドットによる階層型パスで表現できます。

クッキー??

次のステップにいく前に、あなたはクッキーの使い方に興味があるかもしれません。まず第一に、クッキーが有効になるであろうドメインの上にいる必要があります。サイトと会話する前にクッキーをセットしたい場合でホームページが大きくてロードするのに時間がかかる場合はサイト内の小さなページをロードするという方法もあります。404 のページ(http://example.com/some404page) がそういったものです。

// 有効なドメインに行ってください。
driver.get("http://www.example.com");

// クッキーをセットします。これはドメイン全体で有効です。
Cookie cookie = new Cookie("key", "value");
driver.manage().addCookie(cookie);

// 現在の URL で入手できる全てのクッキーを出力します。
Set<Cookie> allCookies = driver.manage().getCookies();
for (Cookie loadedCookie : allCookies) {
    System.out.println(String.format("%s -> %s", loadedCookie.getName(), loadedCookie.getValue()));
}

// クッキーを削除するには3通りの方法があります。
// 名前を指定して
driver.manage().deleteCookieNamed("CookieName");
// クッキーそのものを指定して
driver.manage().deleteCookie(loadedCookie);
// 「全て」を指定して
driver.manage().deleteAllCookies();
# 有効なドメインに行ってください。
driver.get("http://www.example.com")

# クッキーをセットします。これはドメイン全体で有効な例です。
# クッキーの名前は 'key' で、値は 'value' です。
driver.add_cookie({'name':'key', 'value':'value', 'path':'/'})
# 追加で渡されるキーとして:
# 'domain' -> String, 'secure' -> Boolean,
# 'expiry' -> 時間切れの Epoch までのミリ秒時間

# 現在の URL で入手できる全てのクッキーを出力します。
for cookie in driver.get_cookies:
    print "%s -> %s" % (cookie['name'], cookie['value'])

# クッキーを削除するには2通りの方法があります。
# 名前を指定して
driver.delete_cookie("CookieName")
# 「全て」を指定して
driver.delete_all_cookies()

ユーザーエージェントの変更??

a class="reference internal" href="#firefox-driver">Firefox Driverでは簡単です。::

FirefoxProfile profile = new FirefoxProfile();
profile.addAdditionalPreference("general.useragent.override", "some UA string");
WebDriver driver = new FirefoxDriver(profile);

ドラッグ&ドロップDrag And Drop??

ドラッグ&ドロップを実行するための Actions クラスを使う例を示します。有効にするためにはネイティブイベントが必要です。

WebElement element = driver.findElement(By.name("source"));
WebElement target = driver.findElement(By.name("target"));

(new Actions(driver)).dragAndDrop(element, target).perform();

ドライバー特有の情報とトレードオフ??

WebDriver をバックエンドで使用する Selenium-RC??

WebDriver の Java バージョンは Selenium-RC API の実装を提供しています。これは、WebDriver 上で Selenium-RC API を使えるということです。 主に後方互換性を保つために提供されています。Selenium-RC API を使用した既存のテストスイートを持っている人がそれをWebDriver の下で使うことを可能にします。Selenium-WebDriverへの移行を楽にするために提供されました。また、これは、同じテストコードの中で両方の API を並行して使うことを可能にします。

Selenium-WebDriver は次のように使われます:

// どの WebDriver の実装を使用してさしつかえありません。例として FireFox ドライバーを使用します。
WebDriver driver = new FirefoxDriver();

// "base url" は Selenium で相対的な URL のベースとなる URL です。
 String baseUrl = "http://www.google.com";

// Selenium の実装の作成
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);

// Selenium でのアクションの実行
selenium.open("http://www.google.com");
selenium.type("name=q", "cheese");
selenium.click("name=btnG");

// 背後の WebDriver の実装を呼び出します。
// これは前に出てきた "driver" 変数と同じく、WebDriver インスタンスを参照します。
WebDriver driverInstance = ((WebDriverBackedSelenium) selenium).getUnderlyingWebDriver();

//最後に、ブラウザを閉じます。driver.quit() を呼ぶ代わりに、WebDriverBackedSelenium インスタンスの stop を読んでください。
//さもなければ、ブラウザが閉じられた後も、JVM は動き続けます。
selenium.stop();

長所??

  • WebDriver と Selenium API を平行して使用することができます。
  • Selenium RC API から WebDriver への管理された移行のための簡単なメカニズムを提供します。
  • スタンドアロンの Selenium RC サーバーを必要としません。

短所??

  • すべてのメソッドを実装しているわけではありません。
  • Selenium の高度な使用法(Selenium コアから "browserbot" 等の内蔵 JavaScript メソッドを使用する等)は動作しないかもしれません。
  • 実装の違いにより動作の遅いメソッドがあります。

WebDriver のバックエンドで Selenium を使用??

WebDriver は、Selenium RC ほど多くのブラウザをサポートしないのでWebDriver API を使っている間も以下のように SeleneseCommandExecutor を使うことによって Selenium RC のサポートを受けることができます:

Safari はこの方法で次のコードによってサポートされます。(ポップアップのブロッキングを無効にするのを忘れないで下さい。):

DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setBrowserName("safari");
CommandExecutor executor = new SeleneseCommandExecutor(new URL("http://localhost:4444/"), new URL("http://www.google.com/"), capabilities);
WebDriver driver = new RemoteWebDriver(executor, capabilities);

現在、このアプローチにはいくつかの大きな制限があり、特に、 findElements は、予期されたようには動作しません。また、ブラウザを動かす負荷が高い作業のために Selenium Core を使っているので、JavaScript サンドボックスの制限を受けます。

Selenium WebDriver Wiki??

WebDriver wiki の中に WebDriver についてのより多くの情報があります。

次のステップ??

この章では単に WebDriver とそのキーとなる機能のいくつかを見渡しただけでした。Selenium-WebDriver API に精通するようになると次には保守性、拡張性に優れ、AUT の機能が頻繁に変わっても耐えられるようなテストスイートをどのようにして作成するかを学びたいでしょう。ほとんどの Selenium エキスパートが現在推奨しているアプローチはページオブジェクトデザインパターンとことによるとページ ファクトリーを使ってテストコードをデザインすることです。WebDriver は Java と C# で PageFactory クラスを提供してこれをサポートしています。これは他の高度なトピックとともに次章で説明されます。また、このテクニックのハイレベルの説明のために、テスト設計に関する考慮の章を見たいかもしれません。これら両方の章において、テストコードをよりモジュール化されたものにし、よりメンテナンスしやすいものにするためのテクニックを説明します。