Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Webdriverio Webdriverio Browser Runner Render

From Leeroopedia

Metadata

Field Value
Page ID Browser_Runner_Render
Wiki Webdriverio_Webdriverio
Type Implementation (Wrapper Doc)
Domains Testing, Component_Testing, Frontend
Knowledge Sources Repo (https://github.com/webdriverio/webdriverio), Doc (https://webdriver.io/docs/component-testing)
Related Principles Principle: Component_Test_Rendering

Overview

Wrapper documentation for component rendering in WebdriverIO browser runner tests using framework testing libraries. When using the WDIO browser runner, components are rendered using framework-specific testing libraries (e.g., @testing-library/vue for Vue, @testing-library/react for React). The render() function mounts a component into the browser DOM. After rendering, $() and $$() query the component's DOM, and expect() validates output. The browser runner includes mock/spy support via @vitest/spy.

Description

The browser runner render flow involves three stages:

  1. Rendering -- The framework-specific render() function mounts a component into the real browser DOM with specified props and slots.
  2. Querying -- Testing Library query utilities (getByText, getByRole, etc.) or WebdriverIO selectors ($(), $$()) locate elements in the rendered output.
  3. Asserting -- WebdriverIO's expect() function with expect-webdriverio matchers validates the component's output and behavior.

The browser runner's expect system is implemented in packages/wdio-browser-runner/src/browser/expect.ts, which creates matcher factories that serialize assertions and send them to the Node.js worker process for evaluation. The mocking system in packages/wdio-browser-runner/src/browser/spy.ts re-exports @vitest/spy and provides mock(), unmock(), and mocked() functions.

Source

File Lines Description
examples/wdio/vite-vue-example/src/components/HelloWorld.test.ts L1-27 Full Vue component test example
packages/wdio-browser-runner/src/browser/expect.ts L1-50+ Browser-side expect matcher factory
packages/wdio-browser-runner/src/browser/spy.ts L1-55 Mock/spy module (re-exports @vitest/spy, provides mock/unmock)
examples/wdio/vite-vue-example/src/components/HelloWorld.vue L1-38 Vue component under test

APIs

render(Component, options?)

Mounts a UI component into the browser DOM. Provided by the framework-specific testing library.

For Vue:

import { render } from '@testing-library/vue'
import Component from './MyComponent.vue'

const { getByText, getByRole, container } = render(Component, {
    props: { msg: 'Hello' },
    slots: { default: '<span>slot content</span>' }
})

I/O Contract:

Parameter Type Description
Component Framework component The component to render
options.props Object (optional) Props to pass to the component
options.slots Object (optional) Slot content (Vue-specific)
Returns RenderResult Object with query utilities: getByText, getByRole, container, etc.

$('selector') / $$('selector')

WebdriverIO global selectors for querying the rendered DOM. Can also wrap DOM elements returned by Testing Library queries.

// Query by CSS selector
const button = await $('button.submit')

// Wrap a Testing Library query result
const { getByText } = render(Component)
const element = await $(getByText('Click me'))

I/O Contract:

Parameter Type Description
selector string or HTMLElement CSS selector string or DOM element
Returns ChainablePromiseElement WebdriverIO element wrapper with full command API

expect(element).matcher()

Assertion function using expect-webdriverio matchers. The browser runner's expect implementation serializes matcher calls and evaluates them in the Node.js worker process.

await expect(button).toHaveText('count is 2')
await expect($('.message')).toBeDisplayed()
await expect($('input')).toHaveValue('test')

mock(path, factory?) / unmock(moduleName)

Module mocking functions provided by the browser runner's spy module.

import { fn, spyOn } from '@wdio/browser-runner'

// Mock a module with a factory
mock('./api.js', () => ({
    fetchData: fn().mockResolvedValue({ items: [] })
}))

// Remove a mock
unmock('./api.js')

I/O Contract:

Function Parameters Description
mock(path, factory?) path: string, factory: function (optional) Replaces module imports with factory return value
unmock(moduleName) moduleName: string Removes a previously registered mock
mocked(item) item: T Type utility for casting to MaybeMocked<T>
fn() None Creates a mock function (from @vitest/spy)
spyOn(obj, method) obj: object, method: string Creates a spy on an object method (from @vitest/spy)

Full Example: Vue Component Test

Component under test (HelloWorld.vue):

<script setup lang="ts">
import { ref } from 'vue'

defineProps<{ msg: string }>()

const count = ref(0)
</script>

<template>
  <h1>{{ msg }}</h1>
  <div class="card">
    <button type="button" @click="count++">count is {{ count }}</button>
  </div>
</template>

Test file (HelloWorld.test.ts):

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

import * as matchers from '@testing-library/jest-dom/matchers'
expect.extend(matchers as any)

import Component from './HelloWorld.vue'

describe('Vue Component Tests', () => {
    it('should do something cool', async () => {
        // The render method returns a collection of utilities to query your component.
        const { getByText } = render(Component)

        // getByText returns the first matching node for the provided text, and
        // throws an error if no elements match or if more than one match is found.
        getByText('count is 0')

        const button = await $(getByText('count is 0'))

        // Dispatch a native click event to our button element.
        await button.click()
        await button.click()

        getByText('count is 2')
        await expect(button).toHaveText('count is 2')
    })
})

Test flow:

  1. Import render from @testing-library/vue and the component.
  2. Call render(Component) to mount the component in the real browser DOM.
  3. Use getByText('count is 0') to verify initial render text.
  4. Wrap the DOM element with $(getByText(...)) to get a WebdriverIO element.
  5. Call .click() twice to simulate user interaction.
  6. Assert the button text changed to 'count is 2' using toHaveText().

Import Summary

// WebdriverIO globals (available in browser runner context)
import { expect, $ } from '@wdio/globals'

// Framework-specific render function
import { render } from '@testing-library/vue'    // Vue
import { render } from '@testing-library/react'   // React
import { render } from '@testing-library/svelte'   // Svelte

// Mocking (from browser runner)
import { fn, spyOn, mock, unmock } from '@wdio/browser-runner'

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment