【问题标题】:Explicit Wait for findElements in Selenium Webdriver在 Selenium Webdriver 中显式等待 findElements
【发布时间】:2020-04-11 08:31:56
【问题描述】:

登录后,页面重定向到一个页面(我想等待页面加载),在那里我通过 tagName 查找元素,

By inputArea = By.tagName("input");
 List <WebElement> myIput = driver.findElements(inputArea);

在这里我想显式等待 findElements,我想等待它的所有可见性或存在。我的网页中只有两个输入。如果我给隐式等待很长时间,代码将起作用。但它会有所不同。所以我决定给明确的等待,我怎样才能给 findElements 明确的等待?或者我如何检查列表中第二个的可见性(List myIput)。即,myIput.get(1)。当我给出如下所示的 visibilityOfAllElements() 时,它会引发错误。

WebDriverWait waitForFormLabel = new WebDriverWait(driver, 30);      
By inputArea = By.tagName("input");
List <WebElement> myIput = driver.findElements(inputArea);
waitForFormLabel.until(ExpectedConditions.visibilityOfAllElements(myIput));
myIput.get(1).sendKeys("Test");

这是我在自动化程序中使用的代码列表。

package mapap;
import java.util.ArrayList;
import java.util.List;

import lib.ReadExcellData;
import lib.WriteExcellData;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import com.relevantcodes.extentreports.ExtentReports;
import com.relevantcodes.extentreports.ExtentTest;
import com.relevantcodes.extentreports.LogStatus;

public class EditForm {
    public static WebDriver driver;
    static String excelName         = "D:\\xlsx\\map2.xlsx";
    ReadExcellData readData         = new ReadExcellData(excelName);
    WriteExcellData writeData       = new WriteExcellData(excelName); 
    String baseUrl                   = readData.getExcellData("base", 0, 0);    
    By colRadio;
    ExtentReports  report;
    ExtentTest logger;

    @BeforeClass
    public void browserOpen() throws Exception{

        report = new ExtentReports("D:\\driver\\extentRepo\\Edit Map Forms.html", true);
        logger = report.startTest("Map Forms Automation Testing", "Adding Forms");

        driver = new FirefoxDriver();       
        driver.get(baseUrl);
        String username = readData.getExcellData("user", 1, 0);
        String password = readData.getExcellData("user", 1, 1); 
        WebDriverWait waitForUserName = new WebDriverWait(driver, 250);
        By usernameField = By.name("username");
        waitForUserName.until(ExpectedConditions.elementToBeClickable(usernameField)).sendKeys(username);
        driver.findElement(By.name("password")).sendKeys(password);
        driver.findElement(By.xpath("//input[contains(@src,'/images/signin.png')]")).click();

    }

    @Test(priority = 1)
    public void addingForm() throws Exception{      
            driver.navigate().to(baseUrl+"/anglr/form-builder/dist/#/forms");
        driver.manage().window().maximize();       
        WebDriverWait waitForFormLabel = new WebDriverWait(driver, 30);      
        By inputArea = By.tagName("input");
        List <WebElement> myIput = driver.findElements(inputArea);
        waitForFormLabel.until(ExpectedConditions.visibilityOfAllElements(myIput));
        myIput.get(1).sendKeys("Test");


    }

}

请注意:如果我在代码 "driver.navigate().to(baseUrl+"/anglr/form-b​​uilder/dist/#/forms");" 之后给了 Thread.sleep 很长一段时间,我会得到所有 Web 元素。但我想避免这种情况,我只想等待 WebElements 加载()。

请大家帮忙。

【问题讨论】:

    标签: java selenium selenium-webdriver


    【解决方案1】:

    你可以这样做:

    //explicit wait for input field field
    WebDriverWait wait = new WebDriverWait(driver, 10);
    wait.until(ExpectedConditions.visibilityOfElementLocated(By.tagName("input")));
    

    ExpectedConditions 类在很多情况下都很有用,它提供了一些预定义的条件来等待元素。以下是其中一些:

    • alertIsPresent :存在警报
    • elementSelectionStateToBe:元素状态是选择。
    • elementToBeClickable:元素存在且可点击。
    • elementToBeSelected: 元素被选中
    • frameToBeAvailableAndSwitchToIt:框架可用且框架已选择。
    • invisibilityOfElementLocated: 元素不可见
    • presenceOfAllElementsLocatedBy:当前元素所在的位置。
    • textToBePresentInElement: 特定元素上的文本
    • textToBePresentInElementValue: 以及特定元素的元素值。
    • visibilityOf:可见元素。
    • titleContains: 标题包含

    【讨论】:

    • 虽然这解决了 OPs 问题,但我来这里是为了寻找问题的答案(在 FindElements 上放置显式等待),而这个答案并没有真正提供。
    • 除非您创建自己的包装方法,否则您不能将超时作为findElements 方法的参数传递(如果我正确理解您想要实现的目标)。我不明白的是为什么你首先需要这样做,所以也许一些上下文会有所帮助。
    • 有很多充分的理由。例如,等待元素显示在页面上,而不必让每个元素查找都花费一个时间并摆弄隐式等待以将其用作假的显式等待。请参阅我的答案以获取可能的解决方案。我只是决定自己解决这个问题。是的,它只是按照你的建议做一个包装器
    【解决方案2】:

    我决定弄清楚如何解决我的用例,我的用例想要对特定的 FindElements 调用进行显式等待,但不是所有调用,并且摆弄隐式等待感觉不干净和可怕。所以我为 IWebDriver 实现了一个扩展方法,它使用 WebDriverWait(参见 Selenium 中的显式等待)来实现它。

        /// <summary>
        /// Allows you to execute the FindElements call but specify your own timeout explicitly for this single lookup
        /// </summary>
        /// <remarks>
        /// If you want no timeout, you can pass in TimeSpan.FromSeconds(0) to return an empty list if no elements match immediately. But then you may as well use the original method
        /// </remarks>
        /// <param name="driver">The IWebDriver instance to do the lookup with</param>
        /// <param name="findBy">The By expression to use to find matching elements</param>
        /// <param name="timeout">A timespan specifying how long to wait for the element to be available</param>
        public static ReadOnlyCollection<IWebElement> FindElements(this IWebDriver driver, By findBy, TimeSpan timeout)
        {
            var wait = new WebDriverWait(driver, timeout);
            return wait.Until((d) =>
            {
                var elements = d.FindElements(findBy);
                return (elements.Count > 0)
                    ? elements
                    : null;
            });
        }
    

    【讨论】:

    • 你做的实现几乎和这个one-liner在引擎盖下所做的一样。一切都已经实现,无需重新发明轮子:var allElements = Wait.Until(ExpectedConditions.PresenceOfAllElementsLocatedBy(By.XPath(".//")));github.com/SeleniumHQ/selenium/blob/master/dotnet/src/support/…
    • 很抱歉,但我不同意,这与您提出的答案之间存在差异。这个关键实际上使用了 FindElements,这正是我想要的,即使 OP 对使用 ExpectedCondition 感到满意。您已经获得了接受答案的代表。不要惊慌。
    • @Cosmin:即使是最初的 Selenium 创建者之一也不会评价预期条件,正如我们的一位测试自动化专家在我与他谈及此事时指出的那样。所以,我尽量避免使用 ExpectedConditions。观看他的一个主题演讲中的这段视频,了解他的感受:youtu.be/gyfUpOysIF8?t=29m
    猜你喜欢
    • 2013-12-03
    • 1970-01-01
    • 2013-05-28
    • 1970-01-01
    • 2012-05-11
    • 2015-10-09
    • 1970-01-01
    • 2018-01-24
    相关资源
    最近更新 更多