Skip to main content

Component Testing

With WebdriverIOs Browser Runner you can run tests within an actual desktop or mobile browser while using WebdriverIO and the WebDriver protocol to automate and interact what gets rendered on the page. This approach has many advantages compared to other test frameworks that only allow testing against JSDOM.

How does it Work?​

The Browser Runner uses Vite to render a test page and initialize a test framework to run your tests in the browser. Currently it only supports Mocha but Jasmine and Cucumber are on the roadmap. This allows to test any kind of components even for projects that don't use Vite.

The Vite server is started by the WebdriverIO testrunner and configured so that you can use all reporter and services as you used to for normal e2e tests. Furthermore initialises the runner a browser instance within the global scope that allows you to access a subset of the WebdriverIO API.

Setup​

To set-up WebdriverIO for unit or component testing in the browser, initiate a new WebdriverIO project via:

npm init wdio@latest ./
# or
yarn create wdio ./

Once the configuration wizard starts, pick browser for running unit and component testing and choose one of the presets if desired otherwise go with "Other" if you only want to run basic unit tests. You can also configure a custom Vite configuration if you use Vite already in your project. For more information check out all runner options.

info

Note: WebdriverIO by default will run browser tests in CI headlessly, e.g. a CI environment variable is set to '1' or 'true'. You can manually configure this behavior using the headless option for the runner.

At the end of this process you should find a wdio.conf.js that contains various WebdriverIO configurations, including a runner property, e.g.:

// wdio.conf.js
export const config = {
// ...
runner: ['browser', {
// runner options
preset: 'svelte' // setup WebdriverIOs Vite server for a Svelte project
// define code coverage options, see more https://webdriver.io/docs/runner#coverage-options
coverage: {
enabled: true,
statements: 90,
branches: 90,
functions: 90,
lines: 90
}
}]
}

By defining different capabilities you can run your tests in different browser, in parallel if desired.

Test Harness​

It is totally up to you what you want to run in your tests and how you like to render the components. However we recommend to use the Testing Library as utility framework as it provides plugins for various of component frameworks, such as React, Preact, Svelte and Vue. It is very useful for rendering components into the test page and it automatically cleans up these components after every test.

You can mix Testing Library primitives with WebdriverIO commands as you wish, e.g.:

import { expect, $ } from '@wdio/globals'
import * as matchers from '@testing-library/jest-dom/matchers'
expect.extend(matchers)

import { render, fireEvent, screen } from '@testing-library/svelte'
import '@testing-library/jest-dom'

// see implementation here: examples/wdio/browser-runner/components/Component.svelte
import Component from './components/Component.svelte'

describe('Svelte Component Testing', () => {
it('shows proper heading when rendered using Testing Library primitives', () => {
render(Component, { name: 'World' })
const heading = screen.getByText('Hello World!')
expect(heading).toBeInTheDocument()
})

it('changes button text on click', async () => {
render(Component, { name: 'World' })
const button = await $('button')
await button.click()
await expect(button).toHaveText('Button Clicked')
})
})

Note: using render methods from Testing Library helps remove created components between the tests. If you don't use Testing Library ensure to attach your test components to a container that gets cleaned up between tests.

Watch Test and Application Files​

There are multiple ways how you can debug your browser tests. The easiest is to start the WebdriverIO testrunner with the --watch flag, e.g.:

$ npx wdio run ./wdio.conf.js --watch

This will run through all tests initially and halt once all are run. You can then make changes to individual files which then will be rerun individually. If you set a filesToWatch pointing to your application files, it will re-run all tests when changes to your app are being made.

Debugging​

While it is not (yet) possible to set breakpoints in your IDE and have them being recognised by the remote browser, you can use the debug command to stop the test at any point. This allows you to open DevTools to then debug the test by setting breakpoints in the sources tab.

When the debug command is called, you will also get a Node.js repl interface in your terminal, saying:

The execution has stopped!
You can now go into the browser or use the command line as REPL
(To exit, press ^C again or type .exit)

Press Ctrl or Command + c or enter .exit to continue with the test.

Examples​

You can find various examples for testing components using popular component frameworks in our example repository.