Мне очень нравится, как селен 2 по соглашению подталкивает вас к использованию PageObjects в качестве POJO, а затем просто к использованию PageFactory для создания экземпляров полей в этом классе.
Что я нахожу ограничивающим заключается в том, что мы повторно используем множество элементов на разных страницах. Большая проблема в том, что эти повторно используемые компоненты не имеют одинаковых идентификаторов / имен, когда они появляются на разных страницах; однако тесты, которые мы будем запускать для каждого из них, одинаковы.
В качестве примера мы собираем даты во многих местах. Таким образом, пример объекта страницы для этого может быть (поля месяца и дня удалены):
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 I может ввести этот идентификатор / имя / 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);
}
}