我在我的selenium webdriver + TestNG框架中使用PageObject模式。
在我的pageObject类中,我有多个方法,我使用driver.findElement来查找同一页面上存在的相同webelement。
例如:
public class HomePage extends BasePage {
private WebElement searchField;
private String searchFieldLocator;
HomePage(WebDriver driverFromTest, CustomLogger loggerFromTest,
HashMap<String, String> testDataMapFromTest)
{
super(driverFromTest, loggerFromTest, testDataMapFromTest);
searchFieldLocator = testDataMap.get("searchFieldLocator");
}
public void method1()
{
searchField = driver.findElement(By.cssSelector(searchFieldLocator));
searchField.sendKeys("foo");
}
public void method2()
{
searchField = driver.findElement(By.cssSelector(searchFieldLocator));
searchField.sendKeys("bar");
}
我的问题是:
1.如何避免多次在同一个WebElement变量上使用driver.findElement。我想要一种方法,一旦我找到了webelement,我将在任何其他方法中使用该变量而不使用driver.findElement。我已经阅读了有关PageFactory的内容,您可以将@FindBy(how = How.NAME,using =“locatorstring”)与@CacheLookup注释一起使用。这是我需要的吗? CacheLookup是否仅使用driver.findElement一次并重新使用引用?
2.其次,当你为同一个web元素执行driver.findElements太多次时,它会变成内存密集型吗?我不需要担心这种微观优化吗?
我想到了一种方法,可以通过编写如下方法来避免在同一个web元素上执行driver.findElement:
protected WebElement getWebElement(By by, String elementName) {
WebElement element;
if(webElementMap.get(elementName)==null)
{
element = driver.findElement(by);
webElementMap.put(elementName, element);
}
else
element = webElementMap.get(elementName);
return element;
}
这是正确的方法吗?
答案 0 :(得分:1)
是
@CacheLookup只使用一次driver.findElement并重新使用该引用。
注意你可能会开始穿越StaleElementReferenceException的
答案 1 :(得分:1)
使用网格提供程序(如Saucelabs)时,多次调用可能会出现问题。
每个Webdriver命令都会产生一个API调用,因此以下内容将进行两次API调用;
searchField = driver.findElement(By.cssSelector(searchFieldLocator));
searchField.sendKeys("foo");
对网格的请求将比使用ChromeDriver等特定驱动程序的速度慢,因此在编写可能使用Grid的测试时必须考虑这一点。缓存对象是实现这一目标的方法。
但是,如果您缓存对象,则可能会遇到StaleObject
个问题,因此您要引用Kenny Rogers;
“你必须知道何时抓住他们,知道什么时候弃他们”
我个人远离@FindBy
和@CacheLookup
注释,因为我希望控制缓存策略