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

问题描述 投票:0回答:2

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

    }

这是正确的方法吗?

webdriver selenium-webdriver ui-automation
2个回答
1
投票

@CacheLookup只使用一次driver.findElement并重新使用该引用。

注意你可能会开始遇到StaleElementReferenceException


1
投票

使用网格提供程序(如Saucelabs)时,多次调用可能会出现问题。

每个Webdriver命令都会产生一个API调用,因此以下内容会产生两个API调用;

searchField = driver.findElement(By.cssSelector(searchFieldLocator));
searchField.sendKeys("foo");

对网格的请求将比使用特定驱动程序(如ChromeDriver)慢一些,因此在编写可能使用Grid的测试时必须考虑这一点。缓存对象是实现此目的的方法。

但是,如果你缓存对象,你可能会遇到StaleObject问题,所以你引用Kenny Rogers;

“你必须知道何时抓住他们,知道何时弃他们”

我个人远离@FindBy@CacheLookup注释因为我想控制缓存策略

© www.soinside.com 2019 - 2024. All rights reserved.