WebdriverIO Assertions: The Complete Guide for 2026
Master WebdriverIO's built-in assertion library. Learn how to use browser and element matchers to create robust, self-healing automated tests.
Introduction
🎯 Quick Answer
WebdriverIO uses the expect-webdriverio library, which provides a set of specialized matchers for browser and element assertions. These assertions are asynchronous and feature built-in retry logic, meaning they will automatically wait for a condition to be met before failing. The basic syntax is await expect(element).toBeDisplayed(). This makes your tests more resilient to network latency and slow-rendering components.
In end-to-end testing, assertions are the heart of your scripts. They are the checkpoints that verify whether your application is behaving as expected. WebdriverIO's assertion library is built on top of Jest's expect but is specifically optimized for the asynchronous nature of web browsers.
📖 Key Definitions
- Matcher
A specialized function used in an assertion to verify a specific property or state (e.g.,
toHaveText,toBeEnabled).- Asynchronous Assertion
An assertion that returns a promise and waits for a condition to be true within a specified timeout period.
- Soft Assertion
An assertion that allows the test to continue even if it fails, typically used for non-critical UI checks.
- Retry Logic
The mechanism that repeatedly checks a condition until it passes or the timeout is reached, reducing "flaky" test results.
Core Matchers in WebdriverIO
WebdriverIO categorizes its matchers into browser-level and element-level checks.
Browser Matchers
These are used to verify the state of the entire browser window or tab.
toHaveUrl: Verifies the exact current page URL.toHaveTitle: Checks the page title for an exact match or substring.toHaveUrlContaining: Checks if the current URL contains a specific string.
Element Matchers
These are used to verify the state or properties of specific DOM elements.
toBeDisplayed: Checks if an element is visible to the user.toExist: Checks if an element is present in the DOM (even if hidden).toBeEnabled: Verifies that an input or button is not disabled.toHaveText: Matches the visible text content of an element.toHaveValue: Checks the current value of an input field.toBeSelected: Verifies if a checkbox, radio button, or option is selected.
🚀 Step-by-Step Implementation
Identify the Target
Locate the element or browser property you want to verify using a selector (e.g., const btn = await $('#submit')).
Choose the Right Matcher
Select a matcher that fits your requirement (e.g., use toBeClickable if you want to ensure the button can be interacted with).
Write the Assertion
Use the await expect(...) syntax to perform the check.
Configure Custom Timeouts (Optional)
If an element takes longer than usual to appear, pass a custom timeout: await expect(btn).toBeDisplayed({ timeout: 5000 }).
Run and Verify
Execute your test and ensure the assertion provides clear feedback in the logs if it fails.
Common Errors & Best Practices
⚠️ Common Errors & Pitfalls
- Missing 'await' Keyword
Forgetting to
awaitthe assertion. Since WDIO assertions are asynchronous, failing to await them will cause the test to proceed before the check is complete. - Using Generic Matchers
Using
expect(await el.isDisplayed()).toBe(true)instead of the specializedawait expect(el).toBeDisplayed(). The latter includes built-in retries, while the former does not. - Over-Asserting
Adding too many assertions for every minor UI detail, which makes tests brittle and slow.
✅ Best Practices
- ✔Always use Specialized Matchers (like
toHaveText) over generic boolean checks to benefit from automatic retries. - ✔Use Sub-string Matching with
containingmatchers when exact text matches are too restrictive or dynamic. - ✔Implement Custom Error Messages to make debugging easier:
await expect(el).toBeDisplayed({ message: 'Login button was not found!' }). - ✔Leverage Negative Assertions using
.not(e.g.,await expect(el).not.toBeDisplayed()) to verify elements disappear after an action.
Frequently Asked Questions
How do I change the default timeout for assertions?
You can set the waitforTimeout in your wdio.conf.js file, or pass a specific timeout object to an individual assertion.
Can I use Jest matchers with WebdriverIO?
Yes, WebdriverIO's expect is compatible with standard Jest matchers, but it's recommended to use the expect-webdriverio versions for browser interactions.
What is the difference between toBeDisplayed and toExist?
toExist only checks if the element is in the HTML source, while toBeDisplayed also checks if it's visible on the screen (not hidden by CSS).
Example Usage
describe('WebdriverIO Assertions Demo', () => {
it('should verify page and element states', async () => {
await browser.url('https://ecommerce-playground.lambdatest.io/');
// Browser level assertion
await expect(browser).toHaveTitle('Your Store');
// Element level assertions
const searchInput = await $('#input-search');
await expect(searchInput).toBeEnabled();
await expect(searchInput).toHaveAttribute('placeholder', 'Search For Products');
// Negative assertion
const hiddenElement = await $('.hidden-msg');
await expect(hiddenElement).not.toBeDisplayed();
});
});
Conclusion
Mastering WebdriverIO assertions is key to building stable and reliable automation suites. By using asynchronous matchers with built-in retries, you can eliminate many common causes of test flakiness and ensure your tests provide accurate feedback on your application's health.
📝 Summary & Key Takeaways
This guide provided a deep dive into WebdriverIO assertions, highlighting the power of the expect-webdriverio library. We explored both browser and element-level matchers, emphasizing the importance of asynchronous execution and built-in retry logic. The tutorial outlined a structured approach to writing assertions, identified common mistakes like missing await keywords, and detailed best practices for creating resilient tests. By leveraging these specialized matchers, automation engineers can build self-healing tests that gracefully handle the dynamic nature of modern web applications.
Share it with your network and help others learn too!
Follow me on social media for more developer tips, tricks, and tutorials. Let's connect and build something great together!