Selenium WebDriver(selenium-2.46.0を使用)で画面のローディング等を待つために、Wait処理を書く必要があるが、Implicit WaitsとExplicit Waitsを混ぜて使用してはいけない。
Implicit Waitsはdriver全体に対しての設定なので非常に簡潔に書けるし、Explicit Waitsは柔軟に書けるので、基本はImplicit Waitsで定義して、必要に応じてExplicit WaitsでWait時間を上書きしようとすると上手くいかないので注意。
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get("http://somedomain/url_that_delays_loading");
WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));
// ここだけ秒数を上書きしたい
WebDriverWait wait = new WebDriverWait(driver, 30);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
以下の英語サイト群のまとめを載せておく。
http://elementalselenium.com/tips/47-waiting
http://stackoverflow.com/questions/15164742/combining-implicit-wait-and-explicit-wait-together-results-in-unexpected-wait-ti#answer-15174978
http://www.aptuz.com/blog/selenium-implicit-vs-explicit-waits/
Implicit Waitsは全体に対して設定ができるため便利だが、Explicit Waitsを推奨する。そしてImplicit WaitsとExplicit Waitsを絶対に混ぜてはいけない。
通常Implicit WaitsはWebDriverのリモートサーバ側(IEDriverServer.exe, chromedriver.exe, etc)に実装されるのに対し、Explicit Waitsはローカル側で実装されることが、混ぜてはいけない理由である。
以下のように処理が移っていく。
local code -> Java remote server -> local Java language bindings on the remote server -> "remote" component
このとき、どれだけWaitがかかるのかは「未定義」となる。
もし動作のルールがわかったとしても、IEDriverServer.exeやchromedriver.exeなどdriverによって実装が変わるため、どのdriverでも同じルールとなるとは限らない。
Aptuzのsiva dhanamjay氏の調査によるとExplicit Waits >= Implicit Waits
のとき、最大待ち時間はExplicit Waitsとなるが、Explicit Waits < Implicit Waits
のとき、最大待ち時間はExplicit Waits + Implicit Waits
となることがある。