Skip to content

feat!: remove the deprecated APIs - #2467

Merged
mykola-mokhnach merged 6 commits into
masterfrom
depr-rem
Oct 6, 2026
Merged

mykola-mokhnach merged 6 commits into
masterfrom
depr-rem

Conversation

@mykola-mokhnach

@mykola-mokhnach mykola-mokhnach commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Removes the APIs that were deprecated in v10 and makes the page factory and storage tests independent of real servers.
The legacy commands were kept only as fallbacks for servers without the mobile: extensions. Appium 3 removed most of the
legacy endpoints, and the UiAutomator2, XCUITest and Windows drivers have the mobile:/windows: replacements
(checked against Appium 3.8, UiAutomator2 8.7.0/9.0.0-beta.1, XCUITest 12.15.0/13.0.0-beta.1 and Windows 6.2.0).

Breaking changes

The footers for the squashed commit:

BREAKING CHANGE: The minimum supported Appium server version is now Appium 3. Only drivers and
plugins that are compatible with Appium 3 or later are supported.
BREAKING CHANGE: io.appium.java_client.functions.AppiumFunction is removed. Use
java.util.function.Function instead. It is not a drop-in replacement for the chains:
AppiumFunction#compose and AppiumFunction#andThen skipped the next step when the previous one
returned null, which FluentWait treats as 'keep polling', while Function#compose and
Function#andThen pass null on. The steps of a chain must handle null themselves, otherwise the wait
fails with a NullPointerException on the first null.
BREAKING CHANGE: AndroidMobileCommandHelper and IOSMobileCommandHelper are removed. Send the
`mobile:` extension with executeScript instead, for example driver.executeScript("mobile: shake").
BREAKING CHANGE: CanRememberExtensionPresence is removed, together with
AppiumDriver#assertExtensionExists and AppiumDriver#markExtensionAbsence. The driver interfaces do
not extend it anymore.
BREAKING CHANGE: The deprecated MobileCommand constants are removed, and the commands are not
defined in MobileCommand.commandRepository anymore: RESET, GET_STRINGS, SET_VALUE,
RUN_APP_IN_BACKGROUND, LAUNCH_APP, CLOSE_APP, GET_DEVICE_TIME, IS_APP_INSTALLED, INSTALL_APP,
ACTIVATE_APP, QUERY_APP_STATE, TERMINATE_APP, REMOVE_APP, GET_CLIPBOARD, SET_CLIPBOARD,
GET_PERFORMANCE_DATA, GET_SUPPORTED_PERFORMANCE_DATA_TYPES, HIDE_KEYBOARD, LOCK, SHAKE, TOUCH_ID,
TOUCH_ID_ENROLLMENT, CURRENT_ACTIVITY, END_TEST_COVERAGE, GET_DISPLAY_DENSITY,
GET_NETWORK_CONNECTION, GET_SYSTEM_BARS, IS_KEYBOARD_SHOWN, IS_LOCKED, LONG_PRESS_KEY_CODE,
FINGER_PRINT, OPEN_NOTIFICATIONS, PRESS_KEY_CODE, SET_NETWORK_CONNECTION, START_ACTIVITY,
TOGGLE_LOCATION_SERVICES, UNLOCK, REPLACE_VALUE, GET_CURRENT_PACKAGE, SEND_SMS, GSM_CALL,
GSM_SIGNAL, GSM_VOICE, NETWORK_SPEED, POWER_CAPACITY, POWER_AC_STATE, TOGGLE_WIFI,
TOGGLE_AIRPLANE_MODE, TOGGLE_DATA. PULL_FILE, PULL_FOLDER and PUSH_FILE stay and become public.
BREAKING CHANGE: The deprecated MobileCommand helper methods are removed: hideKeyboardCommand,
prepareArguments, pressKeyCodeCommand, longPressKeyCodeCommand (all overloads), lockDeviceCommand,
unlockDeviceCommand, getIsDeviceLockedCommand, pushFileCommand and isKeyboardShownCommand.
BREAKING CHANGE: The driver interfaces call the `mobile:` extensions only, without the fallback to
the legacy commands, so UnsupportedCommandException and InvalidArgumentException from the server are
not swallowed anymore. Affected: InteractsWithApps, LocksDevice, HidesKeyboard,
HidesKeyboardWithKeyName, HasOnScreenKeyboard, HasAppStrings, PullsFiles, PushesFiles, HasClipboard,
HasAndroidClipboard, PressesKey, AuthenticatesByFinger, CanReplaceElementValue,
HasAndroidDeviceDetails, HasNotifications, HasSupportedPerformanceDataType, StartsActivity,
SupportsGpsStateManagement, SupportsNetworkStateManagement, SupportsSpecialEmulatorCommands,
HasNetworkConnection and ShakesDevice. The Android and iOS drivers must serve the corresponding
extensions.
BREAKING CHANGE: AndroidDriver#setClipboard(label, contentType, base64Content) sends the setClipboard
extension with the label instead of the legacy setClipboard command.
BREAKING CHANGE: WindowsDriver#launchApp and WindowsDriver#closeApp send `windows: launchApp` and
`windows: closeApp` instead of the legacy /appium/app/launch and /appium/app/close routes.

Not breaking

  • WindowsDriver overrides pullFile, pullFolder and pushFile to keep sending the driver-level commands, because the Windows
    driver has no extensions for them. The requests are the same as before.
  • START_RECORDING_SCREEN, STOP_RECORDING_SCREEN and SET_SETTINGS are not deprecated anymore: the drivers still serve them and they
    have no replacements. GET_SESSION and GET_ALLSESSION stay deprecated.
  • setPowerAC requested mobile: powerAC, but the driver registers mobile: powerAc, so it always used the legacy route. It uses the
    extension now.
  • StorageClient#add reports the error that the server sends for a failed upload instead of a generic exception that wraps a
    NullPointerException.
  • Tests: the page factory tests (TimeoutTest, DesktopBrowserCompatibilityTest) use the stub driver instead of headless Chrome, and
    TimeoutTest takes 1.5s instead of about 12s. StorageTest runs against a fake of the storage plugin instead of a server at
    127.0.0.1:4723, so it is not skipped on CI anymore. The selenium-chrome-driver and webdrivermanager dependencies of the unit
    test suite are removed.

Not covered

  • GET_LOCATION and SET_LOCATION (/location, used by SupportsLocation) are not deprecated, but Appium 4 removes the route.
    They need a mobile: path (getGeolocation/setGeolocation on Android, getSimulatedLocation/setSimulatedLocation on iOS
    simulators) in a follow-up.
  • The v10 to v11 migration guide and the OpenRewrite recipe are not updated yet.

Verification

  • Unit tests (194, 0 failures), checkstyle, and compilation of the e2e source sets.
  • The commands.json golden changes by removing the commands only.
  • New ExtensionCommandsOverHttpTest covers mobile: powerAc and the Windows file, launch and close commands over a real HTTP server.

🤖 Generated with Claude Code

mykola-mokhnach and others added 4 commits October 5, 2026 20:14
BREAKING CHANGE: io.appium.java_client.functions.AppiumFunction is
removed. Use java.util.function.Function instead.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The events of a failed upload have no success field, so the null
Boolean cast threw and the error was wrapped into a generic exception
with the raw payload as its message. Check it null-safely so that the
error sent by the server is decoded.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
DesktopBrowserCompatibilityTest and TimeoutTest use the stub driver
instead of headless Chrome, and TimeoutTest now asserts a lower bound of
the waiting time and runs in 1.5s instead of about 12s. StorageTest runs
against a fake of the storage plugin of the Appium server rather than a
server at 127.0.0.1:4723, so it is not skipped on CI anymore.

The selenium-chrome-driver and webdrivermanager dependencies of the unit
test suite are removed, along with the deprecated timeout overloads of
the stub driver.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The drivers call the `mobile:` extensions only, as the legacy endpoints
were removed in Appium 3 or have extension replacements in the
UiAutomator2, XCUITest and Windows drivers. The extension presence
tracking served the fallbacks only, so it is removed as well.

WindowsDriver keeps the driver-level file transfer commands, because the
Windows driver has no extensions for them, and uses the `windows:`
extensions to launch and close the app.

The power AC extension is requested under its actual name,
`mobile: powerAc`, so it is not routed to the removed endpoint anymore.

BREAKING CHANGE: AndroidMobileCommandHelper, IOSMobileCommandHelper,
CanRememberExtensionPresence and the deprecated MobileCommand constants
and helper methods are removed. Android and iOS drivers require a server
and drivers that support the corresponding `mobile:` extensions.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

@KazuCocoa KazuCocoa left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the changes and the replacement command contracts. The unit-test build passes (194 root-project tests, zero failures), but the Function migration introduces the Android test regression noted inline. The Android device tests were not run.

Comment thread src/main/java/io/appium/java_client/functions/AppiumFunction.java
Function#compose and Function#andThen pass null on, unlike the removed
AppiumFunction, which skipped the next step. FluentWait treats null as
"keep polling", so the steps have to handle a null input themselves.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@mykola-mokhnach
mykola-mokhnach merged commit 0f6e5c1 into master Oct 6, 2026
12 checks passed
@mykola-mokhnach
mykola-mokhnach deleted the depr-rem branch October 6, 2026 21:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants