toshiです。
Selenium WebDriverで遊んでみよう、第三回目ぐらいかな。
今回のテーマは、
「Webの表示に時間がかかる場合(すぐには表示されない場合)に、
どのように確認処理を行うか。」
です。
例えばボタンクリックして、
Ajaxでデータ取ってきて、
1,2秒後に結果が表示されるみたいなケース。
こんな場合に、Java的にはThread.sleep ?
ちょっと待っていればいいかと思うわけですが。。。
しかし、Seleniumのページを見てみると書いてありました。
表示を待つのにThread.sleepはあまり良くないと^^;
では、どうするか。
表示されるのを待つ例
Seleniumでは以下のように書くことができるみたいです。
★waitする処理の例
WebElement addDynamicElement = (new WebDriverWait(driver, 7)) .until(new ExpectedCondition<WebElement>() { @Override public WebElement apply(WebDriver d) { return d.findElement(By.id("add")); } });
実験用サンプル例
それでは、試してみます。
試すサンプルはテキトウに
以下のサーブレットとJavascriptを用意しました。
★画面表示用のサーブレット(HelloWorld.java)
package com.example.tests; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class HelloWorld extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { response.setContentType("text/html"); StringBuilder text = new StringBuilder(); text.append("<html>"); text.append("<head>"); text.append("<meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\">"); text.append("<title>Hello World!</title>"); text.append("<script type=\"text/javascript\" src=\"js/delay.js\"></script>"); text.append("<script type=\"text/javascript\" src=\"js/prototype.js\"></script>"); text.append("</head>"); text.append("<body>"); text.append("<h1>Hello World!</h1><div id=\"result\"></div>"); text.append("</body>"); text.append("</html>"); PrintWriter out = response.getWriter(); out.print(text.toString()); } }
★web.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0" metadata-complete="true"> <display-name>Test Sample</display-name> <description>For Selenium</description> <servlet> <servlet-name>Hello</servlet-name> <servlet-class>com.example.tests.HelloWorld</servlet-class> </servlet> <servlet-mapping> <servlet-name>Hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
★遅延処理(5秒後にid=addの要素を追加)させるJavascript(delay.js)
window.onload = function() { // 画面開いて、5秒後に処理。 setTimeout( bar , 5000); } function bar(){ // id=addの要素を追加。 addObj = document.createElement("div"); addObj.setAttribute("id", "add"); addObj.innerHTML = "SampleText"; $("result").appendChild(addObj); }
WebDriverを動かす。
WebDriverを用いてどのように処理するのかを下に書いてみました。
JUnitで動かします。
package com.example.tests; import static org.junit.Assert.*; import java.util.concurrent.TimeUnit; import org.junit.After; import org.junit.Before; import org.junit.Test; 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 DelayCaseTest { private WebDriver driver; // テストアドレス private String testUrl = "http://localhost:8080/WebTest/hello"; // 表示される予定の文字列 private String expected = "SampleText"; private StringBuffer verificationErrors = new StringBuffer(); @Before public void setUp() throws Exception { driver = new FirefoxDriver(); } /** * そもそも待たないケース */ @Test public void testMethod1() { driver.get(testUrl); WebElement addDynamicElement = driver.findElement(By.id("add")); String actual = addDynamicElement.getText(); assertEquals(expected, actual); } /** * 待つ条件を指定するケース * (id=addが取得できるまで待っている) */ @Test public void testMethod2() { driver.get(testUrl); // 指定した状態に変わるまで待つ(タイムアウトを7秒と指定) WebElement addDynamicElement = (new WebDriverWait(driver, 7)) .until(new ExpectedCondition<WebElement>() { @Override public WebElement apply(WebDriver d) { return d.findElement(By.id("add")); } }); String actual = addDynamicElement.getText(); assertEquals(expected, actual); } /** * とりあえず最初に待っているケース */ @Test public void testMethod3() { // 画面表示を待つように指定(タイムアウトを10秒と指定) driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get(testUrl); WebElement addDynamicElement = driver.findElement(By.id("add")); String actual = addDynamicElement.getText(); assertEquals(expected, actual); } @After public void tearDown() throws Exception { driver.quit(); String verificationErrorString = verificationErrors.toString(); if (!"".equals(verificationErrorString)) { fail(verificationErrorString); } } }
結果、実行してみると
testMethod1は全く待たないため、失敗になります。
testMethod2とtestMethod3は待っている処理が異なりますが
要素(id=add)が表示された後に処理をするため成功になりました。
というわけで想定したように動いたみたいです^^
では〜。