原来写过的一篇WebElement元素过期的Blog,见下:
http://blog.sina.com.cn/s/blog_64693fd401012zoq.html
今天研究了org.openqa.selenium.support里面的东西
发现原来PageFactory可以避免元素过期的,例子见下:
首先定义两个一样的元素,其中一个由Locator指定;另一个由 @FindBy 注解修饰
By anyDealLocator =By.xpath("//h2[@class='deal-title']/a");
@FindBy(xpath = "//h2[@class='deal-title']/a") WebElementanyDealProxyed;
然后在构造函数里面调用
PageFactory.initElements(driver,this);
public HomePage(WebDriver driver)
{
this.driver = driver;
PageFactory.initElements(driver, this);
}
下面分别使用两个WebElment,看看效果?
其中按销量排序会使页面进行变化,导致原有的WebElement失效。
public void magic()
{
System.out.println(anyDealProxyed.getAttribute("title"));
driver.findElement(By.xpath("//a[text()='销量']")).click();//按销量排序
System.out.println(anyDealProxyed.getAttribute("title"));
}
结果:magic()方法 pass了;
public void magic2()
{
WebElement anyDeal = driver.findElement(anyDealLocator);
System.out.println(anyDeal.getAttribute("title"));
driver.findElement(By.xpath("//a[text()='销量']")).click();//按销量排序
System.out.println(anyDeal.getAttribute("title"));
}
结果:magic2()方法报错了;
//org.openqa.selenium.StaleElementReferenceExc
eption: Elementnot found in the cache - perhaps the page has changed since it waslooked up
回头来分析一下PageFactory这个玩意:
看一下initElement方法的JavaDoc:
Instantiate an instance of the given class, and set a lazyproxy for each of the WebElement and List fields that have beendeclared, assuming that the field name is also the HTML element's"id" or "name". This means that for the class:
public classPage { private WebElement submit; } there will be an elementthat can be located using the xpath expression "//*[@id='submit']"or "//*[@name='submit']"
By default, theelement or the list is looked up each and every time a method iscalled upon it. To change this behaviour, simply annotatethe field with the
CacheLookup. To change how the element is located, usethe
FindBy annotation. This method will attempt toinstantiate the class given to it, preferably using a constructorwhich takes a WebDriver instance as its only argument or fallingback on a no-arg constructor. An exception will be thrown if theclass cannot be instantiated.
看到了吧,一旦page被PageFactory进行处理过,每一次操作的时候都会去更新其声明的WebElement使其是最新的。
本文介绍如何利用Selenium中的PageFactory机制来避免WebElement元素过期的问题,通过实例对比展示了直接定位元素与使用@FindBy注解的方式在页面变化时的表现差异。
843

被折叠的 条评论
为什么被折叠?



