Selenium Tips

随時追記中。。

Page Object Design Pattern

 別記事で書いてます。

改行を送信

 別記事で書いてます。

FooterWait

// footerが出るまで待機
public static void FooterArrivalWait() {
	Wait<WebDriver> wait = new WebDriverWait(driver, 30);
	wait.until(presenceOfElementLocated(By.id("Footer")));
}
・使用例
driver.get("http://www.yahoo.co.jp)";
Extract_Wait.FooterArraivalWait();

とか、

driver.findElement(By.id("Jigsaw"));
Extract_Wait.FooterArraivalWait();

このメソッドを挟むだけで、読み込み未遂による失敗・エラーは激減する。
毎日、約400ケースを回しているが、読み込み未遂による失敗・エラーは、ほぼ0。

テキストフィールド

public static void SendKeysANDClear(By by, String Key) {
	Extract_Wait.FooterArrivalWait();
	try {
		Extract_Driver.driver.findElement(by).clear();
		Extract_Driver.driver.findElement(by).sendKeys(Key);
	} catch (NoSuchElementException e) {
		fail("指定されたフィールドが見つからない:" + by);
	}
}

ポップアップ

// 新しいウィンドウに切り替え
public static void popupChangeNewWindow() {
	// ポップアップしたウィンドウのID取得
	Default_Windows = driver.getWindowHandle();
	String newWindowId = null;

	for (String id : driver.getWindowHandles()) {
		if (!id.equals(Default_Windows)) {
			newWindowId = id;
		}
	}

	try {
		Thread.sleep(2500);
	} catch (InterruptedException e) {

	}

	// ウィンドウ切り替え
	driver.switchTo().window(newWindowId);
}

// メイン画面へ戻す
public static void popupChangeMainWindow() {
	driver.switchTo().window(Default_Windows);
}

画像のURL取得

// 指定画像のURLを返す
public static String returnImageURL(By by) {
	String ImageURL = null;
	try {
		ImageURL = driver.findElement(by).getAttribute("src");
	} catch (NoSuchElementException e) {
		fail("画像が見つからない");
	}
	return ImageURL;
}

ダイアログ

// ダイアログでOKを選択する
public static void dialogOK() {
	Alert confirm = driver.switchTo().alert();
	confirm.accept();
}

// ダイアログでキャンセルを選択する
public static void dialogNO() {
	Alert confirm = driver.switchTo().alert();
	confirm.dismiss();
}

Page Object Design Pattern(ページオブジェクトパターン)

ドキュメントに少し解説あり。
Page Object Design Pattern

・ページオブジェクトパターンで実装すると何が良いのか

 ・ページ操作とシナリオの分離
 ・メンテナンス性の向上
 ・テストケースの追加コストが低い(既にあるページオブジェクトを使える場合)

・なぜ、ページオブジェクトパターンか

 ページオブジェクトパターンを知る前に100ケースほどテストを書いたのですが、サービスがアップデートされるたびに、シナリオとページ操作がぐっちゃぐちゃになっているテストコードから修正点を探し出すという、非常にバカなことをやっていました。
 もちろん、漏れが起きるため、テストを回して修正、テストを回して修正、、、
 一方、ページオブジェクトパターンで実装すれば、サービスがアップデートされれば、該当するページのテストを書き換えるだけで修正ができます。
 もちろん、アップデートに伴い、シナリオを変更する必要も出てくるが、シナリオとページ操作が分離されているので、修正が容易でした。

 ページオブジェクトパターンのメリットは、1度実装したページは使い回しが効くということです。
 同じページ操作が複数のシナリオ内で出現することは、良くあること。。。
 パターンで実装していなかった場合は、変なメソッドにまとめてしまったり、コピペで使いまわしたり。工数もかかるし、メンテナンス性は最悪というか皆無(笑・・えない)。
 実際、シナリオ・ページ操作ぐっちゃぐちゃのテストケースを100個書いた後に、パターンに則って300ぐらい実装して身に染みた。

・書いたもの

 ・ページオブジェクトで使うインターフェース
 ・テストシナリオで必要となるページオブジェクト
 ・テストシナリオ
 ・テストデータを格納するYaml

・実際に使用しているインターフェース

public interface PageObject_Admin {
	//URL直叩き用
	public void Open();
	//未定
	public void Close();
	//各ページからログアウトするために
	public void Logout();
	//トップページへのリンク
	public void Top();
	//ヘルプ
	public void Help();
}

・ページ実装

public class PageObject001 implements PageObject_Master {
	static WebDriver driver;

	public PageObject001 () {
		driver = CreateDriverInstance.getDriver();
        }
        // URL直叩き用
	public void Open() {
		Extract_Driver.openBaseHTTP("/form/");
	}
    // ログアウト用
	public void Logout() {
		Extract_Auth.ToolLogout();
	}
	public void Close() {
	}
    //トップへの遷移用
	public void Top() {
		driver.findElement(By.linkText("トップ")).click();
		Extract_Wait.FooterArrivalWait();
	}
	public void Help() {
	}
	// タイトル
	public void inputComment_title(String Comment_title) {
		Extract_Input.SendKeysANDClear(By.id("title"),Comment_title);
	}
	// 本文
	public void inputComment_body(String Comment_body) {
		Extract_Input.SendKeysANDClear(By.id("body"),Comment_body);
	}
	// 変更する
	public void doChange() {
		driver.findElement(By.id("change_submit")).click();
		Extract_Wait.FooterArrivalWait();

		driver.findElement(By.id("do_change")).click();
		Extract_Wait.FooterArrivalWait();

		driver.findElement(By.linkText("トップへ戻る")).click();
		Extract_Wait.FooterArrivalWait();
	}
}

・テストシナリオ

public class TextCase0001 extends TestBase {
	@DataPoints
	public static Object[] getDataPoints() {
		// TODO getStackTraceは重いので、他の取得方法に変えたい。
		String ClassInfo = Thread.currentThread().getStackTrace()[1]
				.getClassName();
		return Extract_Yaml.ImportTestDataYaml_MAP(ClassInfo);
	}

	@Theory
	public void ゴニョゴニョする(Map<Object, Object> TestDataMAP) {
		PageObject001 PageObject001 = new PageObject001();
		PageObject002 PageObject002 = new PageObject002();
		PageObject003 PageObject003 = new PageObject003();

		PageObject001 .Open();
		P11_01.Login(TestDataMAP.get("ID").toString(), TestDataMAP.get("PW")
				.toString());

		// ログイン状態の確認
		Assertion_Condition.Auth_LogoutButtonAvailableCheck();

		PageObject002.openP0003();

		PageObject003.inputName(TestDataMAP.get("Name").toString());
                PageObject003.inputName(TestDataMAP.get("TelNum").toString());
		PageObject003.doSearch();

		Assertion_TextElement
				.Assertion_ShowText_PerfectPatern(By.xpath("/html/body/div//table/tbody/tr/td/a"),TestDataMAP.get("Name").toString());
		Assertion_TextElement
				.Assertion_ShowText_PerfectPatern(By.xpath("/html/body/div//table/tbody/tr/td/a"),TestDataMAP.get("TelNum").toString());
	}
}

・テストデータ用Yaml

1:
  ID: Jigsaw
  PW: Jigsawww
  Name: Jigsaw
  TelNum: 00-0000-0000

Firefoxのextensionでハマった

Firefoxのextensionを作る時、諸々のファイルが入ったフォルダを圧縮し、FXへ投げても、このアドオンは壊れているため云々が表示されてインストールできない。
だが、必要なファイル諸々を選択して圧縮後にリネームし、FXへ投げてみると、すんなりインストール出来てしまった。
フォルダ自体を選択するのではなく、必要なファイルを選択して圧縮する必要がある。