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 Given When Then Functions

From Leeroopedia

Metadata

Field Value
Page ID Given_When_Then_Functions
Page Type Implementation
Implementation Type Wrapper Doc
Repository webdriverio/webdriverio
Package @wdio/cucumber-framework (re-exports from @cucumber/cucumber)
Source packages/wdio-cucumber-framework/src/index.ts (L584: re-export), examples/wdio/cucumber/step-definitions.ts (L12-42), packages/wdio-cucumber-framework/src/index.ts (L443-521: wrapSteps/wrapStep)
External Reference Cucumber Step Definitions Documentation
Related Pages implements Principle:Webdriverio_Webdriverio_Step_Definition_Binding

Overview

Wrapper documentation for Cucumber step definition functions re-exported through the @wdio/cucumber-framework package.

Description

The Given(), When(), and Then() functions are re-exported from @cucumber/cucumber via the @wdio/cucumber-framework package. The adapter's wrapStep() method integrates each step with WDIO's beforeHook/afterHook lifecycle. Within step functions, the browser, $, $$, and expect globals are available for browser automation.

The re-export is a wildcard re-export at the bottom of the adapter's entry file:

// packages/wdio-cucumber-framework/src/index.ts (L584)
export * from '@cucumber/cucumber'

This makes all Cucumber exports (including Given, When, Then, Before, After, BeforeAll, AfterAll, BeforeStep, AfterStep, setDefaultTimeout, World, etc.) available when importing from @wdio/cucumber-framework.

Signatures

Given(pattern: string | RegExp, fn: (...args: any[]) => Promise<void> | void): void
When(pattern: string | RegExp, fn: (...args: any[]) => Promise<void> | void): void
Then(pattern: string | RegExp, fn: (...args: any[]) => Promise<void> | void): void

All three functions have identical signatures. The keyword distinction (Given/When/Then) is semantic only and exists for readability in step definition files. Cucumber treats them identically at the matching level -- a step defined with Given can match a When step in a feature file.

Import

import { Given, When, Then } from '@wdio/cucumber-framework'

Inputs

Parameter Type Description
pattern RegExp Pattern to match against step text. Strings use Cucumber Expression syntax (e.g., '{string}', '{int}'). RegExp uses JavaScript regex with capture groups.
fn void Async step function. Arguments are the captured groups from the pattern match. For data table steps, a DataTable object is appended as the last argument. WDIO globals (browser, $, $$, expect) are available in scope.

Outputs

  • Registered step definitions bound to the Cucumber runtime via supportCodeLibraryBuilder.
  • At runtime, each step function is wrapped with WDIO hooks via setDefinitionFunctionWrapper().
  • Step execution results are emitted to WDIO reporters through the CucumberFormatter.

Step Wrapping Mechanism

The adapter's wrapSteps() method uses setDefinitionFunctionWrapper() to intercept all step definitions:

// packages/wdio-cucumber-framework/src/index.ts (L443-481)
wrapSteps(config: WebdriverIO.Config) {
    const wrapStep = this.wrapStep
    const cid = this._cid

    let params: unknown
    this._eventEmitter.on('getHookParams', (payload) => {
        params = payload
    })
    const getHookParams = () => params

    setDefinitionFunctionWrapper(
        (fn: Function, options: StepDefinitionOptions = { retry: 0 }) => {
            // hooks defined in wdio.conf are already wrapped
            if (fn.name.startsWith('wdioHook')) {
                return fn
            }
            const isStep = !fn.name.startsWith('userHook')
            // Steps without retry options are returned as-is for performance
            if (isStep && !options.retry) {
                return fn
            }
            return wrapStep(fn, isStep, config, cid, options,
                getHookParams, this._cucumberOpts.timeout)
        }
    )
}

The wrapStep() method wraps the step function with testFnWrapper from @wdio/utils, which handles:

  • Invoking config.beforeHook before step execution
  • Invoking config.afterHook after step execution
  • Retry logic based on options.retry

Usage Example

From examples/wdio/cucumber/step-definitions.ts:

import { Given, When, Then } from '@wdio/cucumber-framework'
import { Key } from 'webdriverio'

Given(/^I go on the website "([^"]*)"$/, async (url) => {
    await browser.url(url)
})

When(/^I add the following groceries$/, async (table) => {
    const newTodo = await $('.new-todo')
    table.rawTable.shift()

    for (const [item, amount] of table.rawTable) {
        await newTodo.addValue(`${item} (${amount}x)`)
        await browser.keys(Key.Enter)
        await browser.pause(100) // for demo purposes
    }
})

Then(/^should the element "([^"]*)" be (\d+(?:\.\d+)?)px wide and (\d+(?:\.\d+)?)px high$/, async (selector, width, height) => {
    const elemSize = await $(selector).getSize()
    expect(elemSize.width).toBe(Number(width))
    expect(elemSize.height).toBe(Number(height))
})

Then(/^should the title of the page be "([^"]*)"$/, async (expectedTitle) => {
    await expect(browser).toHaveTitle(expectedTitle)
})

Then(/^I should have a list of (\d+) items$/, async (items) => {
    await expect($$('.todo-list li')).toBeElementsArrayOfSize(items)
})

String Pattern (Cucumber Expression) Example

import { Given, Then } from '@wdio/cucumber-framework'

Given('I have {int} items in my cart', async (count) => {
    // count is automatically parsed as a number
    await expect($$('.cart-item')).toBeElementsArrayOfSize(count)
})

Then('the page title should be {string}', async (title) => {
    await expect(browser).toHaveTitle(title)
})

Related Pages

Page Connections

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