Мне очень нравится, как селен 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 я могу добавить в приложение 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);
}
}