Automated Testing (IT)QA Automation Engineer

How to properly implement waiting and synchronization in automated UI tests?

Pass interviews with Hintsage AI assistant

Answer.

At the very beginning of UI test automation, the main difficulty was the instability of tests due to delays in element appearance and the need to wait for asynchronous actions on the page. Previously, testers often used hard waits (sleep), which led to long test execution times and low stability.

The problem is that web applications are becoming increasingly dynamic. Elements appear and disappear asynchronously, and the simultaneous operation of the frontend and backend can create situations where tests fail due to improper waiting for the UI state. Static pauses, such as Thread.sleep(1000), only increase the testing time and do not guarantee successful test completion.

The solution is to use explicit and implicit waits, which allow for more flexible and effective synchronization of actions with the actual state of the interface. For example, in Selenium or similar frameworks, WebDriverWait or equivalents are used to check for the appearance of required elements conditionally:

from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC wait = WebDriverWait(driver, 10) element = wait.until(EC.presence_of_element_located((By.ID, "myElem")))

Key features:

  • Less downtime for tests: tests continue as soon as the condition is met.
  • Reduced rate of false positives (flaky tests) due to UI dynamics.
  • Higher level of abstraction (waiting for complex conditions, e.g., changes in text values or the disappearance of elements).

Trick questions.

Why is it better not to use only implicit waits instead of explicit waits?

Implicit waits apply to the entire driver and can lead to unexpected delays or conflicts with explicit waits, which often results in "TimeoutException" errors.

Should Thread.sleep be used for waits in UI tests?

Using Thread.sleep is highly discouraged: it leads to unnecessary delays and test instability. It’s better to use explicit waits and conditions.

What to do if an element appears with animation?

Wait for not only the element itself but also its state (e.g., visibility or clickability) using special conditions like visibility_of_element_located.

Typical mistakes and anti-patterns

  • Using fixed timeouts (sleep) instead of conditions.
  • Conflict between explicit and implicit waits.
  • Waiting for the existence of an element when visibility or readiness for interaction is needed.

Real-life examples

Negative case

In the project, the waiting for the modal window to appear was implemented through Thread.sleep(3000). Sometimes the window appeared faster, sometimes slower. Scripts ran slowly, and under increased load, tests sometimes failed.

Pros:

  • Simplicity of implementation.
  • Quickly implemented without diving into synchronization.

Cons:

  • Test instability.
  • Increased execution time of automated tests across all environments.
  • Maintenance difficulties during UI improvements.

Positive case

The logic was redesigned — all actions with the UI were wrapped in functions with explicit waits for visibility and activity of elements, everything sped up, and stability increased to 98%.

Pros:

  • Stable and fast tests.
  • Easy scalability and maintenance of scenarios.

Cons:

  • During the implementation stage, time was needed to clarify all synchronization nuances.