Webdriver How to wait until the element is clickable in webdriver C#

前端 未结 4 1901
一整个雨季
一整个雨季 2020-11-29 08:56

There is a block Ui which covers all the elements for a few seconds after the Element have been generated in the browser because of this i facing a problem ,Since element ha

相关标签:
4条回答
  • 2020-11-29 09:00

    On our slower test runner computers it seemed the input element would be findable first, but still not clickable by the time that the script tried to send keys or a click to the input control. Waiting for "ElementToBeClickable" helped. Faster, more powerful test runner systems did not have this problem nearly as much.

    Here is code with a bit of context that seems to have improved things on my C# based Selenium tests. Also using SpecFlow and xUnit. We are using IE11 and IEDriverServer.exe.

    As of May 2019, the NuGet package containing this is DotNetSeleniumExtras.WaitHelpers.

    The key line is this one:

    wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By...

    Do this for the first input field on a new page, using a selector that points to the first input field you want to interact with. (By.XPath("")

    [Given(@"I have selected the link to the OrgPlus application")]
    public void GivenIHaveSelectedTheLinkToTheOrgPlusApplication()
    {
        _driver.Navigate().GoToUrl("http://orgplus.myorg.org/ope?footer");
    }
    
    [Given(@"I have selected the link to the OrgPlus Directory lookup")]
    public void GivenIHaveSelectedTheLinkToTheOrgPlusDirectoryLookup()
    {
        var wait = new WebDriverWait(_driver, new TimeSpan(0, 0, 30));
        var element = wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.XPath("//*[@id=\"lnkDir\"]")));
        IWebElement btnSearch = _driver.FindElement(By.XPath("//*[@id=\"lnkDir\"]"));
        btnSearch.SendKeys(Keys.Enter);
    }
    
    0 讨论(0)
  • 2020-11-29 09:08

    Here's the code I use to check if it's clickable, else go to another URL.

    if (logOutLink.Exists() && ExpectedConditions.ElementToBeClickable(logOutLink).Equals(true))
                {
                    logOutLink.Click();
                }
                else
                {
                    Browser.Goto("/");
                }
    
    0 讨论(0)
  • 2020-11-29 09:13

    Well taking a look into the Java source, tells me it is basically doing two things to determine if it's 'clickable':

    https://code.google.com/p/selenium/source/browse/java/client/src/org/openqa/selenium/support/ui/ExpectedConditions.java

    Firstly, it'll check if it's 'visible' by using the standard ExpectedConditions.visibilityOfElementLocated, it'll then simply check if the element.isEnabled() is true or not.

    This can be condensed slightly, this basically means (simplified, in C#):

    1. Wait until the element is returned from the DOM
    2. Wait until the element's .Displayed property is true (which is essentially what visibilityOfElementLocated is checking for).
    3. Wait until the element's .Enabled property is true (which is essentially what the elementToBeClickable is checking for).

    I would implement this like so (adding onto the current set of ExpectedConditions, but there are multiple ways of doing it:

    /// <summary>
    /// An expectation for checking whether an element is visible.
    /// </summary>
    /// <param name="locator">The locator used to find the element.</param>
    /// <returns>The <see cref="IWebElement"/> once it is located, visible and clickable.</returns>
    public static Func<IWebDriver, IWebElement> ElementIsClickable(By locator)
    {
        return driver =>
        {
            var element = driver.FindElement(locator);
            return (element != null && element.Displayed && element.Enabled) ? element : null;
        };
    }
    

    Usable in something like:

    var wait = new WebDriverWait(driver, TimeSpan.FromMinutes(1));
    var clickableElement = wait.Until(ExpectedConditions.ElementIsClickable(By.Id("id")));
    

    However, you might have a different idea of what clickable might mean, in which case, this solution may not work - but it is a direct translation of what the Java code is doing.

    0 讨论(0)
  • 2020-11-29 09:21

    If you are having an issue such as "Another element would receive the click", a way around this is to use a while loop that waits for that overlay box to go away.

    //The below code waits 2 times in order for the problem element to go away.
    int attempts = 2;
    var elementsWeWantGone = WebDriver.FindElements(By.Id("id"));
    while (attempts > 0 && elementsWeWantGone.Count > 0)
    {
        Thread.Sleep(500);
        elementsWeWantGone = WebDriver.FindElements(By.Id("id"));
    }
    
    0 讨论(0)
提交回复
热议问题