Skip to content

fix(appium): rename deprecated Appium protocol commands for Appium 3 compatibility#15141

Merged
wswebcreation merged 14 commits intomainfrom
fix/15124-appium3-deprecated-endpoints
Mar 15, 2026
Merged

fix(appium): rename deprecated Appium protocol commands for Appium 3 compatibility#15141
wswebcreation merged 14 commits intomainfrom
fix/15124-appium3-deprecated-endpoints

Conversation

@wswebcreation
Copy link
Copy Markdown
Member

@wswebcreation wswebcreation commented Mar 8, 2026

Important

After merge and release we should also release the docs

Related issue

Closes #15124

Summary

Appium 3 removed ~90 JSONWP-era endpoints from base-driver. This PR contains multiple steps/fixes to make WebdriverIO compatible with Appium 3 while keeping backward compatibility with Appium 2 users on older drivers.

Research

Most of the research is in #15124. Here's a summary

Backward Compatibility & mobile: Command Availability

After further research into the driver changelogs, a clearer picture emerged on how to handle backward compatibility with Appium 2.

When were the mobile: replacements introduced?

For UIAutomator2 (Android), all relevant mobile: replacement commands (mobile: lock, mobile: unlock, mobile: isLocked, mobile: getCurrentPackage, mobile: getCurrentActivity, mobile: pressKey, mobile: gsmCall, mobile: getPerformanceData, mobile: getSystemBars, mobile: openNotifications, etc.) were available before January 2024 — added progressively in UIAutomator2 v2.17–v2.24 (April–May 2023).

For XCUITest (iOS), the same applies for most commands. The one exception is mobile: startXCTestScreenRecording / mobile: stopXCTestScreenRecording, which landed in XCUITest v7.3.0 (March 2024).

What this means

There are three user groups

Group What works Risk
Appium 2 + drivers from 2023 or earlier Old endpoint only Calling mobile: would fail
Appium 2 + drivers from 2024+ Old endpoint and mobile: None, both paths work
Appium 3 + drivers from 2024+ mobile: only Old endpoint still works via driver grace period, but shows deprecation warning

The group that would break if WDIO switched unconditionally to mobile: is Appium 2 users on drivers from 2023 or earlier. This is a small and shrinking group, but worth protecting.

Chosen approach: try/catch with specific error handling

WDIO will attempt the mobile: execute path first. If the driver responds with an "unknown command" error (meaning the driver is too old to support it), WDIO falls back to the old endpoint and logs a clear deprecation warning. Any other error (device disconnected, wrong parameters, etc.) is re-thrown immediately and not swallowed by the catch.

This means:

  • Appium 3 + 2024+ drivers: mobile: succeeds, no warning, no double call
  • Appium 2 + 2024+ drivers: mobile: also succeeds, same as above
  • Appium 2 + 2023 or earlier drivers: mobile: fails with unknown command → caught → falls back to old endpoint → deprecation warning logged once

The deprecation warning will tell users which driver they need to upgrade to to remove the old endpoint dependency.

What this PR does (protocol layer)

  • Renames 37 protocol commands that have a mobile: replacement by prefixing them with appium (e.g. lockappiumLock, getCurrentPackageappiumGetCurrentPackage). The original clean names are reserved for upcoming mobile command wrappers with try/catch fallback logic.
  • Adds missing deprecated notices to startRecordingScreen, stopRecordingScreen, rotateDevice, and all five IME commands.
  • Commands without a known mobile: replacement (rotateDevice, IME commands, JSONWP touch commands) keep their original names with a generic deprecation message.
  • Updates internal call sites (getContexts, switchContext, relaunchActiveApp, saveRecordingScreen) that used old protocol names, with TODO comments pointing to the upcoming mobile command implementations.

Architecture decision

Two-layer strategy:

  1. Protocol commands, raw HTTP endpoints, prefixed with appium, marked deprecated
  2. Mobile commands, smart wrappers that try mobile: execute first, catch "unknown command" errors, fall back to the appium* protocol endpoint for Appium 2 backward compat, and log a deprecation warning

This means users calling e.g. driver.lock() will transparently get the Appium 3-compatible implementation via the mobile command layer, with no breaking changes.

Commands renamed (37 total)

Old name New protocol name Future mobile command
shake appiumShake shake
lock appiumLock lock
unlock appiumUnlock unlock
isLocked appiumIsLocked isLocked
startRecordingScreen appiumStartRecordingScreen startRecordingScreen
stopRecordingScreen appiumStopRecordingScreen stopRecordingScreen
getCurrentPackage appiumGetCurrentPackage getCurrentPackage
getCurrentActivity appiumGetCurrentActivity getCurrentActivity
pressKeyCode appiumPressKeyCode pressKeyCode
longPressKeyCode appiumLongPressKeyCode longPressKeyCode
background appiumBackground background
launchApp appiumLaunchApp launchApp
closeApp appiumCloseApp closeApp
getStrings appiumGetStrings getStrings
getSystemBars appiumGetSystemBars getSystemBars
getDisplayDensity appiumGetDisplayDensity getDisplayDensity
openNotifications appiumOpenNotifications openNotifications
startActivity appiumStartActivity startActivity
touchId appiumTouchId touchId
toggleEnrollTouchId appiumToggleEnrollTouchId toggleEnrollTouchId
toggleAirplaneMode appiumToggleAirplaneMode toggleAirplaneMode
toggleData appiumToggleData toggleData
toggleWiFi appiumToggleWiFi toggleWiFi
toggleLocationServices appiumToggleLocationServices toggleLocationServices
toggleNetworkSpeed appiumToggleNetworkSpeed toggleNetworkSpeed
gsmCall appiumGsmCall gsmCall
gsmSignal appiumGsmSignal gsmSignal
gsmVoice appiumGsmVoice gsmVoice
powerCapacity appiumPowerCapacity powerCapacity
powerAC appiumPowerAC powerAC
sendSms appiumSendSms sendSms
fingerPrint appiumFingerPrint fingerPrint
setClipboard appiumSetClipboard setClipboard
getClipboard appiumGetClipboard getClipboard
getPerformanceDataTypes appiumGetPerformanceDataTypes getPerformanceDataTypes
getPerformanceData appiumGetPerformanceData getPerformanceData
sendKeyEvent appiumSendKeyEvent pressKeyCode

Test plan

  • All existing tests pass
  • Mobile command wrappers with try/catch fallback
  • TypeScript interface in packages/wdio-protocols/src/commands/appium.ts updated to new names (follow-up)
  • Unit tests for each new mobile command

…m 3 compatibility

Addresses #15124 — Appium 3 removed/deprecated JSONWP-era endpoints.

Changes in this commit (protocol layer, first step):

- Rename 37 protocol commands that have a `mobile:` replacement by prefixing
  them with `appium` (e.g. `lock` → `appiumLock`, `getCurrentPackage` →
  `appiumGetCurrentPackage`). The original clean names are reserved for
  upcoming mobile command wrappers with Appium 3 try/catch fallback logic.
- Add `deprecated` notices to commands that were previously missing them:
  `startRecordingScreen`, `stopRecordingScreen`, `rotateDevice`, and all
  five IME commands.
- Commands with no known `mobile:` replacement (`rotateDevice`, IME commands,
  JSONWP touch commands, etc.) keep their original names with an updated
  generic deprecation message.
- Update internal call sites that referenced old protocol command names
  (`getCurrentPackage`, `stopRecordingScreen`) to the new `appium*` names
  with TODO comments pointing to the upcoming mobile command implementations.
- Update tests accordingly with TODO comments.

Next steps (tracked via TODOs):
- Implement mobile command wrappers with try/catch fallback for each renamed
  command so Appium 2 users on older drivers are not broken.
- Update `packages/wdio-protocols/src/commands/appium.ts` interface to
  reflect the renamed commands.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 8, 2026

Open in StackBlitz

create-wdio

npm i https://pkg.pr.new/webdriverio/webdriverio/create-wdio@15141

eslint-plugin-wdio

npm i https://pkg.pr.new/webdriverio/webdriverio/eslint-plugin-wdio@15141

@wdio/allure-reporter

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/allure-reporter@15141

@wdio/appium-service

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/appium-service@15141

@wdio/browser-runner

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/browser-runner@15141

@wdio/browserstack-service

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/browserstack-service@15141

@wdio/cli

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/cli@15141

@wdio/concise-reporter

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/concise-reporter@15141

@wdio/config

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/config@15141

@wdio/cucumber-framework

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/cucumber-framework@15141

@wdio/dot-reporter

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/dot-reporter@15141

@wdio/firefox-profile-service

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/firefox-profile-service@15141

@wdio/globals

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/globals@15141

@wdio/jasmine-framework

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/jasmine-framework@15141

@wdio/json-reporter

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/json-reporter@15141

@wdio/junit-reporter

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/junit-reporter@15141

@wdio/lighthouse-service

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/lighthouse-service@15141

@wdio/local-runner

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/local-runner@15141

@wdio/logger

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/logger@15141

@wdio/mocha-framework

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/mocha-framework@15141

@wdio/protocols

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/protocols@15141

@wdio/repl

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/repl@15141

@wdio/reporter

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/reporter@15141

@wdio/runner

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/runner@15141

@wdio/sauce-service

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/sauce-service@15141

@wdio/shared-store-service

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/shared-store-service@15141

@wdio/smoke-test-cjs-service

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/smoke-test-cjs-service@15141

@wdio/smoke-test-reporter

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/smoke-test-reporter@15141

@wdio/smoke-test-service

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/smoke-test-service@15141

@wdio/spec-reporter

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/spec-reporter@15141

@wdio/static-server-service

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/static-server-service@15141

@wdio/sumologic-reporter

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/sumologic-reporter@15141

@wdio/testingbot-service

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/testingbot-service@15141

@wdio/types

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/types@15141

@wdio/utils

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/utils@15141

@wdio/webdriver-mock-service

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/webdriver-mock-service@15141

@wdio/xvfb

npm i https://pkg.pr.new/webdriverio/webdriverio/@wdio/xvfb@15141

webdriver

npm i https://pkg.pr.new/webdriverio/webdriverio/webdriver@15141

webdriverio

npm i https://pkg.pr.new/webdriverio/webdriverio@15141

commit: 9168741

@wswebcreation wswebcreation added the PR: Polish 💅 PRs that contain improvements on existing features label Mar 8, 2026
wswebcreation and others added 6 commits March 8, 2026 19:34
`/appium/device/app_state` is removed in Appium 3. Rename to
`appiumQueryAppState` to reserve the clean `queryAppState` name
for the future mobile command wrapper with try/catch fallback.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
Implements the `lock` mobile command that tries `mobile: lock` first
(Appium 3 / modern drivers) and falls back to the deprecated
`appiumLock` protocol endpoint for older Appium 2 drivers, logging
a deprecation warning on fallback.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
- new UTs
- generic methods
…uards and docs support

- Add 37 new mobile command wrappers that call the modern `mobile:` execute API and automatically fall back to the deprecated Appium 2 protocol endpoints for older drivers
- Throw platform-specific errors for iOS-only and Android-only commands, with hints to the equivalent command on the other platform (e.g. `touchId` → `fingerPrint` and vice versa)
- Add `@support` JSDoc tag to all new commands and update the docs formatter and template to render platform icons (iOS/Android) with a link to the official Appium driver documentation for version details
- Add full unit test coverage for all new commands including non-mobile, wrong platform, modern driver, and legacy fallback scenarios
- update docs and fix MDX generation errors
@wswebcreation wswebcreation marked this pull request as ready for review March 9, 2026 17:35
@dprevost-LMI
Copy link
Copy Markdown
Contributor

dprevost-LMI commented Mar 10, 2026

From the below, does that mean that until people migrate to Appium 3, there will be a non-working call followed by a working one that falls back on Appium 2?

Mobile commands, smart wrappers that try mobile: execute first, catch "unknown command" errors, fall back to the appium* protocol endpoint for Appium 2 backward compat, and log a deprecation warning

If so, is there any better way to do this so it is not constantly doing "failing request"?
I did ask AI yesterday, but nothing bullet-proof was really found, but we could have maybe some alternate ways, like

  • Query an endpoint that ensures it is Appium 3 vs 2
  • Use some kind of config or capability that could be easily provided so that we target the right version on the first try.

Note:

  • I'm not a big open source maintainer, so maybe your approach is more robust and should be the way to go!
  • Also, maybe it is easier to just upgrade to Appium 3 instead of trying the above options in the code!

@wswebcreation
Copy link
Copy Markdown
Member Author

Thanks for the feedback. In theory you are right, but...

  • appium (2 and 3) have a server package and separate drivers
  • The mobile:.. command is supported by the server and the drivers since a long time
  • only user group 3, appium 2 with very old drivers will have issues. These issues will already be with the drivers because they are "too old" and will give issues with the OS version of the phone. They would be from around 2023/2024. For appium drivers very old
  • there is a way to check if people have appium 3, but not a way to check if they have the right drivers (very old drivers won't even work with Appium 3), so that could be an option and I've considered this, but then we would loose user group 2 (appium 2 with more recent drivers, 2024 and up)

Hope this makes sense

@wswebcreation wswebcreation added PR: New Feature 🚀 PRs that contain new features and removed PR: Polish 💅 PRs that contain improvements on existing features labels Mar 11, 2026
@eglitise
Copy link
Copy Markdown
Contributor

Hi, I'd love to assist with this from Appium side, especially since Appium Inspector uses WDIO under-the-hood and entirely depends on its supported endpoints and commands.

The described implementation approach generally seems good to me. I suppose it may also make sense to drop support for group 3 users in WDIO v10, but that's up to you.

One thing I would like to point out is that Claude seems to have made a few mistakes regarding removed commands:

@wswebcreation
Copy link
Copy Markdown
Member Author

wswebcreation commented Mar 14, 2026

Hi @eglitise

Thanks for looking into this and for the feedback. This wasn't all Claude, it's just so helpful when fixing a lot of commands in the same way 🤣 , but in the analysis part Claude and I missed a few things you pointed out.

Here's my feedback

The described implementation approach generally seems good to me. I suppose it may also make sense to drop support for group 3 users in WDIO v10, but that's up to you.

Thanks, the challenge here is that a lot of cloudvendors don't have updated drivers, or they have the old drivers connected to old OS versions. So we want to still be "backwards compatible"

We need to soften the message, but we will proced with introducing the same command names with the `mobile: equivelant so we are ready

will revert this

  • startRecordingScreen/stopRecordingScreen do not actually have a direct mobile: equivalent, however, the commands themselves are still supported in all the main drivers, so I would probably suggest leaving its WDIO implementation as-is.

This is what is in the docs
image

I see that the new command implementation isn't platform specific, so I need to fix that

  • The replacement for toggleNetworkSpeed is mobile: networkSpeed, not mobile: setNetworkSpeed

This was my bad, will fix this

…ssages

- Fix `mobile: fingerPrint` → `mobile: fingerprint` (all lowercase, as registered in appium-android-driver)
- Fix `mobile: setNetworkSpeed` → `mobile: networkSpeed` (correct UiAutomator2 command name)
- Implement platform-specific screen recording commands
- Remove incorrect `deprecated` field from `rotateDevice` — command is still available in Appium 3
- Soften IME deprecated messages: replace incorrect "not supported in Appium 3" claim
  and `mobile: shell` workarounds with a neutral "deprecated, check driver docs" notice
- Update tests
@wswebcreation
Copy link
Copy Markdown
Member Author

@eglitise ,

See the fixes. This should fix all points there were mentioned by you

@eglitise
Copy link
Copy Markdown
Contributor

We need to soften the message, but we will proced with introducing the same command names with the `mobile: equivelant so we are ready

To clarify, these commands are only deprecated in the main Appium server (since they are platform-specific), but they are not deprecated in the UiAutomator2/Espresso drivers (which are the only drivers where these commands are relevant), so the WDIO command will still work the same way once they are removed from the Appium server.

That's why I suggest leaving them unchanged for now. If the Appium team decides to later deprecate them in the drivers and add mobile: equivalents, then yes, it would make sense to add the deprecation warning and wrapper in WDIO as well.

This is what is in the docs

Yes, it says that the endpoints have been moved to drivers, which includes all the main ones, so they are effectively still supported, and there's no need to change the WDIO implementation.
(I do agree that this is confusing; I feel like the endpoints are universal enough to still be used in the main server)

Also, XCTestScreenRecording/MediaProjectionRecording use different functionality under the hood, and have a different set of accepted input parameters, so they would not work as drop-in replacements.

@wswebcreation
Copy link
Copy Markdown
Member Author

@eglitise

To clarify, these commands are only deprecated in the main Appium server (since they are platform-specific), but they are not deprecated in the UiAutomator2/Espresso drivers (which are the only drivers where these commands are relevant), so the WDIO command will still work the same way once they are removed from the Appium server.

This means the endpoint is passed directlty from the server to the driver?

Yes, it says that the endpoints have been moved to drivers, which includes all the main ones, so they are effectively still supported, and there's no need to change the WDIO implementation.
(I do agree that this is confusing; I feel like the endpoints are universal enough to still be used in the main server)
Also, XCTestScreenRecording/MediaProjectionRecording use different functionality under the hood, and have a different set of accepted input parameters, so they would not work as drop-in replacements.

Ok, I'll revert it, thanks

@eglitise
Copy link
Copy Markdown
Contributor

This means the endpoint is passed directlty from the server to the driver?

Essentially, yes. The endpoints supported by the server are actually defined in the Appium base driver, which is a core dependency for all other drivers. As a result, drivers have access to the full set of these base driver endpoints, and can extend it with endpoints with their own. And when a session is started, the supported endpoints are retrieved from the driver directly.

@wswebcreation
Copy link
Copy Markdown
Member Author

Yes, it says that the endpoints have been moved to drivers, which includes all the main ones, so they are effectively still supported, and there's no need to change the WDIO implementation.
(I do agree that this is confusing; I feel like the endpoints are universal enough to still be used in the main server)
Also, XCTestScreenRecording/MediaProjectionRecording use different functionality under the hood, and have a different set of accepted input parameters, so they would not work as drop-in replacements.

Thanks! That makes it more clear. I've reverted all commands we discussed and will push it to this branch. If you then don't have any remarks then I'll merge it

- Restore `startRecordingScreen` and `stopRecordingScreen`
- Remove the incorrectly added mobile command wrappers for screen recording
- Remove their exports from `browser.ts` and `mobile.ts`
- remove deprecated messages for IME commands
@wswebcreation wswebcreation merged commit 8cf133a into main Mar 15, 2026
62 checks passed
@eglitise
Copy link
Copy Markdown
Contributor

@wswebcreation sorry, I had missed one more issue - the queryAppState endpoint only had its GET version removed in Appium 3, and its POST version still remains. WDIO only ever exposed the POST endpoint, so there's no need to add a wrapper for it, either.

@wswebcreation wswebcreation deleted the fix/15124-appium3-deprecated-endpoints branch March 16, 2026 10:28
@wswebcreation
Copy link
Copy Markdown
Member Author

ok, I'll remove that one, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

PR: New Feature 🚀 PRs that contain new features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[🐛 Bug]: Appium 3 deprecated/removed a lot of endpoints

3 participants