Selenium: ExpectedCondition vs ExpectedConditions
Tags: automation, java, selenium, testing
Published: 2023-01-31 15:47:00

Selenium is a popular testing framework used for automating web applications. One of the key features of Selenium is the ability to wait for specific conditions to be met before performing actions on a web page. The two main methods used for waiting in Selenium are ExpectedCondition and ExpectedConditions. In this post, we'll explore the difference between these two methods and when to use them.

## What are ExpectedCondition and ExpectedConditions?

ExpectedConditions is utility class which we use to apply waits in Explicit Wait in Selenium. This class includes conditions on which wait can be applied. But what we have to do, if we have to apply wait on some custom condition? Then ExpectedCondition come into picture. 

ExpectedCondition is an interface which inherits (extends) Function interface which is introduced in Java8 along with Consumer, Supplier and Predicate interface. 

## What is Function Interface and application in ExpectedCondition?
Function Interface is a type of functional interface that receives one argument and returns a value after the required processing. It has one method named apply which takes one parameter and return a value with specified type in second argument. 

```
public interface ExpectedCondition<T> extends Function<WebDriver, T> {}
```

As we can see in above code snippet, we are inheriting Function interface with one argument as WebDriver (which act as input) and T as return type which depends on value passed while implementing this interface. 

Let's see how this can help us while creating automation framework. As we have to use explicit wait with some custom condition which is not provided by `ExpectedConditions` class. Then we can implement this interface and override apply method given by this `ExpectedCondition` interface (which is inherited from Function interface).
Below code snippet helping us in creating a condition to have wait till Javascript get completely loaded on page.

```
ExpectedCondition<Boolean> expectedConditon=new ExpectedCondition<Boolean>() {
		@Override
		public Boolean apply(WebDriver driver) {
			return ((JavascriptExecutor) driver).executeScript("return document.readyState")
			        .toString().equals("complete");
		}
};
```
In above code snippet we are using anonymous class (class without any name) to implement `ExpectedCondition<T>` interface by passing Boolean as return type. And then implementing `apply` method which this interface inherits from `Function<F, T>` interface (a sort of functional interface).

## Best Practices for Using ExpectedCondition and ExpectedConditions

Here are some best practices to keep in mind when using ExpectedCondition and ExpectedConditions in your Selenium tests:

- Use ExpectedConditions when possible to save time and ensure consistency in your tests.
- Use ExpectedCondition when you need to define a custom condition that is not provided by Selenium.
- Always specify a timeout when using ExpectedCondition or ExpectedConditions to avoid waiting indefinitely.
- Use the ExpectedConditions.not() method to wait for an element to disappear from the page.
- Use the ExpectedConditions.and() and ExpectedConditions.or() methods to create more complex conditions.

## Conclusion

ExpectedCondition and ExpectedConditions are powerful tools in Selenium for waiting for specific conditions to be met before performing actions on a web page. By understanding the difference between these two methods and when to use them, you can write more efficient and effective Selenium tests. Remember to always use best practices like specifying a timeout and using pre-defined conditions when possible. ExpectedCondition is an interface and ExpectedConditions is a collection of static methods in Selenium that return ExpectedCondition objects.