In UI automation, waits are required because certain elements get loaded on the page asynchronously, so after triggering an event a page may get loaded successfully but some of its element may still not get loaded. This causes elementNotFound exception while locating the element. In such cases we are left with using Thread.sleep() i.e. a static wait that will halt the test execution for some specified time and than perform the next step. As Thread.sleep() will wait for the specified time no matter if the elements gets visible before that time. So, using Thread.sleep() is never advisable in UI automation.
To avoid this selenium provides different types of waits out of which Implicit and explicit waits are most commonly used.
An implicit wait when used is set to the WebDriver instance and is applied to all the web elements. In implicit wait the webdriver polls the DOM to check the availability of the webElement and waits till the maximum time specified before throwing NoSuchElementException.
In the above code snippet, the value 20 specified in implicit wait method is the maximum time in seconds till which webDriver will wait before throwing NoSuchElementException while locating a webElement.
Unlike implicit waits, the explicit waits are applied to each and every webElement. In explicit wait, certain conditions are defined for which the webDriver instance waits before locating webElements or performing actions on them. Some of the most common conditions specified in explicit waits are-
elementToBeClickable, presenceOfElementLocated etc.
Here the webDriver instance will wait until the condition specified is met i.e. the presence Of Element located by the ElementLocator with the maximum wait time of 15 seconds after which if the condition is still not met than it will throw exception.