Fix the Flaky Login Test
beginner Java 10 minA login test passes locally and fails one run in five on CI. Remove the sleeps and make it deterministic.
The Scenario
This test has been in the suite for a year. It passes on every developer laptop and fails roughly one run in five on the CI runners, always with either NoSuchElementException: h1.welcome or an assertion on the title showing Login | Example.
CI machines are slower and the dashboard fetches the user’s name from an API before rendering the heading. Nothing about the product is broken.
Your Task
Rewrite the test so it never depends on how long the app takes, and so it fails fast with a clear message if the app is genuinely broken. There should be no Thread.sleep left.
What Good Looks Like
- One
WebDriverWaitwith a sensible timeout, reused for each step. - Each wait targets the specific condition the next step needs.
- The title assertion happens after the navigation is known to have completed.
Your task
A login test passes locally and fails one run in five on CI. Remove the sleeps and make it deterministic.
@Test
void userCanLogIn() throws InterruptedException {
driver.get("https://app.example.com/login");
Thread.sleep(2000);
driver.findElement(By.id("email")).sendKeys("qa@example.com");
driver.findElement(By.id("password")).sendKeys("secret");
driver.findElement(By.cssSelector("button[type=submit]")).click();
Thread.sleep(3000);
assertEquals("Dashboard | Example", driver.getTitle());
WebElement heading = driver.findElement(By.cssSelector("h1.welcome"));
assertEquals("Welcome, QA", heading.getText());
}
Need Help?
Solution
Try to solve the challenge yourself before revealing the solution.
Lessons that cover this
- Explicit Waits Learn to use explicit waits in Selenium to handle dynamic content and avoid flaky tests.
- Flaky Tests: Diagnosis and Cure A systematic method for finding why a test passes sometimes: classify the failure, reproduce it deliberately, fix the root cause (timing, state, order, environment, product), and quarantine without hiding.