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 ConfigParser Class

From Leeroopedia

Overview

Concrete tool for parsing and validating WebdriverIO configuration files provided by the @wdio/config package.

Metadata

Field Value
Page Type Implementation
Repository webdriverio/webdriverio
Package @wdio/config
Source File packages/wdio-config/src/node/ConfigParser.ts, Lines L42-563
Related Principle Principle: Test_Configuration_Parsing

Description

The ConfigParser class reads a wdio.conf.ts or wdio.conf.js configuration file, applies defaults from DEFAULT_CONFIGS(), merges CLI overrides, resolves spec file paths using glob patterns, validates the result, and provides the finalized configuration via getConfig(). It uses deepmerge-ts for merging nested objects with a custom merge strategy that deduplicates array entries for services, reporters, and capabilities.

The class follows a two-phase initialization pattern: the constructor performs synchronous setup (applying defaults and merging initial CLI config), while the asynchronous initialize() method loads the config file (which may require ESM dynamic import) and completes the merge. The getConfig() and getCapabilities() methods throw if called before initialization.

Source Reference

File Lines Description
packages/wdio-config/src/node/ConfigParser.ts L42-563 Main ConfigParser class
packages/wdio-config/src/constants.ts L7-89 DEFAULT_CONFIGS, SUPPORTED_HOOKS, SUPPORTED_FILE_EXTENSIONS
packages/wdio-config/src/node/FileSystemPathService.ts -- PathService implementation for glob resolution

Signature

class ConfigParser {
    constructor(
        configFilePath: string,
        _initialConfig?: Partial<TestrunnerOptionsWithParameters>,
        _pathService?: PathService
    )
    async initialize(object?: MergeConfig): Promise<void>
    getConfig(): Required<WebdriverIO.Config>
    getCapabilities(i?: number): Capabilities.TestrunnerCapabilities | Capabilities.RequestedStandaloneCapabilities
    getSpecs(capSpecs?: Spec[], capExclude?: Spec[]): string[]
    addService(service: Services.Hooks): void
    static getFilePaths(patterns: Spec[], rootDir: string, findAndGlob?: PathService, hierarchyDepth?: number): Spec[]
}

Import

import { ConfigParser } from '@wdio/config/node'

Inputs / Outputs Contract

Inputs

Parameter Type Required Description
configFilePath string Yes Path to the wdio.conf.ts/js configuration file
_initialConfig Partial<TestrunnerOptionsWithParameters> No CLI argument overrides (spec, suite, watch, bail, coverage, etc.)
_pathService PathService No Custom path service for glob resolution (defaults to FileSystemPathService)

Outputs

Method Return Type Description
getConfig() Required<WebdriverIO.Config> Fully-merged configuration object with all defaults applied
getCapabilities() Capabilities.TestrunnerCapabilities Merged capabilities array or multiremote object
getSpecs() string[] Resolved spec file paths filtered by exclude patterns, suite selection, and shard settings

Key Configuration Properties

The parsed configuration object includes these key properties:

Property Type Description
specs string[] Glob patterns for spec files
capabilities Capabilities.TestrunnerCapabilities Browser capability definitions
framework 'jasmine' | 'cucumber' Test framework adapter
reporters string[] Reporter plugins for output formatting
services string[] Service plugins (driver management, etc.)
baseUrl string Base URL for relative navigation commands
logLevel 'debug' | 'info' | 'warn' | 'error' | 'silent' Logging verbosity
maxInstances number Maximum concurrent worker processes
mochaOpts MochaOpts Mocha framework options (timeout, ui, etc.)
cucumberOpts CucumberOpts Cucumber framework options
shard { current: number, total: number } Shard configuration for distributed execution

Usage Example

import { ConfigParser } from '@wdio/config/node'

// Create parser with config file path and CLI overrides
const configParser = new ConfigParser('./wdio.conf.ts', {
    spec: ['./test/specs/login.ts'],
    baseUrl: 'http://staging.example.com',
    logLevel: 'debug'
})

// Initialize (loads config file asynchronously)
await configParser.initialize()

// Access the finalized configuration
const config = configParser.getConfig()
console.log(config.framework)    // 'mocha'
console.log(config.baseUrl)      // 'http://staging.example.com' (CLI override applied)
console.log(config.logLevel)     // 'debug' (CLI override applied)

// Get resolved spec file paths
const specs = configParser.getSpecs()
console.log(specs)  // ['/absolute/path/to/test/specs/login.ts']

// Get capabilities
const caps = configParser.getCapabilities()
console.log(caps)   // [{ browserName: 'chrome' }]

Programmatic usage in the Launcher

// The Launcher class creates a ConfigParser internally
// packages/wdio-cli/src/launcher.ts L59-64
class Launcher {
    public configParser: ConfigParser
    constructor(configFilePath: string, args: Partial<RunCommandArguments> = {}) {
        this.configParser = new ConfigParser(configFilePath, args)
    }
    async run(): Promise<number | undefined> {
        await this.configParser.initialize(this._args)
        const config = this.configParser.getConfig()
        // ... orchestrate test execution using config
    }
}

Internal Behavior

The merge strategy uses deepmergeCustom from deepmerge-ts with special handling for arrays:

// packages/wdio-config/src/node/ConfigParser.ts L186-195
const customDeepMerge = deepmergeCustom({
    mergeArrays: ([oldValue, newValue], utils, meta) => {
        const key = meta?.key as KeyWithMergeDuplication
        if (meta && MERGE_DUPLICATION.includes(key)) {
            // For 'services', 'reporters', 'capabilities':
            // filter non-object entries from old, merge with new, deduplicate
            const origWithoutObjectEntries = oldValue.filter(
                (value) => typeof value !== 'object'
            )
            return Array.from(new Set(deepmerge(newValue, origWithoutObjectEntries)))
        }
        return utils.actions.defaultMerge
    }
})

Spec resolution supports both flat string arrays and grouped arrays (string[][]) for parallel execution of related specs. The getSpecs() method handles suite selection (--suite), exclusion patterns (--exclude), sharding (--shard), and repetition (--repeat).

Related Pages

Page Connections

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