JavaScriptで描画したダイアログのスクリーンショットを撮影する
モダンなWebサイトでは新しい画面を開くときに、ポップアップウィンドウを開くのではなく、同じウィンドウ内でモーダルダイアログを表示することがあります。Pitaliumでページ内ダイアログを扱う方法について解説します。
ダイアログのテスト
要素が利用できるまで待機する
JavaScriptで描画するダイアログは非同期で表示が行われる可能性があり、表示を開始するボタンをクリックした直後にダイアログを操作するとテストがエラーになってしまうことがあります。Seleniumの WebDriverWait と ExpectedConditions を利用することで、「特定の要素が表示されるまで待機する」等を実現できます。
ExpectedConditionsで指定できる条件の一部は以下の通りです。
メソッド名 | 説明 |
---|---|
titleIs(title: String) | Windowのタイトルが○○に完全一致する。 |
urlToBe(url: String) | URLが○○に完全一致する。 |
presenceOfElementLocated(locator: By) | 指定した要素が、可視、不可視に関わらず、DOMに含まれる。 |
visibilityOfElementLocated(locator: By) | 指定した要素がDOMに含まれ、かつ可視状態になる。 |
visibilityOf(element: WebElement) | 指定した要素がDOMに含まれ、かつ可視状態になる。 |
textToBePresentInElement(element: WebElement, text: String) | 指定した要素のテキストが○○に完全一致する。 |
frameToBeAvailableAndSwitchToIt(frameLocator: String) | IDまたはnameを指定したフレームを対象として指定できる。 |
invisibilityOfElementLocated(locator: By) | 指定した要素がDOMに含まれ、かつ不可視状態になる。 |
elementSelectionStateToBe(element: WebElement, selected: boolean) | 指定した要素が特定の選択状態になる。 |
alertIsPresent() | alertまたはconfirmのダイアログが表示される。 |
テストを作ってみる
テストサイトについて
サンプル用に作成したテストサイトに対してPitaliumでスクリーンショットを撮影するコードを書いてみます。今回使用するWebサイトはユーザーがログインできる機能があり、次のような構造になっています。
- メイン画面
メイン画面はユーザーが最初に訪れる画面です。メールアドレス/パスワードの入力項目をモーダルダイアログとして表示するボタンがあります。
ユーザーがログインを実行するとモーダルダイアログが非表示になり、ログイン後の文字列が表示されます。
コードを書いてみる
1.画面を開く
まずはメイン画面を開き、スクリーンショットを撮影します。
ログインするためのボタンがあることが確認できます。
driver.get("dialogInsideWindow");
// スクリーンショット撮影
assertionView.assertView("OpenMainWindow");
2.ボタンをクリックしてログイン画面を開く
ログインボタンをクリックし、ログインダイアログを開きます。
3.モーダルが表示されるのを待ちます
モーダルダイアログが表示されるまで、最大30秒待機します。
// 表示されるダイアログのIDを指定して、ダイアログが表示されるまで待機
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("loginModal")));
4.モーダルのスクリーンショットを撮影
モーダルダイアログが表示されていることを確認するため、スクリーンショットを取得します。
メールアドレス/パスワード入力欄とログイン実行ボタンがあることが分かります。
5.ログイン情報を入力
ログイン動作を行うため、メールアドレスとパスワードを入力します。
入力した状態をチェックするためにスクリーンショットも取得します。
driver.findElementById("email").sendKeys("pitalium.sample@localhost.com");
driver.findElementById("password").sendKeys("password");
// スクリーンショット撮影
assertionView.assertView("EnterLoginParams");
6.ログインボタンをクリック
ログインボタンをクリックし、ログイン処理を実行します。
7.モーダルが消えるのを待ち、スクリーンショットを撮影
モーダルダイアログを表示したときと同様、ダイアログが完全に消えるまで最大30秒待機します。
その後ダイアログが消えたこと、及びログイン後の処理を確認するため、スクリーンショットを撮影します。
wait.until((ExpectedConditions.invisibilityOfElementLocated(By.id("loginModal"))));
// スクリーンショット撮影
assertionView.assertView("LoggedIn");
8.テストコード全体
手順1~6までをまとめた全体のテストコードです。
@Test
public void dialogInsideWindowTest() throws Exception {
// 1.メイン画面を開き、全体のスクリーンショットを撮影します。
driver.get("dialogInsideWindow");
assertionView.assertView("OpenMainWindow");
// 2.ボタンをクリックしてモーダルを開きます。
driver.findElementById("openLoginModal").click();
// 3.モーダルが表示されるのを待ちます。
WebDriverWait wait = new WebDriverWait(driver, 30L);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("loginModal")));
// 4.モーダルのスクリーンショットを撮影します。
assertionView.assertView("OpenLoginModal");
// 5.ログイン情報を入力してスクリーンショットを撮影します。
driver.findElementById("email").sendKeys("pitalium.sample@localhost.com");
driver.findElementById("password").sendKeys("password");
assertionView.assertView("EnterLoginParams");
// 6.ログインボタンをクリックします。
driver.findElementById("login").click();
// 7.モーダルが消えるのを待ち、スクリーンショットを撮影します。
wait.until((ExpectedConditions.invisibilityOfElementLocated(By.id("loginModal"))));
assertionView.assertView("LoggedIn");
}
}
ソースコード
このサンプルのソースコードはGithubレポジトリの次のパスを参照ください。