如何避免在同一个web元素上调用多个driver.findElement?

时间:2013-08-22 11:09:03

标签: webdriver selenium-webdriver ui-automation

我在我的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;

    }

这是正确的方法吗?

2 个答案:

答案 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注释,因为我希望控制缓存策略

相关问题