In this chapter, we had a look at the various kinds of synchronization. We started off with Thread.sleep and learned how it is not feasible in most situations. We looked at explicit waits and the ExpectedConditions class. We also learned about fluent waits, and learned how to configure the polling time and use it to display text at intervals. We explored the Function and 'predicates' components of fluent waits.
Finally, we established a best practice of not using implicit and explicit waits together. Doing so can have an unpredictable impact on the execution time of your script, and can even break explicit waits.
In the next chapter, we will dive deep into the Actions class and JavascriptExecutor in detail.