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 TestFnWrapper

From Leeroopedia
Knowledge Sources
Domains Test_Framework_Integration, Hook_Management
Last Updated 2026-02-12 00:00 GMT

Overview

Wraps test framework spec and hook functions with WebdriverIO before/after lifecycle hooks, providing error handling, retry support, and stack trace filtering.

Description

The TestFnWrapper module provides two wrapper functions that form the core of WebdriverIO's test lifecycle integration. testFnWrapper is a convenience entry point that calls testFrameworkFnWrapper with the standard executeHooksWithArgs and executeAsync implementations. testFrameworkFnWrapper orchestrates the full lifecycle: it first runs the beforeFn hooks (beforeTest or beforeHook) with arguments generated by beforeFnArgs, then executes the spec/hook function via executeAsync (which provides timeout and retry support), catches and processes errors (handling Mocha sync skip and Jasmine pending signals specially), measures execution duration, augments the after-hook arguments with { retries, error, result, duration, passed, skipped }, runs the afterFn hooks (afterTest or afterHook), and either throws the error or returns the result. The filterStackTrace function removes internal WebdriverIO/webdriver/node frame lines from stack traces and strips Vite cache invalidation query parameters for cleaner error output. Special handling exists for Jasmine's dynamic result error list (_wdioDynamicJasmineResultErrorList) to properly surface assertion errors.

Usage

Use testFnWrapper from the test interface wrapper when instrumenting Mocha and Jasmine test and hook functions. Use testFrameworkFnWrapper directly when building custom framework adapters that need to inject their own implementations of executeHooksWithArgs and executeAsync. The Cucumber adapter calls testFnWrapper directly rather than going through the test interface wrapper.

Code Reference

Source Location

Signature

export const testFnWrapper: (
    this: unknown,
    type: string,
    spec: SpecFunction,
    before: BeforeHookParam<unknown>,
    after: AfterHookParam<unknown>,
    cid: string,
    repeatTest?: number,
    hookName?: string,
    timeout?: number
) => Promise<any>

export const testFrameworkFnWrapper: (
    this: unknown,
    wrapFunctions: { executeHooksWithArgs: WrapperMethods['executeHooksWithArgs']; executeAsync: WrapperMethods['executeAsync'] },
    type: string,
    spec: { specFn: Function; specFnArgs: unknown[] },
    before: { beforeFn: Function | Function[]; beforeFnArgs: (ctx: unknown) => unknown[] },
    after: { afterFn: Function | Function[]; afterFnArgs: (ctx: unknown) => unknown[] },
    cid: string,
    repeatTest?: number,
    hookName?: string,
    timeout?: number
) => Promise<any>

export const filterStackTrace: (stack: string) => string

Import

import { testFnWrapper, testFrameworkFnWrapper } from '@wdio/utils'

I/O Contract

Inputs

Name Type Required Description
type string Yes Either "Test", "Step", or "Hook" - determines which before/after hook names are used (e.g., "beforeTest"/"afterTest").
spec SpecFunction Yes Object containing specFn (the actual test/hook function) and specFnArgs (arguments to pass to it).
before BeforeHookParam<unknown> Yes Object containing beforeFn (hook function(s) to run before) and beforeFnArgs (function returning arguments for the before hook).
after AfterHookParam<unknown> Yes Object containing afterFn (hook function(s) to run after) and afterFnArgs (function returning arguments for the after hook; result metadata is appended).
cid string Yes Capability ID for the current worker, used in error logging.
repeatTest number No Number of retries for the spec function. Defaults to 0.
hookName string No Name of the hook (e.g., "beforeEach") appended to before/after hook arguments when type is "Hook".
timeout number No Maximum execution time in milliseconds, passed through to executeAsync.
wrapFunctions WrapperMethods Yes (testFrameworkFnWrapper) Object with executeHooksWithArgs and executeAsync implementations to use.

Outputs

Name Type Description
result Promise<any> The return value of the spec function after successful execution, or throws the error if the spec function failed after all retries.
after hook args (appended) object The after hook receives an additional argument: { retries: { attempts, limit }, error, result, duration, passed, skipped }.
filterStackTrace result string Cleaned stack trace with internal WebdriverIO frames removed.

Usage Examples

import { testFnWrapper, testFrameworkFnWrapper, filterStackTrace } from '@wdio/utils'

// Using testFnWrapper in a framework adapter (called by testInterfaceWrapper)
const result = await testFnWrapper.call(
    testContext,
    'Test',
    {
        specFn: async () => {
            await browser.url('https://example.com')
            expect(await browser.getTitle()).toBe('Example')
        },
        specFnArgs: []
    },
    {
        beforeFn: config.beforeTest,
        beforeFnArgs: (ctx) => [ctx.test, ctx]
    },
    {
        afterFn: config.afterTest,
        afterFnArgs: (ctx) => [ctx.test, ctx]
    },
    '0-0',     // cid
    2,         // retries
    undefined, // hookName (not a hook)
    30000      // timeout
)

// Using filterStackTrace to clean error output
try {
    await someFailingTest()
} catch (err) {
    err.stack = filterStackTrace(err.stack)
    console.error(err.stack)
    // Internal node_modules/@wdio/ lines are removed
}

Related Pages

Page Connections

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