npm / webdriverio
webdriverio
What changed in webdriverio 8 to 10, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-18.
28 breaking3 security33 new APIs and options2 performance15 behavior and defaults8 tooling131 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli initwebdriverio 1061 changes
Breaking changes 24
Appium 3 is required, and Appium 1/2 HTTP fallbacks have been dropped.
browser.uploadFile is replaced by element.setFiles.
$ now throws when a selector matches multiple elements.
Use element.setFiles in place of browser.uploadFile.
Element queries now return results as an ElementArray.
The executeAsync command has been removed.
The frame command queries, changing its behavior for developers working with frames.
JSONWP Appium capabilities have been dropped.
The mobile getValue fallback has been removed.
Multiremote $$ now returns a MultiRemoteElementArray.
The multiremote mock() command now returns a MultiRemoteMock.
Multiremote select() behavior is stabilized, and its environment flag has been dropped.
Multiremote naming is aligned to multi-remote / multiRemote.
The type has been renamed to MultiRemoteConfig.
MultiRemoteConfig replaces the renamed MultiremoteConfig type.
WebdriverIO now requires Node.js >=22.19.0.
React 18 and 19 are supported by react$ and react$$ using a built-in resq replacement.
Ignored legacy options for startActivity have been dropped.
switchToFrame is hidden.
The deprecated throttle command has been removed.
The deprecated touchAction command has been removed.
The url command returns a context, changing what developers receive when they use it.
Every session is now treated as W3C.
Unprefixed capability specs and exclude have been dropped.
New APIs and options 13
The snapshot and session packages are prepared for MCP integration.
Repeated controls in snapshots are tagged with their row context.
A proof-of-concept implementation of the snapshot package is introduced.
WebdriverIO now supports the Sauce Labs asia-south-2 data center.
The setup wizard now offers the devtools service, giving users another service option when creating a WebdriverIO project.
browser.act() is added with cached, self-healing steps.
browser.extract() is added with cached, self-healing steps.
Custom commands can be added to browsing contexts.
Chromedriver can be downloaded from Electron releases.
A command to install browser extensions is added.
Native headless Wayland support using weston is added.
A role/ selector is added for selecting by role and accessible name.
A command to uninstall browser extensions is added.
Performance 1
Hot-path performance improvements make test runs faster.
Behavior and default changes 5
browser.emulate() is driven by the BiDi emulation module.
WebdriverIO holds a browsing context for a tab, window, or frame.
Multiremote instances are looked up with getInstance.
Jasmine sync matchers remain synchronous.
savePDF prints PDFs using browsingContext.print.
Tooling 2
The browser channel IPC is typed, giving developers type information when working with browser-runner channels.
The session help output is self-documenting, helping developers understand the command and use it more effectively.
Fixes and other changes 16
Agents stay on the UI path and fail fast.
Custom strategies, matchers, and argument elements can be found again.
Supports expect.extend() for custom matchers in the Jasmine framework.
Adds expect.multiRemote() to the Jasmine expect.
Keeps expect-webdriverio's expect types and types expectAsync matchers.
Preserves the strict option and index in hasElementId.
Regenerated BiDi types for the script.EvaluationResult rename.
Fixes device emulation with unsupported BiDi.
BiDi execute now returns Blob and File values.
Element handling now follows the WebDriver spec for elements from other browsing contexts.
Commands are routed to their held browsing context, so they act on the intended context.
mock.waitForResponse() works with Firefox 304 responses and in every session.
In multiremote, nextElement, previousElement, and parentElement return a MultiRemoteElement.
In multiremote, custom$, react$, and shadow$ return a MultiRemoteElement.
In multiremote, custom$$, react$$, and shadow$$ return a MultiRemoteElementArray.
Multiremote $$ items now work for missing and late elements.
webdriverio 9157 changes
Breaking changes 4
Classic cookie filtering now requires all filter attributes.
Removes the mobile command wrapper.
Deprecated Appium protocol commands were renamed for Appium 3 compatibility.
Renames multiremoteBrowser to multiRemoteBrowser to follow camel-casing rules.
Security 3
Its preload script is guarded against partial-Bidi remotes.
Redacts the username accesskey from automation logs.
A fix addresses credentials leaking in logs.
New APIs and options 20
Adds support for accepting mobile permission dialogs.
Adds support for CPU and heap profiling.
Adds the Dioxus service to the project creation wizard.
Adds support for dismissing mobile permission dialogs.
Supports CHROMEDRIVER_CDNURL for custom ChromeDriver mirrors.
create-wdio adds third party service null-driver support.
Adds beta ElementArray support under a feature flag for multiRemote.$$(), including MultiRemoteElement[].
Multi-remote instance and element support is enhanced with filter.
The Allure reporter adds a title path.
Expect adds support for multi-element $$() queries.
The WebDriver Bidi response timeout is configurable.
BrowserStack service ships its accessibility Browser type augmentations.
Adds one-to-many Test-Case-ID tagging in the BrowserStack service.
create-wdio adds a Tauri service.
Adds BiDi network data support.
The option can now exclude test suites by name.
The Appium service can start Appium Inspector from the CLI.
A custom timeout can now be passed when starting Appium.
The BrowserStack service implements BrowserStack CLI support.
The Allure reporter adds mode and excluded properties for parameters.
Performance 1
Improves selector performance in the Appium service.
Behavior and default changes 9
Select moved into beta and still requires an environment flag.
The unstable Multi-remote select implementations were reviewed and the filter was removed.
Multi-remote instance and element support is enhanced with select.
WDIO CLI-flow App Automate sessions are routed to app-accessibility.
BrowserStack skips accessibility scans for BiDi window/context commands.
Allure reporter attaches suite-level before/after all hook steps to every test.
The gRPC message limit in WDIO-v9 is updated to 20 MB.
Adds the spec file name to the log file prefix.
Enhanced getContext, getContexts, and switchContext APIs.
Tooling 5
The CLI REPL now supports TypeScript files.
BrowserStack reports Mocha hooks in the CLI/testhub flow.
create-wdio migrates its Electron setup to @wdio/electron-service.
The plugin follows the ESLint v9 plugin specification.
Uses a no-floating-promise ESLint rule to catch missing await statements.
Fixes and other changes 115
Works correctly on multi-remote browsers.
Uses the BiDi accessibility locator for aria selectors.
Enables followRedirects for BiDi connections.
Accepts URLPattern as the url for browser.mock.
Honors exclusion options when retrieving HTML.
Adds undefined as a possible return type.
Resolves a mock state error and race condition.
Handles dynamic function payloads in mock responses.
Uses the correct navigation ID when waiting for network idle.
Reports a non-zero exit code for workers terminated by a signal.
Re-throws the original stale-element error when refetching fails.
Keeps a valid top-level context and can recover a destroyed context when switching to the parent frame.
Applies network throttling conditions to service workers.
Fixes EdgeDriver upgrades when the browser version is missing the corresponding driver architecture.
Restores nested and Shadow DOM scrolling in scrollIntoView.
Tracks the lifecycle of dialog listeners.
Applies keyword exclude to grouped specs.
Clears shadow roots when navigation starts.
Rejects invalid timeout values.
Retries after a failed sync.
BiDi no such node errors are handled as stale errors.
Tracks the document element separately per context.
Correctly serializes IPv6 BiDi WebSocket candidates.
Typing for expect-wdio/api was fixed.
Spec files are retried when session creation fails.
The .cts file extension is added to the supported extensions for configuration files.
Matching mock responses are now recorded even when they are not blocked.
The create-wdio setup installs @serenity-js/html-reporter instead of @senity-js/serenity-bdd.
Requests aborted by connectionRetryTimeout are now retried.
The current context is reset when its browsing context is destroyed.
Element command overrides are now composed.
The wheel action now scrolls by deltaX and deltaY.
An undefined element that passes a filter is now kept.
Driver setup now respects WEBDRIVER_CACHE_DIR.
Guards the Object.keys call when the request body is stringified.
With Cucumber Opts.scenarioLevelReporter, scenarios are reported as testcases.
BrowserStack accessibility options supplied as stringified booleans are coerced.
BrowserStack finalizes orphaned test runs when the process exits interrupted.
Scoped element lookups no longer include unrelated shadow roots.
The CDDL was updated and regenerated to correct a null literal in the protocol definitions.
In BiDi, skips the isConnected check for non-shadow element scopes.
wdio-utils now uses a supported EdgeDriver CDN.
Fixes finished metadata for reloadSession in the BrowserStack service.
waitForResponse now waits for the networkCollector's response.
The BrowserStack config.accessibility issue was addressed.
The logger is now CJS compliant, fixing compatibility for CommonJS consumers.
The BrowserStack service omits unset accessibility configuration.
The BrowserStack service and wdio-types now honor the skipped status.
Fixes an EBUSY file-busy error during spawn.
Calls the afterSession hook when session initialization fails.
Skips desktop browser download when androidPackage is set.
Fixes disableElementImplicitWait when it is defined too early.
Allure reporter historyId now uses the capability key instead of cid.
Fixes stale shadow element behavior.
Prevents a shadow root memory leak during SPA navigation.
Reverts the protocol rename of queryAppState.
Fixes service startup failures caused by Appium stderr log output.
Fixes TypeScript 7 compatibility.
Fixed mobile command argument mismatches for Appium 3 compatibility.
Updates the exit signal used for CLI process termination on Unix.
Ensures getValue returns a string.
Ignores the 'no such frame' error in handleUserPrompt.
Properly resolves pending steps and status …
Correctly detects the Cucumber framework in mult…
Improves robustness for BiDi cookies.
Fixes overlapping capabilities.
Restores the jiti fallback for CJS named imports in wdio-config.
Attaches Cucumber data tables to the step instead of the previously used location.
Fixes a Jasmine error in the Sauce service.
Passes through clean NODE_OPTIONS in the Appium service.
Allows parallel runs to download the CLI.
Allows waitForClickable in native context if the browser condition is met.
Corrects typings and inconsistencies in commands.
BiDi navigation now handles the 'no such frame' error.
Chaining element command overwrites no longer produces undefined binds.
The nested describe structure is preserved by the Jasmine and Allure integration.
Specs added dynamically in this hook are now handled correctly.
Relative XPath chaining works in BiDi mode.
Timeouts are propagated correctly during retries.
The shared-store service uses 127.0.0.1 instead of localhost.
The JUnit reporter no longer reports a skipped test when no tests are executed.
This setting can now be overridden in the beforeSession hook.
The command no longer uses double ports.
The browser runner now prioritizes this package for Tailwind CSS PostCSS handling.
Calling this.skip() in Mocha hooks is no longer reported as a failure.
Overlapping W3C capabilities are normalized.
Stuck workers are force-killed after the shutdown timeout.
Restores hook data for Jasmine 5.10 and later.
Rethrows pending and skip errors for Jasmine.
Handles a 'no such alert' error when a dialog closes.
The command no longer swaps a valid indexed element.
Action IDs are now type-specific to comply with the W3C WebDriver specification.
The BrowserStack service's BiDi syntax error is fixed.
Wildcard support in browser.mock is fixed.
File contention in the BrowserStack CLI is fixed.
Chrome workers on Windows now use a unique user-data directory.
The CLI no longer loads the config file twice and fixes tsx file timing load issues.
Framework timeouts are propagated to the shim to avoid premature behavior.
The implicit wait now handles stale elements correctly.
The Allure reporter now includes the capability ID in historyId for multi-capability runs.
isElementClickable is fixed for Perfecto mobile devices.
isElementDisplayed is fixed for Perfecto mobile devices.
The CLI check for parallel multiremote is corrected for empty capabilities.
The attach command now flattens options to the top level for waitFor commands.
Handling is fixed for multiple webviews with the same package when the first webview is empty.
Absolute paths are obtained using native path.resolve.
The launcher ignores warnings and debugger messages.
All options are passed to fetch.
Stale elements are detected in BiDi mode when using getCSSProperty.
The getHTML return type is corrected.
The withinViewport check logic is corrected.
The CLI respects maxInstancesPerCapability for dynamic capabilities.
Request mocking works when the mock is specified with a hostname only.
The JUnit reporter adds property support for Cucumber tests.
waitForExist maintains elementIds for shadow elements.
webdriverio 82 changes
Behavior and default changes 1
Enhances the gRPC client with message size limits.
Tooling 1
Adds targeted scans to the WDIO CLI V8 BrowserStack service.