我真的很喜欢 selenium 2 按照惯例如何推动您使用 PageObjects 作为 POJO,然后简单地使用 PageFactory 来实例化此类中的字段。
我发现限制是我们在许多不同的页面上重用了很多元素。最大的问题是,这些重用的组件出现在不同页面时,它们的 id/name 并不相同;但是我们将为它们中的每一个运行的测试是相同的。
例如,我们在许多地方收集日期。因此,此示例页面对象可能是(已删除月、日字段):
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);
}
}