Friday 6 May 2016

Why FluentWait required?

Before jumping into fluentwait, let’s understand a bit about other waits

1. Implicit:  
- Applicable for all the elements.
- Waits for the specified amount of time for an Element (Ex: 60 sec). 
- It will come out of waiting loop, if Element found (Ex: 10 sec).
- Throws 'No Such Element Exception' If element not found with in specified amount     (Ex. 60 sec) of time.

driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);


2. Explicit:
- Applicable for said Element. (Only one element)
- Explicit overrides Implicit wait. (Ex: 120 sec)
- We can mention our condition, until satisfied. (I.e. expected condition)
- Returns WebElement 
- Throws Exception If element not found with in specified amount (Ex. 120 sec) of time.

WebDriverWait wait = new WebDriverWait(driver, 120); 
element = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("myId"));

** Here polling time is fixed. i.e 500 milli seconds.


Disadvantages:
- We cannot configure polling time. (i.e. 750 milli secs )
- Accepts only 'By' object, but not WebElement (for most of the Expected Condition method variables)
- There is no way to skip few Exceptions, if you wanted (i.e you wanted to continue wait for an element event though few exceptions thrown)

3. Fluent:
Above Disadvantages are Advantages here.

- Custom polling time
- Accepts WebElement as parameter
- Ignore specific types of exception waiting such as NoSuchElementExceptions while searching for an element on the page.



public static void elementIsDisplayedFluentlyPredicate(WebElement element, long timeOutInSeconds,
                                                long sleepTimeOut) {
                                new FluentWait<WebElement>(element).withTimeout(10, TimeUnit.SECONDS).pollingEvery(100, TimeUnit.MILLISECONDS)
                                                                .ignoring(NoSuchElementException.class).until(new Function<WebElement, Boolean>() {
                                                                                public Boolean apply(WebElement element) {
                                                                                                return element.isDisplayed();
                                                                                }
                                                                });

                }