Skip to main content

Overview

The Wait for Element step pauses your test until an element meets a specific condition - appearing, disappearing, or existing in the page. It’s essential for handling dynamic content, loading states, and ensuring elements are ready before you interact with them.

When to Use Wait for Element

Use Wait for Element when you need to:
  • Handle dynamic content: Wait for elements that load asynchronously via AJAX or API calls
  • Wait for loading states: Pause until loading spinners disappear before continuing
  • Ensure element readiness: Verify elements are visible before clicking or filling them
  • Handle animations: Wait for transitions and animations to complete
  • Synchronize with app state: Ensure your app reaches the right state before testing

How It Works

Wait for Element continuously checks if an element meets your specified condition (visible, hidden, or exists). It polls the page repeatedly until either the condition is met or the timeout is reached. This is different from fixed delays - instead of blindly waiting a set amount of time, Wait for Element completes as soon as the condition is satisfied. This makes tests both faster (when content loads quickly) and more reliable (when content takes longer than expected).

Using the Wait for Element Step

When you add a Wait for Element step, you’ll configure:

Finding Your Element

Use the element picker to visually select the element, or enter a CSS selector directly. This should be the element whose state you’re waiting for - like a loading spinner, content container, or specific UI element.

Choosing Your Condition

Visible (Most Common) Wait until the element appears on the page and is visible to users. The element must exist in the DOM, have visible dimensions, and not be hidden by CSS. Use this before clicking, filling, or verifying content. Hidden Wait until the element disappears or becomes hidden. The condition is satisfied when the element either doesn’t exist in the DOM or is hidden by CSS (display: none, visibility: hidden). Perfect for waiting for loading spinners to disappear. Exists Wait until the element exists in the DOM, regardless of whether it’s visible. Use this for elements that are present but might be hidden, or when you only care about DOM presence.

Setting Timeout (Optional)

Specify how long to wait (in milliseconds) before giving up. The default is typically 30 seconds (30000ms). The step completes immediately when the condition is met, so timeouts are only relevant when the condition isn’t satisfied.

Real-World Examples

Waiting for Page Content to Load

Step 1: Navigate
  URL: https://example.com/dashboard

Step 2: Wait for Element
  Locator: [data-testid='dashboard-content']
  Condition: Visible
  Timeout: 10000

Step 3: Check Text
  Locator: .welcome-message
  Expected Text: Welcome back!
Why this works: Ensure the dashboard content loads before verifying text.

Waiting for Loading Spinner to Disappear

Step 1: Click
  Locator: button[data-action='load-data']

Step 2: Check Visibility
  Locator: .loading-spinner
  Assertion: Is visible

Step 3: Wait for Element
  Locator: .loading-spinner
  Condition: Hidden
  Timeout: 15000

Step 4: Check Visibility
  Locator: .data-table
  Assertion: Is visible
Why this works: Click a button that triggers loading, verify the spinner appears, wait for it to disappear, then verify the data loaded.

Waiting for Search Results

Step 1: Fill
  Locator: input[name='search']
  Text: laptop

Step 2: Press Keys
  Keys: Enter

Step 3: Wait for Element
  Locator: .search-results
  Condition: Visible
  Timeout: 8000

Step 4: Check Visibility
  Locator: .result-item
  Assertion: Is visible
Why this works: Submit a search and wait for results before verifying they appeared.

Waiting for Modal to Close

Step 1: Click
  Locator: button[data-action='delete']

Step 2: Check Visibility
  Locator: .confirmation-modal
  Assertion: Is visible

Step 3: Click
  Locator: button[data-action='confirm-delete']

Step 4: Wait for Element
  Locator: .confirmation-modal
  Condition: Hidden
  Timeout: 5000

Step 5: Check Visibility
  Locator: .success-notification
  Assertion: Is visible
Why this works: Click delete, confirm in the modal, wait for the modal to close, then verify success.

Waiting for Form Validation

Step 1: Fill
  Locator: input[name='email']
  Text: invalid-email

Step 2: Click
  Locator: button[type='submit']

Step 3: Wait for Element
  Locator: .email-error-message
  Condition: Visible
  Timeout: 3000

Step 4: Check Text
  Locator: .email-error-message
  Expected Text: Please enter a valid email address
Why this works: Submit an invalid email and wait for the error message before verifying its text.

Waiting After Infinite Scroll

Step 1: Navigate
  URL: https://example.com/blog

Step 2: Scroll
  Direction: Down
  Pixels: 1000
  Locator: body

Step 3: Wait for Element
  Locator: .loading-more
  Condition: Visible
  Timeout: 2000

Step 4: Wait for Element
  Locator: .loading-more
  Condition: Hidden
  Timeout: 10000

Step 5: Check Visibility
  Locator: .blog-post:nth-child(20)
  Assertion: Is visible
Why this works: Scroll to trigger infinite scroll, wait for the loading indicator to appear and disappear, then verify new content loaded.

Best Practices

Choose the Right Condition

  • Use Visible before interacting with elements (clicking, filling)
  • Use Hidden when waiting for loading states to clear
  • Use Exists when you only need DOM presence, not visibility

Set Reasonable Timeouts

  • 3-5 seconds for fast interactions (form validation, button clicks)
  • 10-15 seconds for data loading (API calls, search results)
  • 20-30 seconds for slow operations (report generation, file uploads)
  • Don’t use excessively long timeouts that slow down failing tests

Write Specific Selectors

  • Target exact elements: [data-testid='search-results']
  • Use unique attributes when possible
  • Avoid selectors that might match multiple elements
  • Test selectors with the element picker

Chain Waits Appropriately

  • Wait before actions that require the element to exist
  • Wait after actions that trigger changes
  • Don’t wait unnecessarily if the element is already stable

Verify After Waiting

Always add verification after waits:

Troubleshooting

Timeout Errors

Symptom: Test fails with “Element not found” or “Timeout waiting for element” Solution:
  • Verify the selector is correct using the element picker
  • Check that the element actually appears/disappears as expected
  • Increase the timeout if content loads slowly
  • Inspect the page manually to confirm the element exists
  • Check network/console for errors preventing the element from loading

Element Never Becomes Visible

Symptom: Wait times out even though the element exists Solution:
  • Element might be in the DOM but hidden (display: none, opacity: 0)
  • Check CSS properties to confirm the element is actually visible
  • Verify the element isn’t covered by another element
  • Try waiting for “Exists” instead of “Visible” if visibility doesn’t matter
  • Check if parent containers are hidden

Element Never Disappears

Symptom: Waiting for Hidden times out but element seems gone Solution:
  • Element might still exist in DOM but be invisible
  • “Hidden” condition is satisfied when element doesn’t exist OR is hidden
  • Check if the element is removed vs. just hidden
  • Verify the selector matches the element that should disappear
  • Check for JavaScript errors preventing removal

Waits Too Long

Symptom: Tests are slow because waits take the full timeout Solution:
  • Reduce timeout values for faster-loading content
  • Check if the condition is ever being satisfied
  • Verify your application is working correctly
  • Look for network issues or slow API responses
  • Use browser dev tools to profile loading times

Wrong Element Detected

Symptom: Wait completes but for the wrong element Solution:
  • Make selectors more specific to target the exact element
  • Check if multiple elements match your selector
  • Use unique data-testid attributes
  • Verify the wait condition matches what you expect

Understanding Wait Conditions

Visible vs. Exists

  • Visible: Element exists AND has visible dimensions AND isn’t hidden by CSS
  • Exists: Element is present in the DOM (might be hidden)
Use Visible before interactions (click, fill). Use Exists when you only care about DOM presence.

Hidden Behavior

Hidden is satisfied when:
  • Element doesn’t exist in DOM at all, OR
  • Element has display: none, OR
  • Element has visibility: hidden
Elements with opacity: 0 or positioned off-screen are still considered “visible” for the Visible condition.
  • Check Visibility - Verify element visibility after waiting
  • Check Text - Verify content after element appears
  • Click - Interact with elements after waiting for them
  • Fill - Fill inputs after waiting for them to be ready
  • Navigate - Wait after navigation for content to load
  • Reload - Wait after reload for content to load