* docs(plugins): remove the duplicated word in the official plugins intro
* docs(plugins): remove the duplicated word in the ja and zh guides
* docs(plugins): revert ja and zh copies; translations are synced with Crowdin
* docs(grid): fix misspelled grid-ip-address placeholder in the en and ja guides
* docs(grid): fix the same placeholder misspelling in the zh guide
* docs(grid): revert ja and zh copies; translations are synced with Crowdin
* feat(oxc-config): restore class member ordering through JS plugins
* docs: document class method ordering for agents and contributors
* docs: keep ordering rules in the contributor style guide
* docs: simplify the agent style guide reference
* docs: add JSDoc and module ordering conventions
* docs(appium): add llms.txt to the documentation site
Adds an /llms.txt file (https://llmstxt.org/) so that LLMs can navigate the
Appium documentation without crawling it, following the same approach taken by
the Selenium project.
The file is hand-written rather than generated. Its value lies in the parts a
crawler could not work out on its own: a set of steering notes covering what
models reliably get wrong about Appium (Appium 1 era patterns, drivers needing
separate installation, the `appium:` capability prefix, `mobile:` execute
methods, the Appium 3 `--allow-insecure` scope prefix, and the move from
GET /sessions to GET /appium/sessions), followed by conceptually grouped links
with a description for each page.
MkDocs copies non-Markdown files in docs_dir to the site verbatim, so this
requires no plugin, no new dependency and no build configuration. It is served
at appium.io/docs/en/latest/llms.txt, and mike gives a per-version copy for
free.
Because the file is hand-written, nothing regenerates it when a page is renamed
or removed. check-llmstxt.js validates it against the documentation sources and
runs on every docs PR: broken links fail the build, while pages that exist but
are not listed produce a warning (or fail under --strict).
The root of appium.io is not produced by MkDocs, but crawlers look for
/llms.txt at the domain root. Since the links in the file are absolute, the
same file serves both locations, so the publish workflow copies it to the
gh-pages root on release. mike only writes under its docs/<lang> deploy prefix,
so this does not interfere with it.
English only, matching Selenium and WebdriverIO. The ja/zh docs are translated
via Crowdin, where hand-edited descriptions would drift out of sync.
* docs(appium): address llms.txt review feedback
- Describe the standard W3C capabilities as the specification's set rather than
only browserName/browserVersion/platformName, so that generated code does not
vendor-prefix acceptInsecureCerts, timeouts, pageLoadStrategy or webSocketUrl.
- Say that these pages describe Appium 3, and that Appium 2 is documented under
its own version of the site, instead of claiming both are covered here.
- Note watchOS for the XCUITest driver, and the AI-related tools (Appium MCP,
agent skills) alongside Appium Inspector.
- Correct the event timings entry: the endpoint works without the
appium:eventTimings capability, which is being removed in Appium 4.
- check-llmstxt.js: a page that exists but is not listed is now an error rather
than a warning, since a warning in CI logs is easy to miss. The --strict flag
is gone, as that is now the only behaviour.
- check-llmstxt.js: validate relative and site-relative links too. A link such
as /docs/en/3.7/guides/caps/ was previously treated as external and skipped,
so a pinned version could have slipped past the check.
* test: fix invalid import
* test: import BaseDriver from package entry in type test
tsd builds its type-check program from an explicit file list, which
trips TS6059 (composite project) when the raw lib source is imported
directly, pulling in the whole transitive dependency tree.
* fix: exclude test/types from base-driver's main tsc build
Importing @appium/base-driver by package name from within its own
test/types dir is a self-reference: the main composite build (tsc -b)
was including test/types too, so it tried to resolve the package's own
not-yet-emitted build/lib/index.d.ts while still generating it,
breaking the whole build. packages/strongbox already excludes
test/types from its main include for the same reason; tsd targets
test/types independently via its own "directory" config, unaffected
by this exclude.
* fix: use explicit tsconfig include instead of excluding test/types
Matches packages/strongbox's pattern of listing test subfolders
explicitly rather than excluding test/types from "test".
---------
Co-authored-by: Mykola Mokhnach <mokhnach@gmail.com>
* docs: update Linux driver listing
* docs: use Itsmeaj Linux driver package
* docs: identify Itsmeaj as Linux driver maintainer
* docs: add separate AT-SPI2 Linux driver entry
* docs: distinguish Linux drivers by maintainer
BREAKING CHANGE: @appium/plugin-test-support is now an ESM-only package. It can no longer be loaded via CommonJS require(); consumers must use import or dynamic import(). Deep imports into the package's internals are no longer possible — only the public entry point is exposed via exports.
BREAKING CHANGE: @appium/storage-plugin is now an ESM-only package. It can no longer be loaded via CommonJS require(); consumers must use import or dynamic import(). Deep imports into the package's internals are no longer possible — only the public entry point is exposed via exports.
BREAKING CHANGE: @appium/driver-test-support is now an ESM-only package. It can no longer be loaded via CommonJS require(); consumers must use import or dynamic import(). Deep imports into the package's internals are no longer possible — only the public entry point is exposed via exports.
BREAKING CHANGE: @appium/docutils is now an ESM-only package. It can no longer be loaded via CommonJS require(); consumers must use import or dynamic import(). Deep imports into the package's internals are no longer possible — only the public entry point is exposed via exports.
BREAKING CHANGE: @appium/opencv is now an ESM-only package. It can no longer be loaded via CommonJS require(); consumers must use import or dynamic import(). Deep imports into the package's internals are no longer possible — only the public entry point is exposed via exports.
BREAKING CHANGE: @appium/execute-driver-plugin is now an ESM-only package. It can no longer be loaded via CommonJS require(); consumers must use import or dynamic import(). Deep imports into the package's internals are no longer possible — only the public entry point is exposed via exports.
BREAKING CHANGE: The forked child process (execute-child.js) now runs as ESM as well, since it inherits "type": "module" from the package's package.json.
BREAKING CHANGE: @appium/relaxed-caps-plugin is now an ESM-only package. It can no longer be loaded via CommonJS require(); consumers must use import or dynamic import(). Deep imports into the package's internals are no longer possible — only the public entry point is exposed via exports.
BREAKING CHANGE: @appium/images-plugin is now an ESM-only package. It can no longer be loaded via CommonJS require(); consumers must use import or dynamic import(). Deep imports into the package's internals are no longer possible — only the public entry point is exposed via exports.
The plugin adds the image element center to the offset carried by
pointerMove and scroll actions. That payload is not validated anywhere,
so an action arriving without x or y made the sum NaN, and the driver
got NaN as the target coordinate. Count an unset offset as zero.
BREAKING CHANGE: @appium/strongbox is now an ESM-only package. It can no longer be loaded via CommonJS require(); consumers must use import or dynamic import(). No other package in this monorepo currently depends on @appium/strongbox, so this only affects external consumers.
BREAKING CHANGE: @appium/universal-xml-plugin is now an ESM-only package. It can no longer be loaded via CommonJS require(); consumers must use import or dynamic import(). Appium's own extension loader already loads plugins via dynamic import(), so appium plugin install/use universal-xml is unaffected. Deep imports into the package's internals are no longer possible — only the public entry point is exposed via exports.
`\b` only asserts a boundary next to a word character, so text rules like
`P@ssw0rd!` never matched anything. Now it is only added to the sides where
the value itself begins or ends with a word character.
* fix(storage-plugin): add fs.sanitizeName for the delete request
* move empty check as well
* fix: apply formatter
* return false for exception cases
* return false for exception cases
* tweak a bit
* fix format
* feat: add IPC channels per session for drivers and plugins to communicate (fix#22206)
* lint
* export AppiumIpc
* fix test issues
* import AppiumIpc directly from basedriver
* fakedriver is used directly outside of appium so can't rely on existence of IPC
* make ipc functions async with lock and better types
* fix assignIpc types
* deduplicate session object deletion
* ipcGuard -> withIpc
* address various review comments
* lint
* address copilot and other review comments
* store only last message. change model to use subscription object and async generator
* enforce max message size in bytes
* fix tests and call the message payload 'data' for clarity
* lint
* make assignIpc optional on drivers for backwards compatibility
* add error handling in startClock since it is usually not awaited
* add docs
* remove todo comment
* apply copilot and eglitise suggestions
* add typedoc
* add error handling to onIpcInit
* apply more suggestions
* fix schema unit test
* apply more suggestions
* add links to ipc examples
* make minimum ipc message size 1 instead of 0
* ensure publisher names are friendly to consumers
* fix ipc message time unit
* use already included sizeof for objs
* just pass error obj to log
* be more typescriptey about our ipc guard
* make max obj size part of opts for appiumipc
* let unsubscribe return whether it worked
* improve ipc types and shapes
* apply master package-lock.json
* update schema config
* use javascript naming conventions
* clarify distinction between message and payload (data)
* ensure async iterator loop ends when unsubscribe is called
* ensure the right things happen when you unsubscribe
* make require ipc more ergonomic
* remove unnecessary async locks and de-asyncify methods
* simplify interface and just use subscriber/plugin names
* fix docs
* fix lint
* document isActive
* add note about topic namespace
* use sleep instead of delay
* restrict the ipc payload data type to something that can be cloned
* clarify topic namespacing recommendation
* make sure listeners and promises are cleaned up in async iterator
* clean up ipc internal names
* readonly
* address review comments
* make ipcmessage readonly
* readonly cause why not
In repositories indexed by CodeGraph (a `.codegraph/` directory exists at the repo root), reach for it BEFORE grep/find or reading files when you need to understand or locate code:
- **MCP tool** (when available): `codegraph_explore` answers most code questions in one call — the relevant symbols' verbatim source plus the call paths between them, including dynamic-dispatch hops grep can't follow. Name a file or symbol in the query to read its current line-numbered source. If it's listed but deferred, load it by name via tool search.
- **Shell** (always works): `codegraph explore "<symbol names or question>"` prints the same output.
If there is no `.codegraph/` directory, skip CodeGraph entirely — indexing is the user's decision.
@@ -3,7 +3,6 @@ description: Create a new bug report.
title:'🐞 bug:<title>'
labels:[Bug, Needs Triage]
body:
- type:markdown
attributes:
value:':stop_sign:_Make sure you are reporting an issue. For general questions, please use [http://discuss.appium.io](http://discuss.appium.io)._'
@@ -13,9 +12,9 @@ body:
label:Is there an existing issue for this?
description:'Please [search :mag:the issues](https://github.com/appium/appium/issues) to check if this bug has already been reported.'
options:
- label:I have searched the existing issues
required:true
- label:I have searched the existing issues
required:true
- type:input
attributes:
label:Appium Version
@@ -49,7 +48,7 @@ body:
description:|
You can retrieve the latest server/driver/plugin version number by running `npm info <package-name> version`. If you are not up to date, please try to reproduce your issue after updating all affected components.
options:
- label:I confirm the issue is still reproducible with the latest component versions
- label:I confirm the issue is still reproducible with the latest component versions
- type:textarea
attributes:
@@ -82,10 +81,10 @@ body:
:warning: _Remember to redact or remove any sensitive information!_
value:|
- Debug details (`appium --show-debug-info`):
- Last component version(s) which did _not_ exhibit the problem:
- Platform and version of device under test:
- Real device or emulator/simulator:
- Debug details (`appium --show-debug-info`):
- Last component version(s) which did _not_ exhibit the problem:
When reviewing JavaScript or TypeScript changes, check new uses of Node.js built-in APIs against the supported Node.js versions declared in package.json#engines.node. The current supported range is ^20.19.0 || ^22.12.0 || >=24.0.0.
For each new Node.js built-in API or option, verify that it exists and is stable across all supported Node.js versions. If any supported version lacks the API, only supports it experimentally, or has different behavior, leave a review comment and suggest using the existing dependency, adding a fallback, avoiding the API, or raising the engine requirement.
Example: util.styleText exists in Node.js 20.12+, but only became stable in Node.js 22.13.0 and 23.5.0. Because this repository supports Node.js 20.19.0 and 22.12.0, replacing a color library with util.styleText should be flagged unless the project explicitly accepts relying on a non-stable API for those supported versions.
description:'Recovery mode:skip version bump, publish only packages missing on npm at their current package.json version'
required:true
type:boolean
default:false
bootstrap_packages:
description:'One-time beta-branch bootstrap only:comma-separated package names (e.g. @appium/base-driver,@appium/support) to force-bump to their next-major beta (premajor --preid beta), bypassing conventional-commit detection. Leave empty for a normal release.'
* **appium:** fallback to latest compatible extension version for CLI `install` ([#23013](https://github.com/appium/appium/issues/23013)) ([3c20d79](https://github.com/appium/appium/commit/3c20d7923806bcc2333670e6cef5c24c6da60d62))
### Bug Fixes
* **appium:** backport bidi close code validation ([#22942](https://github.com/appium/appium/issues/22942)) ([14110e5](https://github.com/appium/appium/commit/14110e50b0bf3414c778e039acb7058a3c649e2e))
* **appium:** prevent recursion when logging the first BiDi event of a method ([#22891](https://github.com/appium/appium/issues/22891)) ([77945dd](https://github.com/appium/appium/commit/77945ddaf10665f9457f6bdc94f9103a631f5ca4))
* **base-driver:** track and remove BiDi subscriptions by ID ([#22895](https://github.com/appium/appium/issues/22895)) ([6241300](https://github.com/appium/appium/commit/62413002a83e70b14eb0a3979cd7a054757a0d80))
* **support:** prevent zip extraction through symlink chains ([#23002](https://github.com/appium/appium/issues/23002)) ([#23069](https://github.com/appium/appium/issues/23069)) ([4c753a1](https://github.com/appium/appium/commit/4c753a134d8e172cfec4caec9033fe2a3d884e27))
* **appium:** do not treat a directory as a CLI argument file ([#22709](https://github.com/appium/appium/issues/22709)) ([6ba6faf](https://github.com/appium/appium/commit/6ba6faf6f533192afbdf9462dbbb3a5c1e5d85c5))
* **appium:** filter prerelease versions in driver update e2e test ([#22794](https://github.com/appium/appium/issues/22794)) ([4e8e334](https://github.com/appium/appium/commit/4e8e334cbc0ae910f521ae7ff7d3ed15f9be0a6a))
* **appium:** match insecure feature prefixes by automationName, case-insensitively ([#22710](https://github.com/appium/appium/issues/22710)) ([6ab17fe](https://github.com/appium/appium/commit/6ab17feb71d74c1f349616f22896faeb256a66ec))
* **base-driver:** add httpServer.frontRouter for global extension middleware ([#22632](https://github.com/appium/appium/issues/22632)) ([f06226b](https://github.com/appium/appium/commit/f06226b7bb2fb7ee2f3a61833f4a1d7777d4ef21))
* **appium:** parse --webhook as a URI instead of host:port ([#22635](https://github.com/appium/appium/issues/22635)) ([c35a12a](https://github.com/appium/appium/commit/c35a12a51d30fe311ef96ebe386cd9c5540e3927))
* **support:** do not treat a sibling folder as a subpath of the root ([#22586](https://github.com/appium/appium/issues/22586)) ([3a80498](https://github.com/appium/appium/commit/3a8049887dc673a6658c3821a2882e0145c3aa86))
* **storage-plugin:** add fs.sanitizeName for the delete request as well ([#22362](https://github.com/appium/appium/issues/22362)) ([5fee017](https://github.com/appium/appium/commit/5fee01752f2782e96fbe64fd13520b433d4a7535))
* add IPC channels per session for drivers and plugins to communicate ([#22211](https://github.com/appium/appium/issues/22211)) ([97c879c](https://github.com/appium/appium/commit/97c879cdd02e6fcccaaea45a8d1a7088bed4ae66)), closes [#22206](https://github.com/appium/appium/issues/22206)
* Limit the maximum count of topics per session and make it configurable ([#22279](https://github.com/appium/appium/issues/22279)) ([0264775](https://github.com/appium/appium/commit/0264775ecb8ecaca9dac2eae47784da02a653255))
* make assignIpc internal ([#22278](https://github.com/appium/appium/issues/22278)) ([25d922b](https://github.com/appium/appium/commit/25d922b7d3062c306c1631d6f5c227600ddd226a))
# Announcing LambdaTest as Appium's Newest Development Partner
As part of our ongoing effort to recognize organizations that meaningfully support the Appium project through dedicated maintainer time, we are excited to welcome our newest Development Partner: LambdaTest!
LambdaTest has long been an active participant in the automated testing ecosystem. Today, they are officially formalizing their commitment by investing people—dedicated engineers who will directly support Appium's development, maintenance, and ecosystem growth.
This kind of hands-on contribution is crucial for ensuring Appium continues to evolve. We deeply value partners who empower their engineering teams to contribute code directly to open source rather than just sponsorship.
<!-- more -->
LambdaTest has long been an active participant in the automated testing ecosystem. Today, they are officially formalizing their commitment by investing people—dedicated engineers who will directly support Appium's development, maintenance, and ecosystem growth.
This kind of hands-on contribution is crucial for ensuring Appium continues to evolve. We deeply value partners who empower their engineering teams to contribute code directly to open source rather than just sponsorship.
@@ -22,15 +24,19 @@ This kind of hands-on contribution is crucial for ensuring Appium continues to e
LambdaTest engineers are already contributing actively across several key Appium repositories. Their current focus includes:
**appium-mcp**– Supporting Appium's implementation of the Model Context Protocol (MCP) to drive forward modern AI-assisted capabilities.
**appium-remote-xpc**– Contributing to the native macOS/XPC-based remote execution layer, essential for iOS automation.
**appium-tun-tap**– Assisting in the development and maintenance of network virtualization and tunneling components for advanced testing scenarios.
* [`appium-mcp`](https://github.com/appium/appium-mcp) – Supporting Appium's implementation of the Model Context Protocol (MCP) to drive forward modern AI-assisted capabilities.
* [`appium-ios-remotexpc`](https://github.com/appium/appium-ios-remotexpc) – Contributing to the native macOS/XPC-based remote execution layer, essential for iOS automation.
* [`appium-ios-tuntap`](https://github.com/appium/appium-ios-tuntap) – Assisting in the development and maintenance of network virtualization and tunneling components for advanced testing scenarios.
These contributions strengthen critical infrastructure within the Appium ecosystem and demonstrate LambdaTest's commitment to deep technical involvement in the project's evolution.
About LambdaTest
**About LambdaTest**
LambdaTest’s platform already serves a massive community of Appium users. As a GenAI-powered Quality Engineering Platform, they provide a full-stack testing cloud with 10,000+ real mobile devices and 3,000+ browsers.
Beyond standard infrastructure, they are pushing the boundaries of test execution with AI-native test management and next-generation agents like KaneAI. By supporting Appium alongside Selenium, Playwright, and other major frameworks, LambdaTest helps teams orchestrate intelligent automation at cloud scale.
LambdaTest will continue contributing people, code, and development expertise to strengthen Appium's core functionality. Their commitment represents a significant investment into the future of the framework, and we're thrilled to have them collaborating with us at this deeper level.
The Appium project is proud to recognize LambdaTest as our newest official Development Partner. We can't wait to see what we'll build together!
If you are VS Code user, you can easily check out the project using [Runme](https://runme.dev/api/runme?repository=https%3A%2F%2Fgithub.com%2Fappium%2Fappium.git&fileToOpen=packages%2Fappium%2Fdocs%2Fen%2Fcontributing%2Findex.md).
If you are VS Code user, you can easily check out the project using [Runme](https://runme.dev/).
@@ -18,8 +18,11 @@ Each rule is an object with a set of predefined properties. The following rule p
supported:
-`pattern`: A valid Javascript RegExp pattern to replace. Must be a valid non-empty pattern.
-`text`: A simple non-empty exact text match to replace. Either this property or the above one must
be provided. `pattern` has priority over `text` if both are provided.
-`text`: A simple non-empty exact text to replace. Either this property or the above one must
be provided. `pattern` has priority over `text` if both are provided. Note that the text is
matched as a whole word: special characters are escaped and word boundaries (`\b`) are added on
the sides where the value begins or ends with a word character. For example, a rule with text
`pass` replaces `pass` in `my pass here`, but does not match inside `password`.
-`flags`: Regular expression flags for the given pattern. Supported flags are the same as for the
standard JavaScript [RegExp constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Advanced_searching_with_flags_2).
Note that the `g` (global matching) flag is always enabled.
> Appium is an open-source framework for UI automation of many app platforms - mobile (iOS, Android, Tizen), browser (Chrome, Firefox, Safari), desktop (macOS, Windows), TV (Roku, tvOS, Android TV, Samsung) and more - driven over the W3C WebDriver protocol.
Appium is split into four parts: the Appium server, which defines the core APIs; drivers, which
implement connectivity to a specific platform; clients, which implement Appium's API in a specific
programming language; and plugins, which change or extend the server's behaviour. To automate
anything you need the server, at least one driver, and a client.
Notes for tools generating Appium code from this documentation:
- Appium 3 is the current major version, and these pages describe Appium 3. Appium 2 is still
supported but is documented separately, under its own version of this site, reachable from the
version selector. Appium 1 is no longer supported: `DesiredCapabilities`, `MobileBy`, the
`findElementByAccessibilityId` family of methods, and the `/wd/hub` server base path are all
Appium 1 era patterns - the default base path has been `/` since Appium 2.
- Drivers are not bundled with the server. Install them explicitly, for example
`appium driver install uiautomator2` or `appium driver install xcuitest`.
- Appium 3 requires Node.js in the range `^20.19.0 || ^22.12.0 || >=24.0.0`, and npm 10 or newer.
- Standard W3C capabilities are written without a prefix. `platformName`, `browserName` and
`browserVersion` are the ones used most often with Appium, and the rest of the specification's
set - `acceptInsecureCerts`, `pageLoadStrategy`, `timeouts`, `webSocketUrl` and so on - is also
accepted, mostly by the browser drivers. Every Appium-specific capability needs the `appium:`
vendor prefix - `appium:automationName`, `appium:app`, `appium:udid` - or must be nested,
unprefixed, inside an `appium:options` object.
- Capabilities cannot be changed once a session has started. Parameters that are adjustable during
a session are exposed through the Settings API instead.
- Driver-specific commands are usually Execute Methods rather than new client methods: call the
standard `Execute Script` command with a known command name such as `mobile: terminateApp`, and
pass a *single* object whose keys are the parameter names. Do not invent client-side method names
for these.
- Beyond the small common set documented here, capabilities, execute methods, settings and locator
strategies are defined by each driver and documented on that driver's own site. Refer users to
the driver's documentation rather than guessing names.
- Appium 3 removed many endpoints that were deprecated in Appium 2. Check the Appium 3 migration
guide before using an endpoint carried over from older code.
- `GET /sessions` was removed. Session discovery is now `GET /appium/sessions`, and requires
starting the server with `--allow-insecure=*:session_discovery`.
- In Appium 3, every `--allow-insecure` feature name must carry a scope prefix: either a driver
name (`uiautomator2:adb_shell`) or the wildcard (`*:adb_shell`).
- WebDriver BiDi support is opt-in per session, via the standard `webSocketUrl` capability.
- Contexts model the difference between native and webview modes. `Get Contexts` always returns at
least one context, conventionally named `NATIVE_APP`.
## Getting started
- [Appium Documentation](https://appium.io/docs/en/latest/): documentation home for the Appium server and its ecosystem.
- [Appium in a Nutshell](https://appium.io/docs/en/latest/intro/): how the server, drivers, clients and plugins fit together, and what you need to install.
- [How Does Appium Work?](https://appium.io/docs/en/latest/intro/appium/): the goals and architecture of the Appium project.
- [Intro to Appium Drivers](https://appium.io/docs/en/latest/intro/drivers/): what a driver is, and how Appium supports unrelated platforms through them.
- [Intro to Appium Clients](https://appium.io/docs/en/latest/intro/clients/): Appium's client-server architecture and its relationship to the W3C WebDriver specification.
- [Getting Started](https://appium.io/docs/en/latest/quickstart/): the quickstart path - install Appium, install a driver, install a client, run a first script.
- [System Requirements](https://appium.io/docs/en/latest/quickstart/requirements/): supported operating systems and the required Node.js and npm versions.
- [Install Appium](https://appium.io/docs/en/latest/quickstart/install/): installing the Appium server with npm.
- [Install the UiAutomator2 Driver](https://appium.io/docs/en/latest/quickstart/uiauto2-driver/): installing an Android driver and its Android SDK prerequisites.
- [Write a Test (JS)](https://appium.io/docs/en/latest/quickstart/test-js/): a first Appium script in JavaScript with WebdriverIO.
- [Write a Test (Python)](https://appium.io/docs/en/latest/quickstart/test-py/): a first Appium script in Python.
- [Write a Test (Java)](https://appium.io/docs/en/latest/quickstart/test-java/): a first Appium script in Java.
- [Write a Test (Ruby)](https://appium.io/docs/en/latest/quickstart/test-rb/): a first Appium script in Ruby.
- [Write a Test (.NET)](https://appium.io/docs/en/latest/quickstart/test-dotnet/): a first Appium script in C#.
- [Next Steps](https://appium.io/docs/en/latest/quickstart/next-steps/): where to go after the quickstart.
## Drivers, clients and plugins
Which driver you install determines which platform you can automate, and the driver's own
documentation is the authoritative source for its capabilities and commands.
- [The Appium Ecosystem](https://appium.io/docs/en/latest/ecosystem/): index of officially-supported and community-supported Appium projects.
- [Appium Drivers](https://appium.io/docs/en/latest/ecosystem/drivers/): every known driver with its install command and documentation link. Official drivers include UiAutomator2 and Espresso (Android), XCUITest (iOS, iPadOS, tvOS, watchOS), Mac2 (macOS), Windows, Chromium, Gecko and Safari.
- [Appium Clients](https://appium.io/docs/en/latest/ecosystem/clients/): official clients for Java, Python, Ruby and .NET, plus community clients including WebdriverIO, Nightwatch.js, Robot Framework, Rust and Swift.
- [Appium Plugins](https://appium.io/docs/en/latest/ecosystem/plugins/): optional extensions that modify or extend server behaviour. Not required for standard automation.
- [Appium-Related Tools](https://appium.io/docs/en/latest/ecosystem/tools/): tools for installation, test development and inspection, such as Appium Inspector, and tools for driving Appium from an AI agent, such as the Appium MCP server and the Appium agent skills.
- [Managing Drivers and Plugins](https://appium.io/docs/en/latest/guides/managing-exts/): installing, listing, updating and removing extensions, and installing from sources other than the official index.
## Sessions and capabilities
- [Session Capabilities](https://appium.io/docs/en/latest/guides/caps/): how capabilities work, the `appium:` vendor prefix, `appium:options` grouping, BiDi opt-in via `webSocketUrl`, and always-match versus first-match.
- [Session Properties](https://appium.io/docs/en/latest/reference/session/): the key properties of a session - capabilities, execute methods, settings and locator strategies - and which are defined by the server versus the driver.
- [Capabilities](https://appium.io/docs/en/latest/reference/session/caps/): the full list of capabilities recognized by the Appium server and base driver, and therefore supported by every driver.
- [Session Settings](https://appium.io/docs/en/latest/guides/settings/): parameters that, unlike capabilities, can be adjusted while a session is running.
- [Execute Methods](https://appium.io/docs/en/latest/guides/execute-methods/): the `mobile:` command convention that drivers use to expose commands beyond the WebDriver spec, with examples in every official client language.
- [Managing Contexts](https://appium.io/docs/en/latest/guides/context/): switching between native and webview modes with the Get Contexts, Get Current Context and Set Context commands.
- [Caching of Application Bundles](https://appium.io/docs/en/latest/guides/caching/): how the base driver caches application builds, and how to use it for faster suite execution.
- [Retrieving Event Timings](https://appium.io/docs/en/latest/guides/event-timing/): startup and command timing information, retrieved from the `POST /session/:sessionId/appium/events` endpoint. The `appium:eventTimings` capability described on that page is not required for the endpoint to work, and is being removed in Appium 4.
## Server configuration and the command line
- [Command Line Interface](https://appium.io/docs/en/latest/reference/cli/): the `appium` executable and its `server`, `driver`, `plugin` and `setup` subcommands.
- [appium server](https://appium.io/docs/en/latest/reference/cli/server/): the complete set of server command-line arguments.
- [appium driver/plugin](https://appium.io/docs/en/latest/reference/cli/extensions/): the extension management subcommands - `install`, `list`, `update`, `uninstall`, `run` and `doctor`.
- [appium setup](https://appium.io/docs/en/latest/reference/cli/setup/): installing a preset bundle of extensions for mobile, browser or desktop automation.
- [Environment Variables](https://appium.io/docs/en/latest/reference/cli/env-vars/): advanced behaviour toggled through the environment rather than CLI arguments.
- [The Appium Config File](https://appium.io/docs/en/latest/guides/config/): supplying server arguments through a config file instead of the command line. CLI arguments take precedence.
- [Filtering the Appium Log](https://appium.io/docs/en/latest/guides/log-filters/): redacting passwords, device identifiers and other sensitive values from server logs with `--log-filters`.
- [Header Handling](https://appium.io/docs/en/latest/guides/headers/): request ID tracking through the `x-request-id` header.
- [SSL/TLS/SPDY Support](https://appium.io/docs/en/latest/guides/tls/): starting the server with secure connections enabled.
- [Appium and Selenium Grid](https://appium.io/docs/en/latest/guides/grid/): relaying commands from a Selenium Grid to an Appium server.
## Security
- [Appium Server Security](https://appium.io/docs/en/latest/guides/security/): the insecure-feature mechanism, and the `--allow-insecure`, `--deny-insecure` and `--relaxed-security` flags. In Appium 3 every feature name requires a scope prefix.
- [Insecure Features](https://appium.io/docs/en/latest/reference/cli/insecure-features/): the features defined at the server and official-plugin level, including `session_discovery` and `execute_driver_script`. Drivers define their own in their own documentation.
## API endpoints
- [Reference](https://appium.io/docs/en/latest/reference/): index of the core interfaces supported by the Appium server.
- [API Endpoints](https://appium.io/docs/en/latest/reference/api/): endpoints exposed by the base driver, and therefore inherited by every driver.
- [WebDriver Protocol](https://appium.io/docs/en/latest/reference/api/webdriver/): the W3C WebDriver endpoints Appium supports.
- [WebDriver BiDi Protocol](https://appium.io/docs/en/latest/reference/api/bidi/): the W3C WebDriver BiDi commands Appium supports. These are commands over a WebSocket, not URL endpoints, and require the `webSocketUrl` capability.
- [Appium Protocol](https://appium.io/docs/en/latest/reference/api/appium/): endpoints defined by Appium's own extension of the WebDriver protocol.
- [Plugin Endpoints](https://appium.io/docs/en/latest/reference/api/plugins/): endpoints added or modified by the official plugins.
- [Other Protocols](https://appium.io/docs/en/latest/reference/api/others/): additional supported endpoints, including the Chromedriver protocol extension.
## Migrating between major versions
- [Migrating to Appium 3](https://appium.io/docs/en/latest/guides/migrating-2-to-3/): every breaking change from Appium 2 to 3 - the Node 20 minimum, removed and modified endpoints, the mandatory `--allow-insecure` scope prefix, and the move from `GET /sessions` to `GET /appium/sessions`.
- [Migrating to Appium 2](https://appium.io/docs/en/latest/guides/migrating-1-to-2/): the Appium 1 to 2 changes, including drivers becoming separately installed extensions and the default base path changing from `/wd/hub` to `/`.
## Building drivers and plugins
- [Developing Appium Extensions](https://appium.io/docs/en/latest/developing/): overview of building your own driver or plugin against Appium's modular structure.
- [Building Drivers](https://appium.io/docs/en/latest/developing/build-drivers/): writing a driver, including command definitions, capability constraints and execute methods.
- [Building Plugins](https://appium.io/docs/en/latest/developing/build-plugins/): writing a plugin that modifies or extends server behaviour.
- [Building Doctor Checks](https://appium.io/docs/en/latest/developing/build-doctor-checks/): shipping preconditions checks that `appium driver doctor` can run for your extension.
- [Building Documentation](https://appium.io/docs/en/latest/developing/build-docs/): using `@appium/docutils` to build an MkDocs site for your extension.
- [Masking Sensitive Log Data](https://appium.io/docs/en/latest/developing/sensitive/): marking values as sensitive so they are redacted from extension logs.
- [Appium's Config System](https://appium.io/docs/en/latest/developing/config-system/): how the schema-driven config file and CLI argument system works internally.
- [Local Validation Of Extension PRs](https://appium.io/docs/en/latest/guides/branch-testing/): installing a driver or plugin from an unmerged branch to test it locally.
## Contributing
- [Contributing to Appium](https://appium.io/docs/en/latest/contributing/): how to contribute code, documentation, maintenance and support to the project.
## Optional
- [Appium Blog](https://appium.io/docs/en/latest/blog/): release announcements and project news.
- [Additional Resources](https://appium.io/docs/en/latest/resources/): third-party courses, books, talks and tutorials.
- [Appium Project History](https://appium.io/docs/en/latest/intro/history/): how the project evolved since 2012, of interest mostly for background.
- [Sponsors & Backers](https://appium.io/docs/en/latest/sponsors/): the project's sponsorship program.
- [Source repository](https://github.com/appium/appium): the Appium server implementation.
- [JSON Wire Protocol](https://appium.io/docs/en/latest/reference/api/jsonwp/): legacy pre-W3C protocol, listed for historical reference. Do not base new code on it.
- [Mobile JSON Wire Protocol](https://appium.io/docs/en/latest/reference/api/mjsonwp/): legacy pre-W3C mobile protocol extension, listed for historical reference. Do not base new code on it.
@@ -89,7 +89,7 @@ Retrieves the URL endpoints and WebDriver BiDi commands supported in the current
#### Response
`ListCommandsResponse` - an object containing all supported endpoints and BiDi commands, grouped by
their origin (base Appium, driver-specific, or plugin-specific). Refer to [the type definition file](https://github.com/appium/appium/blob/master/packages/types/lib/command.ts)
their origin (base Appium, driver-specific, or plugin-specific). Refer to [the type definition file](https://github.com/appium/appium/blob/master/packages/types/lib/command-maps.ts)
for a detailed structure of this object.
### listExtensions
@@ -103,9 +103,51 @@ Retrieves the [execute methods](../../guides/execute-methods.md) supported in th
#### Response
`ListExtensionsResponse` - an object containing all supported execute methods, grouped by their
origin (driver-specific or plugin-specific). Refer to [the type definition file](https://github.com/appium/appium/blob/master/packages/types/lib/command.ts)
origin (driver-specific or plugin-specific). Refer to [the type definition file](https://github.com/appium/appium/blob/master/packages/types/lib/command-maps.ts)
for a detailed structure of this object.
### getCurrentAppiumContext
```
GET /session/:sessionId/appium/context
```
Retrieves the active application context.
#### Response
`string` - the name of the active context
### setAppiumContext
```
POST /session/:sessionId/appium/context
```
Sets an application context as the active context.
#### Parameters
|Name|Description|Type|
|--|--|--|
|`name`|Name of the context to set as the active one|string|
#### Response
`null`
### getAppiumContexts
```
GET /session/:sessionId/appium/contexts
```
Retrieves all available application contexts.
#### Response
`string[]` - the names of available contexts
### getLogEvents
```
@@ -392,3 +434,71 @@ Retrieves data from a directory on the device under test.
#### Response
`string` - the Base64-encoded zip file of the directory contents
### getAppiumRotation
```
GET /session/:sessionId/appium/device/rotation
```
Retrieves the current spatial orientation of the device under test.
#### Response
`Rotation` - an object with the following properties:
|Name|Description|Type|
|--|--|--|
|`x`|Degrees by which the device is rotated on its X axis|number|
|`y`|Degrees by which the device is rotated on its Y axis|number|
|`z`|Degrees by which the device is rotated on its Z axis|number|
### setAppiumRotation
```
POST /session/:sessionId/appium/device/rotation
```
Sets the spatial orientation of the device under test.
#### Parameters
|Name|Description|Type|
|--|--|--|
|`x`|Degrees by which the device is rotated on its X axis|number|
|`y`|Degrees by which the device is rotated on its Y axis|number|
|`z`|Degrees by which the device is rotated on its Z axis|number|
#### Response
`null`
### getAppiumOrientation
```
GET /session/:sessionId/appium/device/orientation
```
Retrieves the current orientation of the device under test.
#### Response
`string` - either `PORTRAIT` or `LANDSCAPE`
### setAppiumOrientation
```
POST /session/:sessionId/appium/device/orientation
```
Sets the orientation of the device under test.
#### Parameters
|Name|Description|Type|
|--|--|--|
|`orientation`|New device orientation. Supported values are `PORTRAIT` or `LANDSCAPE`.|string|
Unsubscribes using either previously returned subscription IDs or event names.
Removing a subscription ID preserves any overlapping subscriptions.
#### Parameters
|Name|Description|Type|Default|
|--|--|--|--|
|`contexts?`|Contexts in which to unsubscribe from the specified events. By default, the global scope is applied.|string[]|`['']`|
|`events`|Names of events to unsubscribe from|string[]||
|`subscriptions?`|Non-empty list of subscription IDs returned by `session.subscribe`. Cannot be combined with `events` or `contexts`.|string[]||
|`contexts?`|Non-standard, only together with `events`: contexts in which to unsubscribe from the specified events. By default, the global scope is applied.|string[]|`['']`|
|`events?`|Non-empty list of event names to unsubscribe from. Required when `subscriptions` is omitted.|string[]||
All subscription IDs must be known to the current session. An unknown ID causes an `invalid argument`
error without removing any subscriptions. Subscription IDs are cleared when the session is deleted.
|`--address`, `-a`|IPv4/IPv6 address to listen on|string|`0.0.0.0`|
|`--address`, `-a`|IPv4/IPv6 address or a hostname to listen on|string|`0.0.0.0`|
|`--allow-cors`|Allow web browser connections from any host|boolean|`false`|
|`--allow-insecure`|List of [insecure features](../../guides/security.md) that should be allowed in this server's sessions. Individual features can be overridden by `--deny-insecure`. Has no effect in combination with `--relaxed-security`.|array<string>|`[]`|
|`--allow-unknown-args`|Do not exit if unrecognized command-line arguments are passed to the server; ignore them instead. Useful when the Appium CLI is wrapped by external tooling that appends extra flags.|boolean|`false`|
|`--base-path`, `-pa`|Base path to use as the prefix for all webdriver routes running on the server|string|`""`|
|`--callback-address`, `-ca`|Callback IP address|string|`0.0.0.0`|
|`--callback-address`, `-ca`|Callback IP address|string|same as `--address`|
|`--config`|Path to an [Appium configuration JSON file](../../guides/config.md)|string||
|`--debug-log-spacing`|Add exaggerated spacing in logs to help with visual inspection|boolean|`false`|
@@ -48,6 +49,8 @@ appium
|`--log-no-colors`|Disable colors in the server log|boolean|`false`|
|`--log-timestamp`|Show timestamps in the server log|boolean|`false`|
|`--long-stacktrace`|Add long stack traces to log entries. Recommended for debugging only.|boolean|`false`|
|`--max-ipc-data-size`|Maximum byte size of IPC message objects.|integer|`1048576` (1MB)|
|`--max-ipc-topics`|Maximum number of IPC topics per session.|integer|`1000`|
|`--no-perms-check`|Skip various permission checks on the server startup|boolean|`false`|
|`--nodeconfig`|JSON configuration for registering Appium as a node with Selenium Grid 3|object||
|`--plugin`|Plugin-specific configuration. Keys should correspond to plugin package names|object||
@@ -62,7 +65,7 @@ appium
|`--tmp`|Absolute path to the directory used for temporary files|string|[`os.tmpdir()`](https://nodejs.org/api/os.html#ostmpdir)|
|`--use-drivers`|List of drivers to activate. By default, all installed drivers are activated.|array<string>|`[]`|
|`--use-plugins`|List of plugins to activate. By default, no plugins are activated. Set to `["all"]` to activate all installed plugins.|array<string>|`[]`|
|`--webhook`, `-G`|URL for an HTTP listener where the server logs should be output. This does not affect output on the console.|string||
|`--webhook`, `-G`|URL for an HTTP listener where the server logs should be output. This does not affect output on the console. A bare `host:port` is also accepted, which posts the logs to the root path over plain http; a value having neither a scheme nor a port falls back to `127.0.0.1:9003`.|string||
| `webSocketUrl` | Toggle support of the WebDriver BiDi protocol | `boolean` ||
| `appium:eventTimings` (deprecated) | Toggle collection of [Event Timings](../../guides/event-timing.md). This capability is deprecated - please use the [`getLogEvents`](../api/appium.md#getlogevents) endpoint instead. | `boolean` ||
| `appium:newCommandTimeout` | Number of seconds the Appium server should wait for clients to send commands before stopping the session. A value of `0` disables the timeout. | `number` | `60` |
| `appium:printPageSourceOnFindFailure` | Toggle retrieval of the the page source and its printing to the Appium log, whenever a request to find an element fails | `boolean` ||
| `appium:printPageSourceOnFindFailure` | Toggle retrieval of the page source and its printing to the Appium log, whenever a request to find an element fails | `boolean` ||
Here you can find links to additional Appium resources around the web:
## Websites
- [Appium Pro](https://appiumpro.com) - a blog and newsletter written by one of Appium's
maintainers, Jonathan Lipps, with lots of useful guides
## Online Courses
- [Appium and Selenium Fundamentals](https://ui.headspin.io/university/learn/appium-selenium-fundamentals-2020) - a comprehensive video course on learning Python, Selenium, and Appium by Jonathan Lipps
@@ -26,3 +21,4 @@ maintainers, Jonathan Lipps, with lots of useful guides
# Announcing LambdaTest as Appium's Newest Development Partner
As part of our ongoing effort to recognize organizations that meaningfully support the Appium project through dedicated maintainer time, we are excited to welcome our newest Development Partner: LambdaTest!
LambdaTest has long been an active participant in the automated testing ecosystem. Today, they are officially formalizing their commitment by investing people—dedicated engineers who will directly support Appium's development, maintenance, and ecosystem growth.
This kind of hands-on contribution is crucial for ensuring Appium continues to evolve. We deeply value partners who empower their engineering teams to contribute code directly to open source rather than just sponsorship.
<!-- more -->
LambdaTest has long been an active participant in the automated testing ecosystem. Today, they are officially formalizing their commitment by investing people—dedicated engineers who will directly support Appium's development, maintenance, and ecosystem growth.
This kind of hands-on contribution is crucial for ensuring Appium continues to evolve. We deeply value partners who empower their engineering teams to contribute code directly to open source rather than just sponsorship.
@@ -20,15 +22,19 @@ This kind of hands-on contribution is crucial for ensuring Appium continues to e
</div>
LambdaTest engineers are already contributing actively across several key Appium repositories. Their current focus includes:
**appium-mcp** – Supporting Appium's implementation of the Model Context Protocol (MCP) to drive forward modern AI-assisted capabilities.
**appium-remote-xpc** – Contributing to the native macOS/XPC-based remote execution layer, essential for iOS automation.
**appium-tun-tap** – Assisting in the development and maintenance of network virtualization and tunneling components for advanced testing scenarios.
- [`appium-mcp`](https://github.com/appium/appium-mcp) – Supporting Appium's implementation of the Model Context Protocol (MCP) to drive forward modern AI-assisted capabilities.
- [`appium-ios-remotexpc`](https://github.com/appium/appium-ios-remotexpc) – Contributing to the native macOS/XPC-based remote execution layer, essential for iOS automation.
- [`appium-ios-tuntap`](https://github.com/appium/appium-ios-tuntap) – Assisting in the development and maintenance of network virtualization and tunneling components for advanced testing scenarios.
These contributions strengthen critical infrastructure within the Appium ecosystem and demonstrate LambdaTest's commitment to deep technical involvement in the project's evolution.
About LambdaTest
**About LambdaTest**
LambdaTest’s platform already serves a massive community of Appium users. As a GenAI-powered Quality Engineering Platform, they provide a full-stack testing cloud with 10,000+ real mobile devices and 3,000+ browsers.
Beyond standard infrastructure, they are pushing the boundaries of test execution with AI-native test management and next-generation agents like KaneAI. By supporting Appium alongside Selenium, Playwright, and other major frameworks, LambdaTest helps teams orchestrate intelligent automation at cloud scale.
LambdaTest will continue contributing people, code, and development expertise to strengthen Appium's core functionality. Their commitment represents a significant investment into the future of the framework, and we're thrilled to have them collaborating with us at this deeper level.
The Appium project is proud to recognize LambdaTest as our newest official Development Partner. We can't wait to see what we'll build together!
If you are VS Code user, you can easily check out the project using [Runme](https://runme.dev/api/runme?repository=https%3A%2F%2Fgithub.com%2Fappium%2Fappium.git&fileToOpen=packages%2Fappium%2Fdocs%2Fen%2Fcontributing%2Findex.md).
If you are VS Code user, you can easily check out the project using [Runme](https://runme.dev/).
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.