5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Selenium(Java)でHTML要素が見つかるまで待機する処理

Last updated at Posted at 2016-05-06

#SeleniumでHTML要素が見つかるまで待機したい
会社で勤怠管理のWebシステムを利用していますが、毎日、手動で入力するのが面倒くさかったのでSelenium(Java)で自動入力するツールを作りました。その際、画面遷移の完了を判断するために、あるHTML要素が見つかるまで待機する処理を作るのに一番、手こずったので内容をメモします。

##Strategyインタフェースを作成
ただ待機するだけではなく、画面によっては見つからなかったら再度、ボタンをクリックするようなことがしたかったので、「どのように待つか」というアルゴリズムを入れ替えられるようにStrategyパターンで作ります。

java
public interface HtmlElementStrategy {
	public boolean isFindElement();
}

##Contextを作成
HtmlElementStrategy#isFindElementがtrueになるまで待機する処理。
waitTimeに待機時間、timeoutCntに待機回数を指定。

java
public class HtmlElementContext{
	public static void waitUntilFindElement(long waitTime, int timeoutCnt,
			HtmlElementStrategy t) {
		for (int i = 0;; i++) {
			try {
				if (t.isFindElement()) {
					// 要素が見つかったらループを抜ける
					break;
				}
			} catch (NoSuchElementException e) {
				if (i > timeoutCnt) {
					// timeoutCntを超えたら例外を投げる
					throw e;
				}
			}
			try {
				// waitTimeの間、待機する
				Thread.sleep(waitTime);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

##クライアントを作成
実際の使用例。
HtmlElementContext#waitUntilFindElementを呼び出す際に、Strategyを実装する。

java
HtmlElementContext.waitUntilFindElement(1000, 30,
		new TeamSplitStrategy() {
			// Strategyの実装
			@Override
			public boolean isFindElement() {
				if (driver.getTitle().contains("HTML要素名")) { 
					// 画面のタイトルが見つかった
					return true;
				}
				// リンクをクリック
				driver.findElement(By.linkText("HTML要素名")).click();
				return false;
			}
		});

##WebDriverWaitクラスを使えばよかった
この記事を書いている最中、SeleniumライブラリのWebDriverWaitクラスを使えば、わざわざ上記のような処理を自作しなくても済むことに気付いてしまいました。

java
// Waitオブジェクト作成
Wait<WebDriver> wait = new WebDriverWait(driver, 30);

// 待機条件を実装
ExpectedCondition<Boolean> waitCondition= new ExpectedCondition<Boolean>() {
	public Boolean apply(WebDriver driver) {
		driver.findElement(By.linkText("HTML要素名")).click();
		return driver.getTitle().contains("HTML要素名");
	}
};

// 条件を満たすまで待つ
wait.until(waitCondition);

つまり、車輪の再発明をする前に、APIを確認しようねというお話でした・・・・・・。

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?