Implementation:Webdriverio Webdriverio ConfigParser Class
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).