Selenium Webdriver:使用相对于其他元素的路径进行页面工厂初始化?

我正在尝试使用页面工厂@FindBy注释在Selenium Webdriver中编写页面对象。 页面对象用于侧边栏,包含页面对象需要与之交互的所有元素的父WebElement以这种方式初始化:

 @FindBy (xpath = "//div[contains(@class,'yui3-accordion-panel-content') and child::div[.='Sidebar']]") WebElement sidebar; 

然后我想要相对于这个sidebar元素的搜索输入。 有没有办法做这个引用sidebar元素? 我可以将整个路径复制并粘贴到开头:

 @FindBy (xpath = "//div[contains(@class,'yui3-accordion-panel-content') and child::div[.='Sidebar']]//input[@id='search']") 

但我宁愿相对于第一个元素。 这样的事情可能吗?

 @FindBy (parent = "sidebar", xpath = ".//input[@id='search']") 

关于@FindBy注释的Selenium文档有点缺乏……

回答我自己的问题。

答案是实现一个ElementLocatorFactory,它允许您提供搜索上下文(意思是驱动程序或WebElement)。

 public class SearchContextElementLocatorFactory implements ElementLocatorFactory { private final SearchContext context; public SearchContextElementLocatorFactory(SearchContext context) { this.context = context; } @Override public ElementLocator createLocator(Field field) { return new DefaultElementLocator(context, field); } } 

然后,在实例化页面对象时,使用此定位器工厂。

 WebElement parent = driver.findElement(By.xpath("//div[contains(@class,'yui3-accordion-panel-content') and child::div[.='Sidebar']]")); SearchContextElementLocatorFactory elementLocatorFactory = new SearchContextElementLocatorFactory(parent); PageFactory.initElements(elementLocatorFactory, this); 

现在你的@FindBy注释将相对于parent 。 例如,要获取主侧边栏WebElement

 @FindBy(xpath = ".") WebElement sideBar; 

不,这种方式不可能。 但是您可以使用getter方法而不是基于注释的初始化:

 public class SomePage { @FindBy (xpath = "//div[contains(@class,'yui3-accordion-panel-content') and child::div[.='Sidebar']]") private WebElement sidebar; private WebElement getSomeChildElement() { return siderbar.findElement(By.id("somechild")); } }