はじめに
構築をしたものの、『Pageクラス作るのかよー』とか言われて重い腰を上げてもらえそうなので、できるだけ簡単にPageクラスを作る方法を記録しておきます。
今までの経験上たぶん色々言ってくる![]()
操作をしたい要素を特定する(CSSセレクタなど)
Windows版で解説。
Chromeのデベロッパーツールを使用します。
Pageクラスを作成してみる
先ほど調べた要素を反映させると以下のPageクラスを作成することになる
package page;
import static com.codeborne.selenide.Selenide.*;
import org.openqa.selenium.WebDriver;
public class Google extends PageBase {
public static final String _url = "https://www.google.co.jp/webhp";
public Google(WebDriver webDriver) {
super(webDriver);
}
private String _id_search = "#lst-ib";
// ****************************************
// 検索ページ
// ****************************************
public Google __検索ワード入力(String s) {
$(_id_search).setValue(s);
return this;
}
public Google __検索を行う() {
$(_id_search).submit();
return this;
}
}
テストは以下のようなコード。
package test;
import org.junit.Test;
import com.htmlhifive.pitalium.core.model.ScreenshotArgument;
import page.Google;
public class GoogleTest extends TestBase {
@Test
public void OK() throws Exception {
driver.get(Google._url);
Google page = new Google(driver);
page.__検索ワード入力("test")
.__検索を行う();
ScreenshotArgument arg = ScreenshotArgument.builder("result").addNewTarget().build();
assertionView.verifyView(arg);
}
}
クリックメニューを扱えるようなPageクラスを作成してみる
検索結果表示後のツールをクリックして操作できるメソッドを追加してみる。
要素の調べ方は先ほどと同じ。
Seleniumは操作が早すぎるようで、要素がないみたいなエラーになることがある。
クリック後に表示される要素を待つようにすると安定する。
package page;
import static com.codeborne.selenide.Condition.*;
import static com.codeborne.selenide.Selenide.*;
import java.util.Iterator;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import com.codeborne.selenide.SelenideElement;
public class Google extends PageBase {
public static final String _url = "https://www.google.co.jp/webhp";
public Google(WebDriver webDriver) {
super(webDriver);
}
private String _id_search = "#lst-ib";
// ****************************************
// 検索ページ
// ****************************************
public Google __検索ワード入力(String s) {
$(_id_search).setValue(s);
return this;
}
public Google __検索を行う() {
$(_id_search).submit();
return this;
}
// ****************************************
// 検索結果ページ(以下は本来なら別クラス)
// 本来なら「__検索を行う()」メソッドで検索結果Pageクラスを返せば良い
// ****************************************
public Google __ツールをクリック() {
$("#hdtb-tls").click();
return this;
}
public Google __ツール$期間をクリック() {
// ツール選択後のメニューが表示されているか確認
if (!$("#hdtbMenus").isDisplayed()) {
__ツールをクリック();
}
// 選択後に表示される項目を60秒待つ
$("#hdtbMenus").waitUntil(appear, 60000);
$("#hdtbMenus > div > div:nth-child(5) > div").click();
return this;
}
public Google __ツール$期間$1時間以内をクリック() {
return __ツール$期間$指定文字をクリック("1 時間以内");
}
public Google __ツール$期間$1年以内をクリック() {
return __ツール$期間$指定文字をクリック("1 年以内");
}
private Google __ツール$期間$指定文字をクリック(String text) {
// 期間のメニューが表示されているか確認
if (!$("#hdtbMenus > div > ul.hdtbU.hdtb-mn-o").isDisplayed()) {
__ツール$期間をクリック();
}
// 選択後に表示される項目を60秒待つ
$("#hdtbMenus > div > ul.hdtbU.hdtb-mn-o").waitUntil(appear, 60000);
return matchTextClick(text, $$("#hdtbMenus > div > ul.hdtbU.hdtb-mn-o > li").iterator());
}
private Google matchTextClick(String text, Iterator<SelenideElement> seItr) {
boolean ckickFlg = false;
while (seItr.hasNext()) {
SelenideElement se = seItr.next();
if (text.equals(se.getText())) {
se.click();
ckickFlg = true;
break;
}
}
if (!ckickFlg) {
throw new NoSuchElementException("Click error:" + text);
}
return this;
}
}
テストは以下のようなコード。
package test;
import org.junit.Test;
import com.htmlhifive.pitalium.core.model.ScreenshotArgument;
import page.Google;
public class GoogleTest extends TestBase {
@Test
public void OK() throws Exception {
driver.get(Google._url);
Google page = new Google(driver);
page.__検索ワード入力("test")
.__検索を行う();
ScreenshotArgument arg = ScreenshotArgument.builder("result1").addNewTarget().build();
assertionView.verifyView(arg);
page.__ツール$期間$1時間以内をクリック();
// 画面状態が完璧にわかるなら以下の記述の方が処理速度が速い
// page.__ツールをクリック()
// .__ツール$期間をクリック()
// .__ツール$期間$1時間以内をクリック();
arg = ScreenshotArgument.builder("result2").addNewTarget().build();
assertionView.verifyView(arg);
page.__ツール$期間$1年以内をクリック();
arg = ScreenshotArgument.builder("result3").addNewTarget().build();
assertionView.verifyView(arg);
}
}
Frameが分かれている画面を処理するPageクラスを作ってみる
Frameが分かれているページは切り替えなくてはいけないらしい。
この制御もやはりPageクラスでカバーする方が良いと思ってる。
(切り替えなしでいける方法があればご教授ください)
18/04/23 変更
コメントをいただいた内容は理解できたが、実力不足でコードには反映できず![]()
"__項目1に入力"メソッドでも同じような記述ができれば良いのだが思いつかず。
package page;
import static com.codeborne.selenide.Selenide.*;
import org.openqa.selenium.WebDriver;
import com.codeborne.selenide.SelenideElement;
import com.codeborne.selenide.WebDriverRunner;
public class FrameSample extends PageBase {
public static final String _url = "https://";
public FrameSample(WebDriver webDriver) {
super(webDriver);
}
/** デフォルトフレームに存在している要素に入力 */
public FrameSample __項目1に入力(String s) throws InterruptedException {
$("#in1").setValue(s);
return this;
}
/** 別フレームに存在している要素に入力 */
public FrameSample __項目2に入力(String s) throws InterruptedException {
switcFrame($(".iframe"));
$("#in2").setValue(s);
switchDefaultFrame();
return this;
}
/***
* デフォルトフレームに切り替える
* @throws InterruptedException
*/
private void switchDefaultFrame() throws InterruptedException{
// 処理が安定しないのでフレーム変更にWaitをとりあえず入れる
WebDriverRunner.getWebDriver().switchTo().defaultContent();
Thread.sleep(2000);
}
/***
* 別フレームに切り替える
* @param se フレームのElement
* @throws InterruptedException
*/
private void switcFrame(SelenideElement se) throws InterruptedException{
// 処理が安定しないのでフレーム変更にWaitをとりあえず入れる
WebDriverRunner.getWebDriver().switchTo().frame(se);
Thread.sleep(2000);
}
}



