我试图将我的selenium测试转换为使用Page Object Model(以及扩展名为@FindBy)。我有几个像这样的对象定义:
public WebElement objectParent() {
return driver.findElement(By.name("parent-id")) ;
}
public WebElement objectChild() {
WebElement elem = objectParent();
return elem.findElement(By.name("child-id")) ;
}
将父对象转换为使用@FindBy
非常简单:
@FindBy(name = "parent-id")
WebElement parentObj;
基本上,如果可能的话,我想做这样的事情(我知道这不是真正的代码,这只是一个伪示例:
@FindBy(name = "parent-id")
WebElement parentObj;
@FindBy(parentObj.name = "child-id")
WebElement childObj;
但是有没有办法使用@FindBy?
将内的子元素定位到父元素中。我需要这样做,因为我定位页面上可能与页面上的其他元素共享相同名称或类名的特定元素。谢谢!
答案 0 :(得分:2)
如果不编写自定义ElementLocatorFactory
,就无法轻松实现。
首先我建议使用XPath。
这样可以很容易地抓住:
第3 <table>
就像这样:@FindBy(xpath = "\\table[3]")
和...
第3个表中的第二个<li>
就像这样:@FindBy(xpath = "\\table[3]\li[2]")
。
但如果你真的想用更短的@FindBy
注释来做,那么你可以选择ElementLocatorFactory
。
public class FindByContextModifier implements ElementLocatorFactory {
private final SearchContext context;
public FindByContextModifier(final SearchContext context) {
this.context = context;
}
public ElementLocator createLocator(final Field field) {
return new DefaultElementLocator(context, field);
}
}
带有元素的类,它将为您提供上下文:
public class Parent {
@FindBy(name = "myTable")
WebElement table;
public WebElement getTable() {
return this.table;
}
}
它的孩子:
public class Child {
@FindBy(name = "particular")
WebElement specialTableListElement;
}
用法:
Parent parent = PageFactory.initElements(driver, Parent.class);
FindByContextModifier parentContext = new FindByContextModifier(parent.getTable());
Child child = new Child();
// This will look for the name "particular" inside the element with "myTable" name
PageFactory.initElements(parentContext, child);
答案 1 :(得分:1)
上述方法有效,但是,如果您使用的是xpath,请确保您的'child'元素前面有一个.//
以使其相对。
答案 2 :(得分:0)
您无需编写自定义ElemLocatorFactory
,只需使用org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory
:
Parent parent = PageFactory.initElements(driver, Parent.class);
DefaultElementLocatorFactory parentContext = new DefaultElementLocatorFactory(parent.getTable());
Child child = new Child();
PageFactory.initElements(parentContext, child);