私は慣例的にセレン2がどのようにPageObjectsをPOJOとして使用し、次にPageFactoryを使用してこのクラスのフィールドをインスタンス化するかを本当に気に入っています。
私が制限しているのは、さまざまなページで多くの要素を再利用することです。大きな問題は、これらの再利用されたコンポーネントが異なるページに表示されたときに、同じID /名前を持たないことです。ただし、それぞれに対して実行するテストは同じです。
例として、多くの場所で日付を収集します。したがって、このためのサンプルページオブジェクトは(月、日フィールドを削除)のようになります。
public class DatePageObject {
private WebDriver driver;
DatePageObject(WebDriver driver) {
this.driver = driver;
}
@FindBy( id = "someIdForThisInstance")
private WebElement year;
public void testYearNumeric() {
this.year.sendKeys('aa');
this.year.submit();
//Logic to determine Error message shows up
}
}
次に、以下のコードでこれを簡単にテストできます。
public class Test {
public static void main(String[] args) {
WebDriver driver = new FirefoxDriver();
DatePageObject dpo = PageFactory.initElements(driver, DriverPageObject.class);
driver.get("Some URL");
dpo.testYearNumeric();
}
}
私が本当にやりたいのは、Springを使用してid / name / xpathなどをアプリケーションに挿入できるように設定することです。
PageFactoryを利用する機能を失うことなくこれを行う方法はありますか?
編集1-カスタムロケーターとファクトリーで作業する、理想的な基本レベルのクラスを追加します。
public class PageElement {
private WebElement element;
private How how;
private String using;
PageElement(How how, String using) {
this.how = how;
this.using = using;
}
//Getters and Setters
}
public class PageWidget {
private List<PageElement> widgetElements;
}
public class Screen {
private List<PageWidget> fullPage;
private WebDriver driver;
public Screen(WebDriver driver) {
this.driver = driver;
for (PageWidget pw : fullPage) {
CustomPageFactory.initElements(driver, pw.class);
}
}
編集2-メモと同じように、Selenium 2.0.a5以降を実行している限り、ドライバーに暗黙のタイムアウト値を指定できます。
したがって、コードを次のコードに置き換えることができます。
private class CustomElementLocator implements ElementLocator {
private WebDriver driver;
private int timeOutInSeconds;
private final By by;
public CustomElementLocator(WebDriver driver, Field field,
int timeOutInSeconds) {
this.driver = driver;
this.timeOutInSeconds = timeOutInSeconds;
CustomAnnotations annotations = new CustomAnnotations(field);
this.by = annotations.buildBy();
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS); //Set this value in a more realistic place
}
public WebElement findElement() {
return driver.findElement(by);
}
}
共通Web要素のページオブジェクトを構築できます(この名前を発明したのは:))。各CWEは、異なるページで使用される「ウィジェット」を表します。あなたの例では、これはある種の日付ウィジェットです-年、月、日が含まれています。基本的にはページオブジェクトになります。
PageFactory
文字列定数を@FindBy
注釈で使用する必要があります。
この制限を解決するために、独自ElementLocator
のを作成しました。
DateWidget
テストでを使用できます。
....
DateWidget widget = new DateWidget(driver, "yearId", "monthId", "dayId");
....
public void testYearNumeric() {
widget.setYear("aa");
widget.submit();
//Logic to determine Error message shows up
// ... and day
widget.setDay("bb");
widget.submit();
//Logic to determine Error message shows up
}
DateWidget
カスタムロケータと注釈パーサが含まれているクラスは、次のとおりです。
package pagefactory.test;
import java.lang.reflect.Field;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.pagefactory.Annotations;
import org.openqa.selenium.support.pagefactory.ElementLocator;
import org.openqa.selenium.support.pagefactory.ElementLocatorFactory;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;
public class DateWidget {
// These constants are used to identify that they should be changed to the actual IDs
private static final String YEAR_ID = "$YEAR_ID$";
private static final String MONTH_ID = "$MONTH_ID$";
private static final String DAY_ID = "$DAY_ID$";
// Elements whose ids will be replaced during run-time
/** Year element */
@FindBy(id = YEAR_ID)
private WebElement year;
/** Month element */
@FindBy(id = MONTH_ID)
private WebElement month;
/** day element */
@FindBy(id = DAY_ID)
private WebElement day;
// The ids of the elements
/** ID of the year element */
private String yearId;
/** ID of the month element */
private String monthId;
/** ID of the day element */
private String dayId;
public DateWidget(WebDriver driver, String yearId, String monthId,
String dayId) {
this.yearId = yearId;
this.monthId = monthId;
this.dayId = dayId;
PageFactory.initElements(new CustomLocatorFactory(driver, 15), this);
}
public String getYear() {
return year.getValue();
}
public void setYear(String year) {
setValue(this.year, year);
}
public String getMonth() {
return month.getValue();
}
public void setMonth(String month) {
setValue(this.month, month);
}
public String getDay() {
return day.getValue();
}
public void setDay(String day) {
setValue(this.day, day);
}
public void submit() {
year.submit();
}
private void setValue(WebElement field, String value) {
field.clear();
field.sendKeys(value);
}
private class CustomLocatorFactory implements ElementLocatorFactory {
private final int timeOutInSeconds;
private WebDriver driver;
public CustomLocatorFactory(WebDriver driver, int timeOutInSeconds) {
this.driver = driver;
this.timeOutInSeconds = timeOutInSeconds;
}
public ElementLocator createLocator(Field field) {
return new CustomElementLocator(driver, field, timeOutInSeconds);
}
}
private class CustomElementLocator implements ElementLocator {
private WebDriver driver;
private int timeOutInSeconds;
private final By by;
public CustomElementLocator(WebDriver driver, Field field,
int timeOutInSeconds) {
this.driver = driver;
this.timeOutInSeconds = timeOutInSeconds;
CustomAnnotations annotations = new CustomAnnotations(field);
this.by = annotations.buildBy();
}
@Override
public WebElement findElement() {
ExpectedCondition<Boolean> e = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver d) {
d.findElement(by);
return Boolean.TRUE;
}
};
Wait<WebDriver> w = new WebDriverWait(driver, timeOutInSeconds);
w.until(e);
return driver.findElement(by);
}
}
private class CustomAnnotations extends Annotations {
public CustomAnnotations(Field field) {
super(field);
}
@Override
protected By buildByFromShortFindBy(FindBy findBy) {
if (!"".equals(findBy.id())) {
String id = findBy.id();
if (id.contains(YEAR_ID)) {
id = id.replace(YEAR_ID, yearId);
return By.id(id);
} else if (id.contains(MONTH_ID)) {
id = id.replace(MONTH_ID, monthId);
return By.id(id);
} else if (id.contains(DAY_ID)) {
id = id.replace(DAY_ID, dayId);
return By.id(id);
}
}
return super.buildByFromShortFindBy(findBy);
}
}
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加