Skip to main content

Introducing DOM and Visual Snapshot Testing for Component, End-to-End and Mobile Testing

· 6 min read

We're excited to announce support for DOM and Visual snapshot tests using a common set of primitives supporting all testing environments WebdriverIO offers. Our vision has always been to provide a comprehensive, versatile testing tool that simplifies your workflow. This update is a step towards creating a 'Swiss Army Knife' for unit and visual testing, catering to diverse requirements across platforms and extending our support to native mobile applications, making your testing process more efficient and seamless.

Both, DOM and Visual Snapshot primitives will be available for you when running component and unit tests, end-to-end tests as well as mobile web tests. In addition to that the same visual snapshot primitives will be also available for native mobile application tests.

If you are more of a visual learner, we've also released a WebdriverIO tutorial on our YouTube channel:

Let's dive into each of these powerful capabilities.

DOM or Object Snapshots

For evaluating the state of the DOM, a large object or the content of a UI element we often tend to copy the value into our test and manually update it if we change the behavior of our application or component.

With text-based snapshots, we can just have this handled by WebdriverIO. For example, let's say we want to verify the state of our React component in a browser, we can just do the following:

import { expect, $ } from '@wdio/globals'
import { render } from '@testing-library/react'

function App() {
const [theme, setTheme] = useState('light')

const toggleTheme = () => {
const nextTheme = theme === 'light' ? 'dark' : 'light'

return <button onClick={toggleTheme}>
Current theme: {theme}

describe('React Component Testing', () => {
it('supports snapshot tests', async () => {
const { container } = render(<App />)
await expect(container).toMatchSnapshot()
await $('button').click()
await expect(container).toMatchSnapshot()

WebdriverIO will automatically grab the DOM structure of the component and store a snapshot file called component.test.tsx.snap in /src/__snapshots__ directory next to your test with the following content:

// Snapshot v1

exports[`React Component Testing > supports snapshot tests 1`] = `"<div><button>Current theme: light</button></div>"`;

exports[`React Component Testing > supports snapshot tests 2`] = `"<div><button>Current theme: dark</button></div>"`;

If you prefer to keep the snapshots as part of your tests you can use toMatchInlineSnapshot instead:

await expect(container).toMatchInlineSnapshot()

After running the test for the first time, WebdriverIO will make a change to the test and fill in the snapshot inline:

await expect(container).toMatchInlineSnapshot(`"<div><button>Current theme: light</button></div>"`)

Now, if you make changes to your component that will impact all snapshots you can update them all in a single run by calling:

npx wdio run wdio.conf.ts --updateSnapshots
# or
npx wdio run wdio.conf.ts -s

This makes maintaining your tests so much easier. The same works for all other types of objects, e.g. CSS Properties, or the text content of an element. They all can be converted into a snapshot to simplify the assertion and keep your tests lean. This can also speed up your tests by merging many single assertions into one, e.g.:

const elem = $('#alertBar')
await expect(elem).toHaveAttribute('data-alert')
await expect(elem).toHaveClassName('success')
await expect(elem).toHaveText('You logged into a secure area!')

now becomes a single:

await expect($('#alertBar')).toMatchSnapshot()
* stores the following into a snapshot file:
* <div data-alert="" id="flash" class="flash success">
* You logged into a secure area!
* <a href="#" class="close">×</a>
* </div>

While taking a snapshot of the DOM might be the most prominent use case, you can take snapshots of all types of serializable data structures, e.g.:

// the visible content of an element
await expect($('elem').getText()).toMatchSnapshot()
// or of an serializable object
await expect($('elem').getCSSProperty('color')).toMatchSnapshot()

You can find more information about DOM and object-based snapshots in our Snapshot guide.

Visual Snapshots

While taking snapshots of an element structure and its attributes might be great and powerful, it comes with an important caveat: even though we are testing that the element has a class name called success, this doesn't guarantee that the alert is green!

For these reasons, visual testing has become a very popular tool as it includes how elements are rendered, in which color and can ensure that e.g. it is not overlaid by any other element. Taking visual snapshots works very similarly, as you can:

  • take a visual snapshot of the whole screen:
    await expect(browser).toMatchScreenSnapshot('partialPage')
  • take a visual snapshot of an element:
    await expect($('#element-id')).toMatchElementSnapshot('firstButtonElement')
  • take a snapshot of the whole page:
    await expect(browser).toMatchFullPageSnapshot('fullPage')
  • or take a page snapshot that includes page tab-ability:
    await expect(browser).toMatchTabbablePageSnapshot('check-tabbable')

WebdriverIO will store these visual snapshots conveniently next to your text-based snapshots within the __snapshots__ directory next to your test.

While text-based snapshot testing is built into WebdriverIO, you have to install a service to enable all visual snapshot capabilities via:

npm i --save-dev @wdio/visual-service

With the most recent release of the Visual Testing Module with have shipped further improvements for Mobile Native App Snapshot Testing.

Mobile Native App Snapshot Testing

The module now supports the toMatchElementSnapshot and toMatchScreenSnapshot matchers for Mobile native apps. It automatically detects the testing context (web, webview, or native_app) to streamline your workflow.

Key Features of the Visual Service

Some of the features that make visual testing with WebdriverIO unique are:

  • save or compare screens/elements/full-page screens against a baseline
  • automatically create a baseline when no baseline is there
  • block out custom regions and even automatically exclude a status and or toolbars (mobile only) during a comparison
  • increase the element dimensions screenshots
  • hide text during website comparison to:
    • improve stability and prevent font rendering flakiness
    • only focus on the layout of a website
  • use different comparison methods and a set of additional matchers for better readable tests
  • verify how your website will support tabbing with your keyboard, see also Tabbing through a website
  • and much more, see the service and method options

Learn everything about WebdriverIO's visual testing capabilities in our Visual docs and join our 👁️-visual-testing channel on Discord.

Special Thanks to @wswebcreation

We owe a big thank you to our core maintainer Wim Selles for his work in wdio-native-app-compare, which inspired this enhancement. His contribution has been vital in advancing our module's capabilities.

Thank you for your continued support, and we look forward to your feedback on these new features.

Happy testing!

The WebdriverIO Team

A New Contributor Stipend Program for WebdriverIO

· 5 min read

The WebdriverIO community is on the verge of an exciting new era, supported by strategic partnerships with BrowserStack and Sauce Labs, along with continuous support from other sponsors like LambdaTest. This collective endeavor signifies a crucial milestone for the WebdriverIO project, as we utilize these additional resources to foster the growth and enrichment of our ecosystem.

Towards a Sustainable Open Source Model

WebdriverIO's story began with its inception into the JS Foundation in 2017, which later evolved into the OpenJS Foundation. Since then, it has thrived as an open-governed, community-driven endeavor, witnessing continuous growth in NPM downloads, the introduction of innovative plugins and reporters, and the rollout of new functionalities. This expansion is a testament to the hard work and dedication of the global testing community, including project users and contributors from leading testing cloud providers.

WebdriverIO's core principle is its dedication to open governance, an aspect that has attracted the trust and confidence of its users, especially those in the enterprise world. The project's growth has been organic, independent of Venture Capital, corporate objectives and sales requirements, guaranteeing that its development aligns with the true needs of our user community and all features remain free of charge.

With the project's continuous expansion, marked by increasing NPM downloads, new functionalities, plugins, and reporters, the importance of nurturing a healthy and sustainable growth path has never been more critical. Our recent alliances with top cloud services for automated testing demonstrate our dedication to responsibly managing these resources, with the aim to widen our network of contributors and enrich the entire ecosystem.

Introducing the Stipend Program

Central to our ethos is the belief that financial support of the WebdriverIO ecosystem is a worthy endeavor. Whether it's the occasional contributions from casual participants or the continuous dedication of our core team members, every contribution is a building block of our project's success. Currently, the project benefits from a monthly donation inflow of $3,879, sourced through various channels like Tidelift,, GitHub Sponsors, and our Open Collective. These funds have empowered the Technical Steering Committee to finalize new governance policies, outlining our strategic approach to fund allocation.

Our monthly budget is allocated across four key areas:

  • Project Development receives the largest share, with 60% of the funds dedicated to fostering growth and innovation.
  • Travel and Event Expenses account for 20%, supporting our participation in and hosting of industry events and meetups.
  • Support Systems are allocated 10% of the budget, ensuring our infrastructure and community support mechanisms remain robust.
  • Lastly, Dependencies, crucial external projects and tools we rely on, also receive 10% of our financial resources.

Dedication to Project Development

Our financial strategy gives top priority to project development, dedicating 60% of our resources to it. This funding aims to draw contributions from a wide range of people, increasing our base of dedicated contributors. By dividing the funds, allocating 35% to individuals not directly involved with the project and 65% to our project contributors and the Technical Steering Committee (TSC) members, we seek to foster a strong sense of community and shared ownership. This approach is vital for ensuring the long-term prosperity and stability of our project.

As part of this strategy, we have developed an automated expense process using a GitHub Action to help run this program. You can read more about how this process works on my personal blog.

Supporting Community Engagement and Events

Recognizing the importance of community engagement, especially in the aftermath of Covid-19, we are allocating funds towards travel and event expenses. This decision emphasizes our commitment to creating user meetups and supporting the broader community in hosting WebdriverIO-related events. It reflects our desire to not only maintain but also to strengthen the community ties that form the backbone of our project.

Enhancing Support Systems

A small fraction of our monthly budget is allocated to various essentials that support our project's community growth and upkeep. Our intention is to invest in translating our documentation and financially support those who contribute to this effort. Additionally, we aim to cover ongoing costs for infrastructure needed to host project-related materials, as well as provide our maintainers with the software tools necessary to enhance their contributions to the project.

Acknowledging Dependencies

Finally, we're committed to giving back to the projects and communities that are crucial to WebdriverIO's success. We believe it's vital for open-source projects benefiting from generous donations to support their key dependencies. Thanks to, we can identify and financially support our most critical dependencies based on their significance to our project and the funds we allocate monthly for this purpose. Noteworthy dependencies include:

  • Individual open-source champions like Sindre Sorhus and isaacs, whose contributions to various dependencies are invaluable.
  • The Vite ecosystem: we use Vitest across almost all our projects, and we couldn't provide such powerful component testing capabilities without Vite under the hood
  • The Eslint project and its related ecosystem projects are fundamental to maintaining a high code quality of our projects and have significantly inspired our contributor stipend program.

Looking Ahead

As we embrace this new chapter, we're excited about the prospects of accelerating growth through strategic investments in our community and project. The early feedback from our initiatives has been overwhelmingly positive, and we are committed to refining our processes for even greater efficiency and transparency.

Twitter Excitement

We extend our heartfelt gratitude to our sponsors for their invaluable support, and we warmly welcome further sponsorship to join us in this journey. Together, we are setting the stage for an even brighter future for WebdriverIO and its thriving ecosystem.

Sauce Labs joins WebdriverIOs Partnership Program as Premium Sponsor

· 2 min read

We are thrilled to announce an exciting development in our journey towards innovation in software testing and quality assurance. Sauce Labs, a pioneering force in the continuous testing arena, is joining forces with us through our Partnership Program. This collaboration marks a significant milestone in our quest to expand our development fund, enabling us to enhance our work on major releases and introduce groundbreaking features yet to be unveiled.

Sauce Labs has earned a reputation as a leader in providing solutions that empower organizations worldwide to achieve excellence in software delivery. Their platform, trusted by thousands of development teams, ensures that digital products function seamlessly across every browser, operating system, and device. This commitment to quality guarantees a flawless user experience, showcasing Sauce Labs' dedication to software excellence.

The company has been technically sponsoring the project almost since day one. My early work on WebdriverIO has opened an opportunity to work at Sauce Labs and during my 7-year tenure there, I was allowed and encouraged to work on this framework. Even some of Sauce Labs products have been heavily inspired by the work in WebdriverIO, e.g. their performance testing and extended debugging capabilities.

It makes me personally very happy to see Sauce Labs staying invested in the Open-Source testing ecosystem. Being the originators of Selenium and creators of Appium Sauce Labs remains a strong supporter of open-governed tools like WebdriverIO.

Thank you 🙏

Welcome! How can I help?

WebdriverIO AI Copilot