Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add custom ExpectedConditions for Selenium?

I'm trying to write my own ExpectedConditions for Selenium but I don't know how to add a new one. Does anyone have an example? I can't find any tutorials for this online.

In my current case I want to wait until an element exists, is visible, is enabled AND doesn't have the attr "aria-disabled". I know this code doesn't work:

var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(seconds));
return wait.Until<IWebElement>((d) =>
    {
        return ExpectedConditions.ElementExists(locator) 
        && ExpectedConditions.ElementIsVisible 
        &&  d.FindElement(locator).Enabled 
         && !d.FindElement(locator).GetAttribute("aria-disabled")
    }

EDIT: A little additional info: the problem I am running into is with jQuery tabs. I have a form on a disabled tab and it will start filling out fields on that tab before the tab becomes active.

like image 460
Rochelle C Avatar asked Jan 24 '14 18:01

Rochelle C


People also ask

What is Selenium ExpectedConditions?

Expected Conditions in Selenium WebDriver provide conditions that are frequently used for automating test scenarios for Selenium automation testing. Like other Selenium language bindings, Expected Conditions in Java provide ways through which you can realize Explicit Waits in the test code.

What is custom wait in Selenium?

The wait applies the condition which tries finding the web element, depending on its status. If the condition can find the element, it returns the element as result. If it cannot find the element, the wait tries the condition again after a short delay.

What is the difference between presenceOfElementLocated and visibilityOfElementLocated?

use presenceOfElementLocated when you don't care whether if element visible or not, you just need to know if it's on the page. use visibilityOfElementLocated when you need to find element which should be also visible.


2 Answers

An "expected condition" is nothing more than an anonymous method using a lambda expression. These have become a staple of .NET development since .NET 3.0, especially with the release of LINQ. Since the vast majority of .NET developers are comfortable with the C# lambda syntax, the WebDriver .NET bindings' ExpectedConditions implementation only has a few methods.

Creating a wait like you're asking for would look something like this:

WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until<IWebElement>((d) =>
{
    IWebElement element = d.FindElement(By.Id("myid"));
    if (element.Displayed &&
        element.Enabled &&
        element.GetAttribute("aria-disabled") == null)
    {
        return element;
    }

    return null;
});

If you're not experienced with this construct, I would recommend becoming so. It is only likely to become more prevalent in future versions of .NET.

like image 64
JimEvans Avatar answered Oct 20 '22 00:10

JimEvans


I understand the theory behind ExpectedConditions (I think), but I often find them cumbersome and difficult to use in practice.

I would go with this sort of approach:

public void WaitForElementPresentAndEnabled(By locator, int secondsToWait = 30)
{
   new WebDriverWait(driver, new TimeSpan(0, 0, secondsToWait))
      .Until(d => d.FindElement(locator).Enabled
          && d.FindElement(locator).Displayed
          && d.FindElement(locator).GetAttribute("aria-disabled") == null
      );
}

I will be happy to learn from an answer that uses all ExpectedConditions here :)

like image 33
Steve Weaver Crawford Avatar answered Oct 20 '22 00:10

Steve Weaver Crawford