Problem
toBeDisplayed() does not respect WebdriverIO's global waitForTimeout or waitForInterval settings. When a test configures a custom timeout via wdio.conf.js or browser.overrideTimeout(), the matcher still uses hardcoded defaults, causing tests to either fail prematurely or hang when elements load slowly on CI/CD pipelines.
This was reported in #2020 but remains unresolved.
Why this matters
- Tests fail inconsistently across environments (local vs CI) due to different network latency
- Users must work around this by wrapping assertions in
browser.pause(ms), which is fragile and masks timing issues
- The matcher violates the principle that
expect-webdriverio should behave consistently with WebdriverIO's configuration
- Other matchers like
toBeEnabled() and toHaveText() likely have the same issue
Current behavior
// wdio.conf.js sets 15s timeout for slow CI
export const config = {
waitForTimeout: 15000,
waitForInterval: 500
}
// Test still fails at ~3s because toBeDisplayed() ignores config
await expect($('button')).toBeDisplayed()
// Actual: timeout after 3s (hardcoded default)
// Expected: timeout after 15s (from config)
What good looks like
toBeDisplayed() should read the timeout from:
- Method options parameter (highest priority):
await expect($el).toBeDisplayed({ timeout: 20000 })
- Browser configuration (fallback):
browser.config.waitForTimeout
- Hardcoded default (final fallback): 3000ms
The implementation should pass timeout and interval through to WebdriverIO's internal wait mechanism instead of hardcoding values.
Implementation path
The fix likely requires:
- Modifying matcher setup in
src/matchers/ to extract browser.config.waitForTimeout and browser.config.waitForInterval
- Updating wait logic to accept timeout/interval as parameters instead of constants
- Ensuring all element matchers (
toBeDisplayed, toBeEnabled, toBeClickable, etc.) apply the same logic
- Adding integration test that verifies timeout behavior with different
wdio.conf.js configurations
Related
Contributed by Klement Gunndu
Problem
toBeDisplayed()does not respect WebdriverIO's globalwaitForTimeoutorwaitForIntervalsettings. When a test configures a custom timeout viawdio.conf.jsorbrowser.overrideTimeout(), the matcher still uses hardcoded defaults, causing tests to either fail prematurely or hang when elements load slowly on CI/CD pipelines.This was reported in #2020 but remains unresolved.
Why this matters
browser.pause(ms), which is fragile and masks timing issuesexpect-webdriverioshould behave consistently with WebdriverIO's configurationtoBeEnabled()andtoHaveText()likely have the same issueCurrent behavior
What good looks like
toBeDisplayed()should read the timeout from:await expect($el).toBeDisplayed({ timeout: 20000 })browser.config.waitForTimeoutThe implementation should pass
timeoutandintervalthrough to WebdriverIO's internal wait mechanism instead of hardcoding values.Implementation path
The fix likely requires:
src/matchers/to extractbrowser.config.waitForTimeoutandbrowser.config.waitForIntervaltoBeDisplayed,toBeEnabled,toBeClickable, etc.) apply the same logicwdio.conf.jsconfigurationsRelated
Contributed by Klement Gunndu