mirror of
https://github.com/appium/appium.git
synced 2026-11-03 07:34:36 +08:00
Compare commits
108
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6815fbebac | ||
|
|
b95aaac60b | ||
|
|
83122525db | ||
|
|
c159d1925c | ||
|
|
b1ec406fd3 | ||
|
|
c5f4217806 | ||
|
|
3188c9fbab | ||
|
|
b791915ffc | ||
|
|
95c04611e7 | ||
|
|
e37f1c1583 | ||
|
|
879873bad5 | ||
|
|
6c9c930cbe | ||
|
|
4de1a3e62c | ||
|
|
ae8a27e02b | ||
|
|
b9c020c6eb | ||
|
|
e391bb249f | ||
|
|
f24e7046eb | ||
|
|
b077efd67d | ||
|
|
3875344e11 | ||
|
|
11d9904166 | ||
|
|
1b7d1e0eb7 | ||
|
|
14c42f791c | ||
|
|
63e9aa4f57 | ||
|
|
9de70be6e2 | ||
|
|
c78cfa405f | ||
|
|
29a60d6e93 | ||
|
|
1b852557a3 | ||
|
|
318329fba7 | ||
|
|
6d1f28ed05 | ||
|
|
00547fe9f6 | ||
|
|
3cdc69b198 | ||
|
|
53b36283f3 | ||
|
|
5cc6041ce9 | ||
|
|
8fbdd42eab | ||
|
|
ebcac6a7e1 | ||
|
|
66ab396a71 | ||
|
|
15ecc718c4 | ||
|
|
f330716793 | ||
|
|
e033851cdf | ||
|
|
6b0938d3ac | ||
|
|
bb51494f67 | ||
|
|
d8370ccf19 | ||
|
|
fb89bb7423 | ||
|
|
dc0568bc65 | ||
|
|
f313306848 | ||
|
|
b7356ee53e | ||
|
|
ad8e7d56f8 | ||
|
|
7a79dc208c | ||
|
|
822e4d19d5 | ||
|
|
2596da02d2 | ||
|
|
225a1c6d9d | ||
|
|
22a00c7a55 | ||
|
|
09a04f4883 | ||
|
|
4f70ff136f | ||
|
|
c2e53e15e5 | ||
|
|
b09efc31c6 | ||
|
|
e303649a42 | ||
|
|
d2483b8bf4 | ||
|
|
b78454ab3e | ||
|
|
83b7835733 | ||
|
|
33d866e575 | ||
|
|
0b104f6bf9 | ||
|
|
93115d1957 | ||
|
|
ac01aa83ad | ||
|
|
0e91fb756b | ||
|
|
8b62a7971a | ||
|
|
a73644fb4f | ||
|
|
33def2cc0b | ||
|
|
b7b09f750f | ||
|
|
b129cbbcd5 | ||
|
|
d6ef7e3f12 | ||
|
|
b25fc20c51 | ||
|
|
74d1ee6d17 | ||
|
|
bcf1c57999 | ||
|
|
5e644a392f | ||
|
|
ff458d7cac | ||
|
|
812ca2a9af | ||
|
|
6323df1d73 | ||
|
|
4eb4d7f317 | ||
|
|
506bfeeb9a | ||
|
|
0df8834638 | ||
|
|
add1615607 | ||
|
|
8840f9f932 | ||
|
|
926a0a5949 | ||
|
|
db72249873 | ||
|
|
f71d980779 | ||
|
|
d82d496f9e | ||
|
|
fe24f527a4 | ||
|
|
5875b94fc4 | ||
|
|
62db5f0b20 | ||
|
|
ef8a8e1934 | ||
|
|
8709844b21 | ||
|
|
464c271fbc | ||
|
|
8db8e5748e | ||
|
|
8e8c00e6db | ||
|
|
c6e42f3fb9 | ||
|
|
fbeb496142 | ||
|
|
9f4a11e719 | ||
|
|
8b7bf30d43 | ||
|
|
835119d1ce | ||
|
|
0b83e77e7a | ||
|
|
454c22f4c2 | ||
|
|
a38539deaf | ||
|
|
e8ee71685b | ||
|
|
8fcdcb30b0 | ||
|
|
ec7de4768f | ||
|
|
cd0d8f14e9 | ||
|
|
3516e50ce6 |
@@ -23,8 +23,6 @@ targets:
|
||||
path: ./packages/appium
|
||||
- type: npm
|
||||
path: ./packages/base-driver
|
||||
- type: npm
|
||||
path: ./packages/eslint-config-appium-ts
|
||||
- type: npm
|
||||
path: ./packages/fake-driver
|
||||
- type: npm
|
||||
|
||||
@@ -20,7 +20,7 @@ runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Use Node.js ${{ inputs.node-version }}
|
||||
uses: actions/setup-node@v7.1.0
|
||||
uses: actions/setup-node@v7.0.0
|
||||
with:
|
||||
node-version: ${{ inputs.node-version }}
|
||||
cache: npm
|
||||
|
||||
+5
-5
@@ -43,6 +43,11 @@ labels:
|
||||
matcher:
|
||||
files: ['packages/appium/**']
|
||||
|
||||
- label: '@appium/http-server'
|
||||
sync: true
|
||||
matcher:
|
||||
files: ['packages/http-server/**']
|
||||
|
||||
- label: '@appium/base-driver'
|
||||
sync: true
|
||||
matcher:
|
||||
@@ -68,11 +73,6 @@ labels:
|
||||
matcher:
|
||||
files: ['packages/driver-test-support/**']
|
||||
|
||||
- label: '@appium/eslint-config-appium-ts'
|
||||
sync: true
|
||||
matcher:
|
||||
files: ['packages/eslint-config-appium-ts/**']
|
||||
|
||||
- label: '@appium/oxc-config'
|
||||
sync: true
|
||||
matcher:
|
||||
|
||||
@@ -3,6 +3,7 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- appium4
|
||||
# this list of paths could potentially impact the build
|
||||
paths:
|
||||
- '**/tsconfig*.json'
|
||||
@@ -23,6 +24,7 @@ on:
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
- appium4
|
||||
paths:
|
||||
- '**/tsconfig*.json'
|
||||
- 'packages/base-driver/test-fixtures/**/*'
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v7.0.1
|
||||
- name: Use Node.js LTS
|
||||
uses: actions/setup-node@v7.1.0
|
||||
uses: actions/setup-node@v7.0.0
|
||||
with:
|
||||
node-version: lts/*
|
||||
cache: 'npm'
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Use Node.js LTS
|
||||
uses: actions/setup-node@v7.1.0
|
||||
uses: actions/setup-node@v7.0.0
|
||||
with:
|
||||
node-version: lts/*
|
||||
cache: 'npm'
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v7.0.1
|
||||
- name: Use Node.js LTS
|
||||
uses: actions/setup-node@v7.1.0
|
||||
uses: actions/setup-node@v7.0.0
|
||||
with:
|
||||
node-version: lts/*
|
||||
cache: 'npm'
|
||||
|
||||
@@ -10,13 +10,7 @@ permissions:
|
||||
|
||||
jobs:
|
||||
prepare_matrix:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
versions: ${{ steps.generate-matrix.outputs.lts }}
|
||||
steps:
|
||||
- name: Select all current LTS versions of Node.js
|
||||
id: generate-matrix
|
||||
uses: msimerson/node-lts-versions@v2.0.2
|
||||
uses: appium/appium-workflows/.github/workflows/node-lts-matrix.yml@main
|
||||
|
||||
check:
|
||||
needs:
|
||||
@@ -29,7 +23,7 @@ jobs:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
steps:
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v7.1.0
|
||||
uses: actions/setup-node@v7.0.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Install Appium
|
||||
|
||||
@@ -49,9 +49,5 @@ jobs:
|
||||
run: |
|
||||
git config --local user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git config --local user.name "github-actions[bot]"
|
||||
- name: Check llms.txt
|
||||
run: npm run docs:check-llmstxt
|
||||
- name: Build Docs
|
||||
run: npm run docs:preview
|
||||
- name: Verify llms.txt was published to the site
|
||||
run: test -s packages/appium/docs/site/en/llms.txt
|
||||
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v7.0.1
|
||||
- name: Use Node.js LTS
|
||||
uses: actions/setup-node@v7.1.0
|
||||
uses: actions/setup-node@v7.0.0
|
||||
with:
|
||||
node-version: lts/*
|
||||
cache: 'npm'
|
||||
|
||||
@@ -13,11 +13,11 @@ on:
|
||||
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.'
|
||||
required: false
|
||||
type: string
|
||||
default: ''
|
||||
allow_legacy_peer_deps:
|
||||
description: 'Beta branch only: pass --legacy-peer-deps to lerna''s internal npm calls, for when a dependent''s peerDependencies range still lags a just-bumped major (causes ERESOLVE otherwise). Leave off unless you hit that failure.'
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
@@ -58,43 +58,29 @@ jobs:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
DRY_RUN: ${{ inputs.dry_run }}
|
||||
RECOVER_MISSING_ONLY: ${{ inputs.recover_missing_only }}
|
||||
BOOTSTRAP_PACKAGES: ${{ inputs.bootstrap_packages }}
|
||||
ALLOW_LEGACY_PEER_DEPS: ${{ inputs.allow_legacy_peer_deps }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
# On the beta branch ($BETA_BRANCH), every release is a beta prerelease anchored at its
|
||||
# target major (see packages/semantic-release-config's "Next-major beta branches" docs
|
||||
# for the equivalent semantic-release behavior this mirrors).
|
||||
#
|
||||
# allow_legacy_peer_deps: independent next-major beta.0 bumps can briefly outrun a
|
||||
# dependent's committed peerDependencies range, aborting lerna's internal lockfile
|
||||
# refresh with ERESOLVE. Opt-in only - it masks a real (if temporary) peer mismatch.
|
||||
LEGACY_PEER_DEPS_FLAGS=""
|
||||
if [ "$ALLOW_LEGACY_PEER_DEPS" = "true" ]; then
|
||||
LEGACY_PEER_DEPS_FLAGS="--npm-client-args=--legacy-peer-deps"
|
||||
fi
|
||||
|
||||
BETA_FLAGS=""
|
||||
DIST_TAG_FLAGS=""
|
||||
if [ "${{ github.ref_name }}" = "$BETA_BRANCH" ]; then
|
||||
BETA_FLAGS="--conventional-prerelease --preid beta"
|
||||
BETA_FLAGS="--conventional-prerelease --preid beta $LEGACY_PEER_DEPS_FLAGS"
|
||||
DIST_TAG_FLAGS="--dist-tag beta"
|
||||
fi
|
||||
|
||||
# One-time bootstrap for packages just starting their beta train: force them
|
||||
# straight to <next-major>.0.0-beta.0 instead of waiting for/relying on a commit that
|
||||
# happens to be marked as breaking. Not part of the normal release flow below - this
|
||||
# exits early on its own.
|
||||
if [ -n "$BOOTSTRAP_PACKAGES" ]; then
|
||||
if [ "${{ github.ref_name }}" != "$BETA_BRANCH" ]; then
|
||||
echo "bootstrap_packages is only meaningful on the $BETA_BRANCH branch" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ "$RECOVER_MISSING_ONLY" = "true" ]; then
|
||||
echo "bootstrap_packages cannot be combined with recover_missing_only" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Bootstrapping ${BOOTSTRAP_PACKAGES} to their next-major beta (premajor --preid beta), bypassing conventional-commit detection"
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
printf "n\n" | npx lerna version premajor --preid beta --exact --no-git-tag-version --no-push --force-publish="$BOOTSTRAP_PACKAGES"
|
||||
else
|
||||
npx lerna publish premajor --preid beta --exact --force-publish="$BOOTSTRAP_PACKAGES" --dist-tag beta --yes
|
||||
fi
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Prints "<pkg_name>@<pkg_version>" to stdout for each non-private workspace package
|
||||
# whose current package.json version is not yet on npm.
|
||||
find_missing_packages() {
|
||||
@@ -194,7 +180,7 @@ jobs:
|
||||
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
echo "Running lerna publish in dry-run mode"
|
||||
printf "n\n" | npx lerna version --exact --no-git-tag-version --no-push $BETA_FLAGS
|
||||
printf "n\n" | npx lerna version --no-git-tag-version --no-push $BETA_FLAGS
|
||||
else
|
||||
echo "Running lerna publish for real"
|
||||
set +e
|
||||
|
||||
@@ -47,4 +47,4 @@ jobs:
|
||||
if [ "${{ github.ref_name }}" = "$BETA_BRANCH" ]; then
|
||||
BETA_FLAGS="--conventional-prerelease --preid beta"
|
||||
fi
|
||||
npx lerna version --exact --yes $BETA_FLAGS
|
||||
npx lerna version --yes $BETA_FLAGS
|
||||
|
||||
@@ -30,18 +30,3 @@ jobs:
|
||||
run: npm run install-docs-deps
|
||||
- name: Publish docs
|
||||
run: npm run docs:publish
|
||||
# The docs are deployed by mike into docs/<lang>/<version>, but crawlers look for
|
||||
# /llms.txt at the domain root. The file's links are absolute, so the same file serves
|
||||
# both locations.
|
||||
- name: Publish llms.txt to the site root
|
||||
run: |
|
||||
cp packages/appium/docs/en/llms.txt "${RUNNER_TEMP}/llms.txt"
|
||||
git checkout -f gh-pages
|
||||
cp "${RUNNER_TEMP}/llms.txt" llms.txt
|
||||
git add llms.txt
|
||||
if git diff --cached --quiet -- llms.txt; then
|
||||
echo "Root llms.txt is already up to date"
|
||||
else
|
||||
git commit -m "docs: update root llms.txt"
|
||||
git push origin gh-pages
|
||||
fi
|
||||
|
||||
@@ -6,14 +6,12 @@ on:
|
||||
paths:
|
||||
- '.github/workflows/renovate.yml' # this file
|
||||
- '.renovaterc.json'
|
||||
- 'renovate/default.json'
|
||||
pull_request:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- '.github/workflows/renovate.yml' # this file
|
||||
- '.renovaterc.json'
|
||||
- 'renovate/default.json'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -27,4 +25,4 @@ jobs:
|
||||
- name: Validate Renovate Config
|
||||
uses: rinchsan/renovate-config-validator@v0.2.1
|
||||
with:
|
||||
pattern: '{.renovaterc.json,renovate/default.json}'
|
||||
pattern: '.renovaterc.json'
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# Do not disable package-lock. Disabling package-lock also disables npm-shrinkwrap
|
||||
package-lock=true
|
||||
save-exact=true
|
||||
foreground-scripts=true
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": ["github>appium/appium//renovate/default"],
|
||||
"extends": ["github>appium/appium-workflows//renovate/default"],
|
||||
"schedule": ["after 10pm", "before 5:00am"],
|
||||
"timezone": "America/Vancouver"
|
||||
}
|
||||
|
||||
@@ -149,31 +149,6 @@ a discretionary of special basis. Basically, this scheme is run at the project's
|
||||
not a public service. Making contributions to the project under this scheme does not obligate the
|
||||
project to pay you for such work, or otherwise compensate you in any way.
|
||||
|
||||
### Contributions Are Voluntary
|
||||
|
||||
Appium is a community-driven open source project, and all contributions to it are voluntary.
|
||||
Opening a pull request, or responding to review feedback, does not create a contract, a
|
||||
commission, a work-for-hire arrangement, or any other obligation on the part of the project, its
|
||||
Committers, the TC, or the OpenJS Foundation. In particular:
|
||||
|
||||
- The project does not hire contractors, assign paid tasks, or quote per-PR, per-task, or hourly
|
||||
rates. The "value tiers" above are an after-the-fact, discretionary gesture of appreciation, not
|
||||
a price list.
|
||||
- Compensation can't be requested, negotiated, or promised in advance, and it must not be made a
|
||||
condition for starting, continuing, or revising a contribution. A value tier is only assigned by a
|
||||
Committer after a change has been merged, and may be zero.
|
||||
- Review feedback, including requests to extend, rework, or re-scope a change, is a normal part of
|
||||
getting it merged and is never a reason to ask for additional payment.
|
||||
- Contributors are free to stop working on a change at any time. Maintainers may pick it up, or
|
||||
close it if it does not suit the project.
|
||||
- Contributions that appear to be primarily motivated by obtaining payouts (for example, bulk or
|
||||
low-effort changes, including AI-generated ones submitted without understanding or testing them)
|
||||
may be closed, and repeated abuse of the scheme may result in the contributor being excluded from
|
||||
it and from the project's spaces. Contributors are fully responsible for the content they submit,
|
||||
regardless of the tools used to produce it.
|
||||
|
||||
If you are not comfortable contributing on these terms, please do not contribute.
|
||||
|
||||
### Raising Issues Related to Governance
|
||||
|
||||
This governance model necessarily leaves many situations unspecified. If
|
||||
|
||||
@@ -133,7 +133,7 @@ appium plugin uninstall <plugin-name>
|
||||
## Server Command Line Interface
|
||||
|
||||
In order to start sending commands to the Appium server, it must be running on the URL and port
|
||||
where your client library expects it to listen. [Appium's command-line interface](https://appium.io/docs/en/latest/reference/cli/)
|
||||
where your client library expects it to listen. [Appium's command-line interface](http://appium.io/docs/en/latest/cli/server/)
|
||||
is used to launch and configure the server:
|
||||
|
||||
```bash
|
||||
@@ -161,7 +161,7 @@ for the particular driver or whether it supports parallel sessions.
|
||||
automation, all using the WebDriver model that's already the standard for web automation.
|
||||
5. You can run your automated tests locally and in a cloud. There are multiple cloud providers that
|
||||
support various Appium drivers (mostly targeting iOS and Android mobile automation).
|
||||
6. [Appium Inspector](https://appium.github.io/appium-inspector/) can be used to visually inspect
|
||||
6. [Appium Inspector](https://github.com/appium/appium-inspector) can be used to visually inspect
|
||||
the page source of applications across different platforms, facilitating easier test development.
|
||||
|
||||
Investing in the [WebDriver](https://w3c.github.io/webdriver/webdriver-spec.html) protocol means you
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
import appiumConfig from '@appium/eslint-config-appium-ts';
|
||||
import {defineConfig, globalIgnores} from 'eslint/config';
|
||||
|
||||
// Create a modified config subset for test support files:
|
||||
// Extract the test file related configs (Mocha plugin and custom rules),
|
||||
// then override their 'files' property (match by name — resilient to new config entries).
|
||||
const testFileConfigItems = appiumConfig.filter(
|
||||
(item) => typeof item?.name === 'string' && item.name.startsWith('Test Files'),
|
||||
);
|
||||
const testSupportFiles = ['packages/driver-test-support/lib/**', 'packages/plugin-test-support/lib/**'];
|
||||
const testSupportConfig = testFileConfigItems.map((item) => ({...item, files: testSupportFiles}));
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
name: 'Base Config',
|
||||
extends: [appiumConfig],
|
||||
},
|
||||
{
|
||||
name: 'Test Support',
|
||||
extends: [testSupportConfig],
|
||||
},
|
||||
{
|
||||
name: 'Consistent type-only imports (all packages)',
|
||||
files: ['**/*.{ts,tsx,mtsx}'],
|
||||
rules: {
|
||||
'@typescript-eslint/consistent-type-imports': [
|
||||
'error',
|
||||
{fixStyle: 'separate-type-imports', prefer: 'type-imports'},
|
||||
],
|
||||
},
|
||||
},
|
||||
globalIgnores([
|
||||
'**/build-fixtures/**',
|
||||
'packages/appium/docs/**/assets/**',
|
||||
'packages/appium/docs/**/js/**',
|
||||
'packages/appium/sample-code/**',
|
||||
]),
|
||||
]);
|
||||
+1
-5
@@ -2,9 +2,6 @@
|
||||
"$schema": "https://json.schemastore.org/lerna",
|
||||
"changelogPreset": "conventional-changelog-conventionalcommits",
|
||||
"command": {
|
||||
"add": {
|
||||
"exact": true
|
||||
},
|
||||
"publish": {
|
||||
"message": "chore: publish"
|
||||
},
|
||||
@@ -14,8 +11,7 @@
|
||||
"version": {
|
||||
"conventionalCommits": true,
|
||||
"createRelease": "github",
|
||||
"allowBranch": ["master", "appium4"],
|
||||
"exact": true
|
||||
"allowBranch": ["master", "appium4"]
|
||||
}
|
||||
},
|
||||
"ignoreChanges": ["**/test/**", "**/*.md"],
|
||||
|
||||
Generated
+6100
-8420
File diff suppressed because it is too large
Load Diff
+15
-27
@@ -46,10 +46,8 @@
|
||||
"dev": "run-s build:compile \"build:workspaces\" \"build:compile -- --watch\"",
|
||||
"dev:docs": "npm run -w packages/appium dev:docs",
|
||||
"docs": "npm run -w packages/appium build:docs",
|
||||
"docs:check-llmstxt": "npm run -w packages/appium check:docs:llmstxt",
|
||||
"docs:preview": "npm run -w packages/appium build:docs:preview",
|
||||
"docs:publish": "npm run -w packages/appium publish:docs",
|
||||
"doctor": "node ./scripts/doctor-stub.mjs",
|
||||
"install-docs-deps": "npm run -w packages/appium install-docs-deps",
|
||||
"format": "oxfmt -c oxfmt.config.mjs .",
|
||||
"format:check": "oxfmt -c oxfmt.config.mjs --check .",
|
||||
@@ -63,7 +61,7 @@
|
||||
"rebuild": "run-s clean build",
|
||||
"reinstall": "run-s clean clean:deps ci",
|
||||
"reinstall:angry": "npm run clean:dangerously && npm ci",
|
||||
"release": "lerna publish --exact",
|
||||
"release": "lerna publish",
|
||||
"stage-synced-pkgs": "git add -A packages/appium/README.md \"packages/*/package.json\"",
|
||||
"start": "appium",
|
||||
"sync-pkgs": "node ./scripts/sync-monorepo-packages.mjs",
|
||||
@@ -81,48 +79,38 @@
|
||||
"zip-and-upload": "run-s zip upload"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@appium/oxc-config": "1.0.0",
|
||||
"@tsconfig/node20": "20.1.10",
|
||||
"@appium/oxc-config": "2.0.0-beta.0",
|
||||
"@tsconfig/node22": "22.0.0",
|
||||
"@types/async-lock": "1.4.2",
|
||||
"@types/bluebird": "3.5.42",
|
||||
"@types/content-disposition": "0.5.9",
|
||||
"@types/express": "5.0.6",
|
||||
"@types/finalhandler": "1.2.4",
|
||||
"@types/jsftp": "2.1.5",
|
||||
"@types/json-schema": "7.0.15",
|
||||
"@types/klaw": "3.0.8",
|
||||
"@types/lockfile": "1.0.4",
|
||||
"@types/method-override": "3.0.0",
|
||||
"@types/mime-types": "3.0.1",
|
||||
"@types/morgan": "1.9.10",
|
||||
"@types/node": "24.19.2",
|
||||
"@types/plist": "3.0.5",
|
||||
"@types/node": "24.13.3",
|
||||
"@types/picomatch": "4.0.3",
|
||||
"@types/pluralize": "0.0.33",
|
||||
"@types/semver": "7.8.0",
|
||||
"@types/serve-favicon": "2.5.7",
|
||||
"@types/shell-quote": "1.7.5",
|
||||
"@types/sinon": "22.0.0",
|
||||
"@types/which": "3.0.4",
|
||||
"@types/ws": "8.18.2",
|
||||
"@types/ws": "8.18.1",
|
||||
"@types/yargs": "17.0.35",
|
||||
"asyncbox": "6.5.0",
|
||||
"asyncbox": "6.4.2",
|
||||
"conventional-changelog-conventionalcommits": "9.3.1",
|
||||
"cpy-cli": "7.0.0",
|
||||
"cross-env": "10.1.0",
|
||||
"finalhandler": "2.1.1",
|
||||
"json-schema-to-typescript": "16.0.0",
|
||||
"lerna": "10.1.1",
|
||||
"mjpeg-consumer": "2.0.0",
|
||||
"mjpeg-server": "0.3.1",
|
||||
"npm-run-all2": "9.0.4",
|
||||
"rewiremock": "3.14.6",
|
||||
"json-schema-to-typescript": "15.0.4",
|
||||
"lerna": "10.0.1",
|
||||
"npm-run-all2": "9.0.3",
|
||||
"rimraf": "6.1.3",
|
||||
"serve-static": "2.2.1",
|
||||
"sinon": "22.1.0",
|
||||
"teen_process": "4.2.1",
|
||||
"tsd": "0.33.0",
|
||||
"typescript": "6.0.3",
|
||||
"webdriverio": "9.32.0",
|
||||
"ws": "8.22.0"
|
||||
"webdriverio": "9.31.2",
|
||||
"ws": "8.21.3"
|
||||
},
|
||||
"overrides": {
|
||||
"@sidvind/better-ajv-errors": {
|
||||
@@ -131,10 +119,10 @@
|
||||
"ajv-formats": {
|
||||
"ajv": "8.20.0"
|
||||
},
|
||||
"http-cache-semantics": "4.3.0"
|
||||
"http-cache-semantics": "4.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.12.0 || >=24.0.0",
|
||||
"node": "^22.22.2 || ^24.15.0 || >=26.0.0",
|
||||
"npm": ">=10"
|
||||
}
|
||||
}
|
||||
|
||||
+134
-11
@@ -3,31 +3,154 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [3.9.0](https://github.com/appium/appium/compare/appium@3.8.0...appium@3.9.0) (2026-10-27)
|
||||
## [4.0.0-beta.3](https://github.com/appium/appium/compare/appium@4.0.0-beta.2...appium@4.0.0-beta.3) (2026-10-05)
|
||||
|
||||
### Features
|
||||
|
||||
* **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))
|
||||
* **universal-xml-plugin:** add execute methods to toggle translation ([#22862](https://github.com/appium/appium/issues/22862)) ([b95aaac](https://github.com/appium/appium/commit/b95aaac60bed065ce0a0d1e4f7baf9c5e60572b1)), closes [#21630](https://github.com/appium/appium/issues/21630)
|
||||
|
||||
### 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:** apply initial settings from selected capabilities ([#22882](https://github.com/appium/appium/issues/22882)) ([95c0461](https://github.com/appium/appium/commit/95c04611e7d1cd8acfa4c6ce51276899938588d3))
|
||||
* **appium:** bracket IPv6 hosts in BiDi websocket URLs ([#22872](https://github.com/appium/appium/issues/22872)) ([3875344](https://github.com/appium/appium/commit/3875344e111dc23e4c99310ad918b769dbb38927))
|
||||
* **appium:** close bidi sockets when a session ends unexpectedly ([#22854](https://github.com/appium/appium/issues/22854)) ([3cdc69b](https://github.com/appium/appium/commit/3cdc69b198e85607b4f35a5b3f57b542b0ae9b80))
|
||||
* **appium:** detect project homes with prerelease dependencies ([#22871](https://github.com/appium/appium/issues/22871)) ([11d9904](https://github.com/appium/appium/commit/11d9904166c9e692e6fa8491acfce4ac892c1a8e))
|
||||
* **appium:** do not crash when a proxied bidi socket closes without a sendable code ([#22835](https://github.com/appium/appium/issues/22835)) ([66ab396](https://github.com/appium/appium/commit/66ab396a71c419f1fb456b8a1ddf23bc3491baf8))
|
||||
* **appium:** explain manual recovery after manifest lock timeouts ([#22875](https://github.com/appium/appium/issues/22875)) ([b9c020c](https://github.com/appium/appium/commit/b9c020c6ebf88643ffe6b6d5e302b43673bbb028))
|
||||
* **appium:** import extensions through escaped file URLs ([#22884](https://github.com/appium/appium/issues/22884)) ([8312252](https://github.com/appium/appium/commit/83122525db72f2d6ff06e27cd3da5269318be3a8))
|
||||
* **appium:** match global and module BiDi event subscriptions ([#22883](https://github.com/appium/appium/issues/22883)) ([879873b](https://github.com/appium/appium/commit/879873bad5669c9b264f3fcb60d05562f6ca3b1e))
|
||||
* **appium:** resolve default extension export conditions ([#22885](https://github.com/appium/appium/issues/22885)) ([3188c9f](https://github.com/appium/appium/commit/3188c9fbab17c16192a6e75ff62f69f4d844be8f))
|
||||
* **appium:** roll back sessions when initialization fails ([#22873](https://github.com/appium/appium/issues/22873)) ([f24e704](https://github.com/appium/appium/commit/f24e7046eb2815822f655a644aee9786d90fd4e8))
|
||||
* **appium:** start idle timeout after session initialization ([#22881](https://github.com/appium/appium/issues/22881)) ([e37f1c1](https://github.com/appium/appium/commit/e37f1c158394617bcaa474da25f1650b9b24ebd1))
|
||||
* **base-driver:** track and remove BiDi subscriptions by ID ([#22876](https://github.com/appium/appium/issues/22876)) ([b791915](https://github.com/appium/appium/commit/b791915ffcf322e1cc84dbde606be55d34f020b3))
|
||||
* use native ESM entrypoint detection ([#22868](https://github.com/appium/appium/issues/22868)) ([e391bb2](https://github.com/appium/appium/commit/e391bb249fec5f700a6d63a747ff921a80689fb5))
|
||||
|
||||
|
||||
## [3.8.0](https://github.com/appium/appium/compare/appium@3.7.0...appium@3.8.0) (2026-09-24)
|
||||
## [4.0.0-beta.2](https://github.com/appium/appium/compare/appium@4.0.0-beta.1...appium@4.0.0-beta.2) (2026-09-27)
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* **base-driver:** @appium/base-driver no longer exports server, normalizeBasePath, configureServer, ServerOpts, ConfigureServerOpts, ConfigureHttpOpts, or StartServerOpts, and no longer depends on express/morgan/body-parser/ method-override/path-to-regexp. Use the new @appium/http-server package instead.
|
||||
* **base-driver:** appium/driver.js and driver.d.ts no longer re-export server/normalizeBasePath/configureServer/ServerOpts (or their types), and no longer use a blanket export *. Import from @appium/http-server directly if you were relying on this undocumented path.
|
||||
|
||||
### Features
|
||||
|
||||
* **appium:** accept package names for installed extension commands ([#22747](https://github.com/appium/appium/issues/22747)) ([6c911de](https://github.com/appium/appium/commit/6c911debd72cb7fe094d27671d1cf14098ff537a))
|
||||
* **appium:** accept package names for installed extension commands ([#22747](https://github.com/appium/appium/issues/22747)) ([#22812](https://github.com/appium/appium/issues/22812)) ([b7356ee](https://github.com/appium/appium/commit/b7356ee53eec3e322707eef0d2bd37976a47cfd2))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **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))
|
||||
* **appium:** release the manifest lock before errAndQuit exits ([#22821](https://github.com/appium/appium/issues/22821)) ([dc0568b](https://github.com/appium/appium/commit/dc0568bc658961f5d6a28fb955d8092d51cf9523))
|
||||
* **base-driver:** carry proxy req via AsyncLocalStorage instead of args ([#22799](https://github.com/appium/appium/issues/22799)) ([2596da0](https://github.com/appium/appium/commit/2596da02d201d7e5fbfd24cf9dd2801302f8abc7))
|
||||
* **support:** narrow fs.glob overload for default withFileTypes/lazy ([#22795](https://github.com/appium/appium/issues/22795)) ([09a04f4](https://github.com/appium/appium/commit/09a04f48831e17b9b7f3b8dc0a72f0df5096ae51))
|
||||
|
||||
### Code Refactoring
|
||||
|
||||
* **base-driver:** extract the HTTP/Express server into @appium/http-server ([#22800](https://github.com/appium/appium/issues/22800)) ([225a1c6](https://github.com/appium/appium/commit/225a1c6d9d24fa2696699d4b61436a49b847d666))
|
||||
|
||||
|
||||
## [4.0.0-beta.1](https://github.com/appium/appium/compare/appium@4.0.0-beta.0...appium@4.0.0-beta.1) (2026-09-19)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **deps:** catch up peerDependencies to published beta.0; drop bootstrap_packages ([#22793](https://github.com/appium/appium/issues/22793)) ([b09efc3](https://github.com/appium/appium/commit/b09efc31c6967bbcf2c4314db9d2a0b6454fa8fb))
|
||||
|
||||
|
||||
## [4.0.0-beta.0](https://github.com/appium/appium/compare/appium@3.7.0...appium@4.0.0-beta.0) (2026-09-19)
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* **base-driver:** align timeouts endpoints closer to W3C standard (#22776)
|
||||
* users relying on the implicit debug default for console/file logs will now see info-level output unless they explicitly pass --log-level debug.
|
||||
* **support:** Any script or tool that consumes Appium CLI output (driver/plugin list/install/update, doctor, etc.) and relies on the previous stream layout will need to be updated. Previously, non-JSON human-readable output (info/success/warning messages) was written to STDERR, with STDOUT reserved almost exclusively for --json output. Now that output goes to STDOUT, and only actual errors go to STDERR.
|
||||
* **support:** Scripts that discarded STDOUT (1>/dev/null) to suppress "chatter" while relying on STDERR for status text will now see that text on STDOUT instead.
|
||||
* **support:** Scripts that captured STDERR to detect/log informational or success messages will no longer see them there — only genuine errors will appear on STDERR. --json output and error behavior are unaffected: --json continues to write clean JSON to STDOUT only, and errors continue to go to STDERR.
|
||||
* **support:** @appium/logger's Log class changes its default output stream from STDERR to STDOUT for all levels except error, and adds an errorStream/stderrLevel pair of properties. Any code that set .stream on a Log instance expecting it to capture all levels (including error) will now need to also set .errorStream to the same target.
|
||||
* **base-driver:** @appium/base-driver's default export (BaseDriver) and @appium/base-driver's basedriver/helpers.js default export are removed; use the named exports instead. The appium/driver.js and driver.d.ts re-exports of the default are removed accordingly.
|
||||
* **base-driver:** BaseDriver.reset() is removed; it was unused, not part of any protocol route or the Driver interface, and had no callers in this monorepo or any driver package that was checked.
|
||||
* **base-driver:** BaseDriver's constructor is removed in favor of inherited DriverCore construction; opts is no longer a required constructor argument (it now defaults to {}, matching DriverCore).
|
||||
* **support:** @appium/support's fs.glob option shape changed from the glob package's GlobOptions to a smaller, @appium/support-owned GlobOptions interface. Supported fields: cwd, withFileTypes, absolute, lazy. Options like nodir/ignore/nocase are no longer supported directly — callers needing directory filtering can pass withFileTypes: true and filter on .isFile()/.isDirectory(); callers needing path exclusion can filter the returned array by pattern.
|
||||
* **appium:** The --allow-cors CLI flag and allow-cors config file property have been removed. Use --allow-insecure=*:cors (or --relaxed-security, optionally overridden with --deny-insecure=*:cors) instead.
|
||||
* **base-driver:** ISessionHandler.createSession (@appium/types) and LegacyCreateSessionArgs — overload and type deleted, single-argument signature only.
|
||||
* **base-driver:** BaseDriver.createSession and AppiumDriver.createSession — collapsed to the single-argument mplementation; capability validation now checks the one argument directly instead of scanning three positions for the first W3C-shaped value.
|
||||
* **base-driver:** FakeDriver.createSession (and the base-driver e2e test double) — overrides updated to match.
|
||||
* **base-driver:** RelaxedCapsPlugin.createSession — this plugin existed specifically to normalize capabilities across the (now-gone) three positions; its hook is simplified to a single caps argument.
|
||||
* **base-driver:** POST /session wire route (w3c.ts) — payloadParams.optional no longer sends capabilities three times into the command args.
|
||||
* **base-driver:** BaseDriver.getSession, ISessionHandler.getSession, and the GET /session/:sessionId JSONWP route are gone. Use getAppiumSessionCapabilities to retrieve session capabilities and EventCommands.getLogEvents to retrieve event history instead.
|
||||
* **base-driver:** The appium:eventTimings capability is removed; it only ever controlled whether getSession's response was decorated with event history, which getLogEvents already exposes unconditionally.
|
||||
* **support:** move npm-related helpers into appium package (#22721)
|
||||
* **logger:** @appium/logger and @appium/support no longer export a default log — import the named log export instead.
|
||||
* **logger:** AppiumLogger#errorAndThrow has been removed; use errorWithException instead.
|
||||
* **logger:** Logger#enableProgress, disableProgress, progressEnabled, enableUnicode, disableUnicode have been removed; they were already permanently disabled no-ops.
|
||||
* **base-plugin:** Plugin#logger has been removed; use Plugin#log instead.
|
||||
* **base-plugin:** @appium/base-plugin no longer exports BasePlugin as the default export; use the named BasePlugin export.
|
||||
* Core.driverData, DriverData, and the driverData parameter on ISessionHandler.createSession/deleteSession are gone. Any driver overriding get driverData() or relying on the umbrella driver passing sibling-session data into createSession/deleteSession needs to migrate off this mechanism.
|
||||
* FakeDriver no longer supports the uniqueApp capability.
|
||||
* **support:** npm.installPackage now takes a hasAppiumDependency boolean computed by the caller instead of importing the check itself, avoiding a support -> appium dependency.
|
||||
* **support:** The env export is removed from @appium/support.
|
||||
* the minimum supported Node.js engine is set to ^22.22.2 || ^24.15.0 || >=26.0.0
|
||||
* **base-driver:** @appium/base-driver no longer exports statusCodes or getSummaryByCode (the jsonwp-status module was removed).
|
||||
* **base-driver:** errorFromMJSONWPStatusCode (aliased as errorFromCode) has been removed; use errorFromW3CJsonCode for W3C error-signature mapping.
|
||||
* **base-driver:** ProtocolError instances no longer have a jsonwpCode property.
|
||||
* **base-driver:** WebDriverProxy (formerly JWProxy) no longer proxies to or interprets responses from downstream servers speaking the legacy MJSONWP protocol; the ProtocolConverter class, COMMAND_URLS_CONFLICTS, and the downstreamProtocol getter/setter have been removed. Downstream automation servers must speak W3C WebDriver.
|
||||
* **base-driver:** Responses no longer duplicate element references under the legacy ELEMENT key; only the W3C element-6066-11e4-a52e-4f735466cecf key is present. The MJSONWP_ELEMENT_KEY constant has been removed.
|
||||
* **base-driver:** determineProtocol has been removed, and drivers can no longer produce the legacy {sessionId, status, value} response shape; all responses are now W3C-shaped regardless of how the client formatted its createSession capabilities.
|
||||
* **base-driver:** DriverCore#setProtocolMJSONWP() has been removed.
|
||||
* **base-driver:** The deprecated JWProxy export has been removed; use WebDriverProxy instead. Its source also moved from lib/jsonwp-proxy/proxy.js to lib/wd-proxy/proxy.js.
|
||||
* **base-driver:** DriverCore#isMjsonwpProtocol() has been removed.
|
||||
* **support:** The following @appium/support exports have been removed: process (getProcessIds, killProcess), mkdirp, imageUtil (requireSharp, cropBase64Image), mjpeg (MJpegStream), net's FTP upload
|
||||
support (FtpUploadOptions, NotHttpUploadOptions; uploadFile only supports http/https now), util's uuidV1/uuidV3/uuidV5/localIp/cancellableDelay/multiResolve, and fs's readPackageJsonFrom/findRoot/ F_OK/R_OK/W_OK/X_OK.
|
||||
* **appium:** The --nodeconfig server argument and the server.nodeconfig config file property no longer exist. Users who need to register with a Selenium Grid should use the Grid 4 relay feature instead (see the Grid guide).
|
||||
* **base-driver:** TLS-enabled Appium servers no longer negotiate SPDY/HTTP2 (spdy/2, spdy/3, spdy/3.1, h2) via ALPN; connections are now served as plain HTTPS (HTTP/1.1) using Node's native https module. Clients relying on SPDY or HTTP/2 multiplexing against Appium's TLS listener must switch to HTTP/1.1.
|
||||
* **appium:** `npm install -g appium --drivers=... --plugins=...` no longer installs extensions automatically. Use `appium driver/plugin install` or add extensions to package.json instead.
|
||||
* require('@appium/support') no longer works; consumers must import it instead.
|
||||
* require('@appium/base-driver') no longer works; drivers extending BaseDriver via require must switch to import.
|
||||
* require('@appium/base-plugin') no longer works; plugins extending BasePlugin via require must switch to import.
|
||||
* require('appium') no longer works; plugins extending the package via require must switch to import.
|
||||
* require('@appium/fake-plugin') no longer works; consumers must import it instead.
|
||||
* require('@appium/fake-driver') no longer works; consumers must import it instead.
|
||||
* require('@appium/types') no longer works; consumers must import it instead.
|
||||
* require('@appium/logger') no longer works; consumers must import it instead.
|
||||
* require('@appium/schema') no longer works; consumers must import it instead.
|
||||
|
||||
### Features
|
||||
|
||||
* **appium:** add --app-url-rules server arg to restrict remote app URLs ([#22753](https://github.com/appium/appium/issues/22753)) ([0b104f6](https://github.com/appium/appium/commit/0b104f6bf9b7180b111df40fd6a15b26d649eabd))
|
||||
* **appium:** remove postinstall autoinstall-extensions script ([#22675](https://github.com/appium/appium/issues/22675)) ([cd0d8f1](https://github.com/appium/appium/commit/cd0d8f14e9d5906ecd1b438038a7f67f74f742fc))
|
||||
* **appium:** remove Selenium Grid 3 support ([#22677](https://github.com/appium/appium/issues/22677)) ([8fcdcb3](https://github.com/appium/appium/commit/8fcdcb30b07c1ee582256fbef3538d6a3ceea5f2))
|
||||
* **appium:** replace --allow-cors flag with --allow-insecure=*:cors ([#22731](https://github.com/appium/appium/issues/22731)) ([926a0a5](https://github.com/appium/appium/commit/926a0a594935a6cf2e7375eb174eeb15af964f12))
|
||||
* **appium:** validate extension manifests and extensions.yaml via ajv ([#22732](https://github.com/appium/appium/issues/22732)) ([8840f9f](https://github.com/appium/appium/commit/8840f9f9322b63bc8940c390b8230f1e5306fa62))
|
||||
* backport diff from master ([#22749](https://github.com/appium/appium/issues/22749)) ([6323df1](https://github.com/appium/appium/commit/6323df1d7354f85cc631508f5cb6a3e35270d4bd))
|
||||
* **base-driver:** add definitions for all WebDriver BiDi commands ([#22770](https://github.com/appium/appium/issues/22770)) ([ac01aa8](https://github.com/appium/appium/commit/ac01aa83ad73982eea48f856dfc0249b4a26e395))
|
||||
* **base-driver:** align timeouts endpoints closer to W3C standard ([#22776](https://github.com/appium/appium/issues/22776)) ([93115d1](https://github.com/appium/appium/commit/93115d195773b011306ffb2e6d7d6cc935df0148))
|
||||
* **base-driver:** remove legacy (M)JSONWP protocol support ([#22681](https://github.com/appium/appium/issues/22681)) ([0b83e77](https://github.com/appium/appium/commit/0b83e77e7a1c24a885d9895a99db30281cf4acea))
|
||||
* **base-driver:** replace spdy with native https transport ([#22676](https://github.com/appium/appium/issues/22676)) ([ec7de47](https://github.com/appium/appium/commit/ec7de4768fdd8dde9d28db6fc2dfd63be45fd4c6))
|
||||
* bump minimum supported Node.js engine to ^22.22.2 || ^24.15.0 || >=26.0.0 ([#22685](https://github.com/appium/appium/issues/22685)) ([9f4a11e](https://github.com/appium/appium/commit/9f4a11e7190290986d01743557e90e6e44f87638))
|
||||
* Change the default log level to `info` ([#22756](https://github.com/appium/appium/issues/22756)) ([5e644a3](https://github.com/appium/appium/commit/5e644a392fbf11e2ca985408853d7f51aa85be17))
|
||||
* convert remaining monorepo packages to ESM-only ([#22674](https://github.com/appium/appium/issues/22674)) ([3516e50](https://github.com/appium/appium/commit/3516e50ce6d022f4c0dc539071c593bf2983325f))
|
||||
* **support:** move env/APPIUM_HOME resolution into appium package ([#22708](https://github.com/appium/appium/issues/22708)) ([8db8e57](https://github.com/appium/appium/commit/8db8e5748e26a7150cacbea09ba3ec52c5ce3fc0))
|
||||
* **support:** remove deprecated APIs ([#22678](https://github.com/appium/appium/issues/22678)) ([e8ee716](https://github.com/appium/appium/commit/e8ee71685b4c21116e61c88fd8d2f0e39fac2edb))
|
||||
* **types:** check execute method params against the command signature ([#22754](https://github.com/appium/appium/issues/22754)) ([b25fc20](https://github.com/appium/appium/commit/b25fc20c51a191c33695c1c71fbf129de834b52d))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* address code review cleanups (plist, env memoize, test reuse) ([#22740](https://github.com/appium/appium/issues/22740)) ([0df8834](https://github.com/appium/appium/commit/0df883463812d57d44a0d6d80e9b88f124361934))
|
||||
* Address several TODOs ([#22762](https://github.com/appium/appium/issues/22762)) ([d6ef7e3](https://github.com/appium/appium/commit/d6ef7e3f1240f161df622c850aea06637f9d1078))
|
||||
* adjust deprecated JSONWP/MJSONWP routes ([#22763](https://github.com/appium/appium/issues/22763)) ([b129cbb](https://github.com/appium/appium/commit/b129cbbcd55656ae7f33b80b4b52719eb5179509))
|
||||
* **appium:** lock the extension manifest while driver/plugin commands run ([#22767](https://github.com/appium/appium/issues/22767)) ([a73644f](https://github.com/appium/appium/commit/a73644fb4f4e7b0363117ac1262d7018094b42ff))
|
||||
* **base-driver:** clean up aborted session creation ([#22733](https://github.com/appium/appium/issues/22733)) ([33d866e](https://github.com/appium/appium/commit/33d866e57506e1546aa4870dde75f7209be107bc))
|
||||
* declare dependencies that were only resolving via hoisting ([#22758](https://github.com/appium/appium/issues/22758)) ([bcf1c57](https://github.com/appium/appium/commit/bcf1c579997b8dbb8292b1a77583aeef40b11ba4))
|
||||
* **support:** route non-error CLI console output to stdout ([#22742](https://github.com/appium/appium/issues/22742)) ([4eb4d7f](https://github.com/appium/appium/commit/4eb4d7f317a685d681b6cf4e25c15b617a8cc7df))
|
||||
|
||||
### Code Refactoring
|
||||
|
||||
* **base-driver:** remove deprecated getSession command ([#22725](https://github.com/appium/appium/issues/22725)) ([f71d980](https://github.com/appium/appium/commit/f71d980779d23e9a19d33285646fad128eae4917))
|
||||
* **base-driver:** remove deprecated multi-argument createSession overload ([#22730](https://github.com/appium/appium/issues/22730)) ([db72249](https://github.com/appium/appium/commit/db722498739ae7fe1deef1b98e02d04b455a4f70))
|
||||
* **base-driver:** replace command mixin with explicit named exports ([#22741](https://github.com/appium/appium/issues/22741)) ([506bfee](https://github.com/appium/appium/commit/506bfeeb9aa15c0dd1f481868d347cb9b0d37f86))
|
||||
* **base-plugin:** remove deprecated legacy logger and default export ([#22718](https://github.com/appium/appium/issues/22718)) ([62db5f0](https://github.com/appium/appium/commit/62db5f0b20c496b495ce27d490453861ddefb259))
|
||||
* **logger:** remove default exports and dead logging APIs ([#22719](https://github.com/appium/appium/issues/22719)) ([fe24f52](https://github.com/appium/appium/commit/fe24f527a4412ed86c7b5e5afe0c6e26dc569e6b))
|
||||
* remove deprecated driverData mechanism ([#22716](https://github.com/appium/appium/issues/22716)) ([ef8a8e1](https://github.com/appium/appium/commit/ef8a8e1934bfdc9699c2b9a7eca3e2201b4b9f93))
|
||||
* **support:** move npm-related helpers into appium package ([#22721](https://github.com/appium/appium/issues/22721)) ([d82d496](https://github.com/appium/appium/commit/d82d496f9e80d6628abface3b623601a6f9791f9))
|
||||
* **support:** replace glob package with native node:fs glob ([#22735](https://github.com/appium/appium/issues/22735)) ([add1615](https://github.com/appium/appium/commit/add161560701ac7fb2bc372ddefd9317146fbae8))
|
||||
|
||||
|
||||
## [3.7.0](https://github.com/appium/appium/compare/appium@3.6.0...appium@3.7.0) (2026-08-24)
|
||||
|
||||
@@ -133,7 +133,7 @@ appium plugin uninstall <plugin-name>
|
||||
## Server Command Line Interface
|
||||
|
||||
In order to start sending commands to the Appium server, it must be running on the URL and port
|
||||
where your client library expects it to listen. [Appium's command-line interface](https://appium.io/docs/en/latest/reference/cli/)
|
||||
where your client library expects it to listen. [Appium's command-line interface](http://appium.io/docs/en/latest/cli/server/)
|
||||
is used to launch and configure the server:
|
||||
|
||||
```bash
|
||||
@@ -161,7 +161,7 @@ for the particular driver or whether it supports parallel sessions.
|
||||
automation, all using the WebDriver model that's already the standard for web automation.
|
||||
5. You can run your automated tests locally and in a cloud. There are multiple cloud providers that
|
||||
support various Appium drivers (mostly targeting iOS and Android mobile automation).
|
||||
6. [Appium Inspector](https://appium.github.io/appium-inspector/) can be used to visually inspect
|
||||
6. [Appium Inspector](https://github.com/appium/appium-inspector) can be used to visually inspect
|
||||
the page source of applications across different platforms, facilitating easier test development.
|
||||
|
||||
Investing in the [WebDriver](https://w3c.github.io/webdriver/webdriver-spec.html) protocol means you
|
||||
|
||||
@@ -61,7 +61,7 @@ cd appium
|
||||
|
||||
!!! info
|
||||
|
||||
If you are VS Code user, you can easily check out the project using [Runme](https://runme.dev/).
|
||||
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).
|
||||
|
||||
Install dependencies:
|
||||
```sh
|
||||
|
||||
@@ -62,33 +62,6 @@ them in `docs`, and add links to these files in `mkdocs.yml`.
|
||||
Refer to the [MkDocs documentation](https://www.mkdocs.org/user-guide/writing-your-docs/) for
|
||||
information on how to organize and structure your documentation.
|
||||
|
||||
### Helping LLMs Use Your Documentation
|
||||
|
||||
The [`/llms.txt` convention](https://llmstxt.org/) is a Markdown file at the root of a
|
||||
documentation site, listing its most useful pages so that large language models can navigate the
|
||||
site without crawling it. Appium's own documentation provides one at
|
||||
[appium.io/docs/en/latest/llms.txt](https://appium.io/docs/en/latest/llms.txt), and you may want to
|
||||
do the same for your extension.
|
||||
|
||||
MkDocs copies any non-Markdown file in your `docs` directory to the built site as-is, so all you
|
||||
need to do is write an `llms.txt` and place it alongside your Markdown files. No plugin or build
|
||||
configuration is required.
|
||||
|
||||
The value of this file lies in the parts a crawler could not have worked out on its own, so it is
|
||||
worth writing by hand rather than generating it from your navigation:
|
||||
|
||||
- A short description of what your extension automates, and which platforms it targets
|
||||
- The handful of things models reliably get wrong about your extension - removed capabilities,
|
||||
renamed commands, patterns from an older major version that no longer apply
|
||||
- Links to the pages that matter, with a description of each
|
||||
|
||||
Because links in `llms.txt` are read out of context, they must be absolute URLs. If you use Mike
|
||||
for versioning, point them at your version alias (for example `latest`) rather than at a pinned
|
||||
version, so that the file does not go stale. Note that a hand-written file can drift as pages are
|
||||
renamed; Appium validates its own with a
|
||||
[script](https://github.com/appium/appium/blob/master/packages/appium/docs/scripts/check-llmstxt.js)
|
||||
that runs in CI, which you are welcome to adapt.
|
||||
|
||||
### Building the Docs
|
||||
|
||||
At this point, you can use the `appium-docs` CLI tool. Run this tool with no arguments to get the
|
||||
|
||||
@@ -80,9 +80,8 @@ The required subfields are:
|
||||
capability to tell Appium to use *your* driver.
|
||||
* `platformNames`: this is an array of one or more platform names considered valid for your driver.
|
||||
When a user sends in the `platformName` capability to start a session, it must be included in
|
||||
this list for your driver to handle the session. These names should generally include the
|
||||
operating systems your driver is targeting - for example, a driver targeting iOS would include
|
||||
`iOS`, while a driver targeting the Chrome browser on Windows would include `Windows`.
|
||||
this list for your driver to handle the session. Known platform name strings include: `iOS`,
|
||||
`tvOS`, `macOS`, `Windows`, `Android`.
|
||||
* `mainClass`: this is a named export (in CommonJS style) from your `main` field. It must be a
|
||||
class which extends Appium's `BaseDriver` (see below).
|
||||
|
||||
@@ -230,16 +229,6 @@ async createSession(w3cCaps) {
|
||||
}
|
||||
```
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Older drivers may still define `createSession` with up to four parameters, e.g.
|
||||
`createSession(jwpCaps, reqCaps, w3cCaps, otherDriverData)`. This shape is a holdover from the
|
||||
retired JSON Wire Protocol, which required desired and required caps as the first two
|
||||
arguments; only the first W3C-shaped argument was ever used. The `otherDriverData` parameter is
|
||||
likewise deprecated in favor of [IPC](#send-messages-to-plugins-running-on-the-same-session) for
|
||||
coordinating with other concurrently-running sessions. New drivers should use the single-argument
|
||||
form shown above.
|
||||
|
||||
You'll want to make sure to call `super.createSession` in order to get the session ID as well as
|
||||
the processed capabilities (note that capabilities are also set on `this.caps`; modifying `caps`
|
||||
locally here would have no effect other than changing what the user sees in the create session
|
||||
@@ -282,8 +271,8 @@ You handle WebDriver commands by implementing functions in your driver class. Ea
|
||||
WebDriver Protocol, plus the various Appium extensions, has a corresponding function that you
|
||||
implement if you want to support that command in your driver. The best way to see which commands
|
||||
Appium supports and which method you need to implement for each command is to look at Appium's
|
||||
[routes/](https://github.com/appium/appium/tree/master/packages/base-driver/lib/protocol/routes).
|
||||
Each route object in this directory's files tells you the command name as well as the parameters you'd expect to
|
||||
[routes.js](https://github.com/appium/appium/blob/master/packages/base-driver/lib/protocol/routes.js).
|
||||
Each route object in this file tells you the command name as well as the parameters you'd expect to
|
||||
receive for that command.
|
||||
|
||||
Let's take this block for example:
|
||||
@@ -324,7 +313,7 @@ Websockets. Implementing handlers for BiDi commands works just the same as imple
|
||||
for WebDriver classic commands (described in the previous section). You simply define a method on
|
||||
your driver of the appropriate name, and it will be called when the BiDi command is requested by
|
||||
the client. To see which specific names you should use for BiDi commands, have a look at
|
||||
[bidi-commands.ts](https://github.com/appium/appium/blob/master/packages/base-driver/lib/protocol/bidi-commands.ts)
|
||||
[bidi-commands.js](https://github.com/appium/appium/blob/master/packages/base-driver/lib/protocol/bidi-commands.js)
|
||||
|
||||
You are not limited to BiDi commands that are defined in the official BiDi specification. If you
|
||||
wish to define new commands, you may do so; you just need to tell Appium about them! See
|
||||
@@ -545,7 +534,7 @@ this.proxyCommand = proxy.command.bind(proxy);
|
||||
Here we are creating a proxy object and assigning some of its methods to `this` under the names
|
||||
`proxyReqRes` and `proxyCommand`. This is required for Appium to use the proxy, so don't forget
|
||||
this step! The `WebDriverProxy` has a variety of other options [which you can check out in the
|
||||
source code as well.](https://github.com/appium/appium/blob/master/packages/base-driver/lib/jsonwp-proxy/proxy.ts)
|
||||
source code as well.](https://github.com/appium/appium/blob/master/packages/base-driver/lib/wd-proxy/proxy.ts)
|
||||
|
||||
Finally, we need a way to tell Appium when the proxy is active. For your driver it might always
|
||||
be active, or it might only be active when in a certain context. You can define the logic as an
|
||||
@@ -725,6 +714,12 @@ A couple notes about this system:
|
||||
mode!
|
||||
1. The `executeMethod` helper will reject with an error if a script name doesn't match one of the
|
||||
script names defined as a command in `executeMethodMap`, or if there are missing parameters.
|
||||
1. If your driver is written in TypeScript, declare the map `as const satisfies
|
||||
ExecuteMethodMap<MyDriver>` (with `ExecuteMethodMap` imported from `@appium/types`). The
|
||||
compiler then checks that each `command` names a method of your driver, and that the
|
||||
`required`/`optional` params are consistent with that method's signature: the method must not
|
||||
require a parameter which is listed as `optional` (or not listed at all), and must accept all
|
||||
of the listed parameters.
|
||||
|
||||
One of the nice things about the Execute Method strategy is that methods implemented in this way
|
||||
will be available via the classic or BiDi interfaces (since they will result in the same Appium
|
||||
@@ -799,50 +794,32 @@ that multiple simultaneous sessions don't use the same resources:
|
||||
|
||||
1. Have your users specify resource IDs via capabilities (`appium:driverPort` etc)
|
||||
1. Just always use free resources (find a new random port for each session)
|
||||
1. Have each driver express what resources it is using, then examine currently-used resources from
|
||||
other drivers when a new session begins.
|
||||
1. Have each running instance of your driver publish and subscribe to messages on a shared IPC
|
||||
channel, so sessions can coordinate directly with one another.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
The `driverData`-based mechanism described below is deprecated. Prefer
|
||||
[IPC](#send-messages-to-plugins-running-on-the-same-session) for coordinating resources across
|
||||
concurrently-running sessions instead.
|
||||
|
||||
To support this third strategy, you can implement `get driverData` in your driver to return what
|
||||
sorts of resources your driver is currently using, for example:
|
||||
|
||||
```js
|
||||
get driverData() {
|
||||
return {specialPort: 1234, specialFile: /path/to/file}
|
||||
}
|
||||
```
|
||||
|
||||
Now, when a new session is started on your driver, the `driverData` response from any other
|
||||
simultaneously running drivers (of the same type) will also be included, as the last parameter of
|
||||
the deprecated, multi-argument form of the `createSession` method:
|
||||
|
||||
```js
|
||||
async createSession(jwpCaps, reqCaps, w3cCaps, driverData)
|
||||
```
|
||||
|
||||
You can dig into this `driverData` array to see what resources other drivers are using to help
|
||||
determine which ones you want to use for this particular session.
|
||||
The per-session IPC channel described in [Send messages to plugins running on the same
|
||||
session](#send-messages-to-plugins-running-on-the-same-session) is isolated per session, so it
|
||||
can't be used for this: it doesn't let you talk to *other* sessions of your driver. Instead,
|
||||
construct and hold on to your own `AppiumIpc` instance (exported from `appium/driver.js`) at
|
||||
module scope in your driver's package, for example as a memoized singleton. Since Node.js caches
|
||||
modules, every instance of your driver loaded within the same Appium server process will share
|
||||
that one `AppiumIpc` object, and can use it to publish and subscribe to topics across sessions —
|
||||
the same way the per-session channel works, just not scoped to a single session. See
|
||||
[xcuitest-driver's `session-claim-handler.ts`](https://github.com/appium/appium-xcuitest-driver/blob/master/lib/session-claim-handler.ts)
|
||||
for a real example, which uses this technique to detect and resolve conflicting sessions targeting
|
||||
the same device UDID.
|
||||
|
||||
!!! warning
|
||||
|
||||
Be careful here, since `driverData` is only passed between sessions of a single running Appium
|
||||
server. There's nothing to stop a user from running multiple Appium servers and requesting your
|
||||
driver simultaneously on each of them. In this case, you won't be able to ensure independence
|
||||
of resources via `driverData`, so you might consider using file-based locking mechanisms or
|
||||
something similar.
|
||||
This only works for sessions running within the same Node.js process (i.e. the same Appium
|
||||
server). It cannot coordinate sessions running on different Appium server processes; for that,
|
||||
consider file-based locking or a similar out-of-process mechanism.
|
||||
|
||||
!!! warning
|
||||
|
||||
It's also important to note you will only receive `driverData` for other instances of *your*
|
||||
driver. So unrelated drivers also running may still be using some system resources. In general
|
||||
Appium doesn't provide any features for ensuring unrelated drivers don't interfere with one
|
||||
another, so it's up to the drivers to allow users to specify resource locations or addresses to
|
||||
avoid clashes.
|
||||
Appium also doesn't provide any features for ensuring unrelated drivers don't interfere with
|
||||
one another, so it's up to the drivers to allow users to specify resource locations or
|
||||
addresses to avoid clashes.
|
||||
|
||||
### Log events to the Appium event timeline
|
||||
|
||||
@@ -990,10 +967,15 @@ export type IpcMessage<T> = {
|
||||
#### IPC Notes
|
||||
|
||||
There are some important things to keep in mind when using Appium's IPC feature:
|
||||
- IPC is only available once `onIpcInit` has been called, at the end of the `createSession` flow.
|
||||
It cannot be used statically or in `createSession` hooks
|
||||
- In sum, IPC is only for use during a session (this is also to prevent drivers/plugins from
|
||||
accessing or reading data sent on IPC channels in other sessions.)
|
||||
- The `ipcSubscribe` method (and the IPC channel it subscribes to) is only available once
|
||||
`onIpcInit` has been called, at the end of the `createSession` flow. It cannot be used statically
|
||||
or in `createSession` hooks
|
||||
- The channel that `ipcSubscribe` gives you access to is scoped to the current session, and is
|
||||
shared only with the plugins active in that same session (this is also to prevent drivers/plugins
|
||||
from accessing or reading data sent on IPC channels in other sessions.) To coordinate across
|
||||
multiple concurrent sessions of your own driver instead, see [Make itself aware of resources
|
||||
other concurrent drivers are
|
||||
using](#make-itself-aware-of-resources-other-concurrent-drivers-are-using).
|
||||
- The default max size of an IPC message is 1MB. This can be configured by the server-admin by
|
||||
using the `--max-ipc-data-size` arg (value is a number in bytes).
|
||||
- If a message exceeds the configured size, any call to `publish` methods will throw, so be
|
||||
|
||||
@@ -257,7 +257,7 @@ throw new errors.NoSuchElementError();
|
||||
### Log messages to the Appium log
|
||||
|
||||
You can always use `console.log`, of course, but Appium provides a nice logger for you as
|
||||
`this.logger` (it has `.info`, `.debug`, `.log`, `.warn`, `.error` methods on it for differing log
|
||||
`this.log` (it has `.info`, `.debug`, `.warn`, `.error` methods on it for differing log
|
||||
levels). If you want to create an Appium logger outside of a plugin context (say in a script or
|
||||
helper file), you can always construct your own too:
|
||||
|
||||
@@ -476,7 +476,7 @@ capability.
|
||||
|
||||
You probably don't normally need to update the Appium server object (which is an
|
||||
[Express](https://expressjs.com/) server having already been
|
||||
[configured](https://github.com/appium/appium/blob/master/packages/base-driver/lib/express/server.ts)
|
||||
[configured](https://github.com/appium/appium/blob/master/packages/http-server/lib/server.ts)
|
||||
in a variety of ways). But, for example, you could add new routes to the server to support your
|
||||
plugin's requirements. To update the server you must implement the `static async updateServer`
|
||||
method in your class. This method takes three parameters:
|
||||
|
||||
@@ -62,7 +62,7 @@ functionality (e.g., the `plugin` or `driver` subcommands).
|
||||
|
||||
Note that this file is the _base_ schema; this will become painfully relevant.
|
||||
|
||||
This file is _not_ a JSON file, because a) JSON is painful to work with for humans, b) is
|
||||
This file is is _not_ a JSON file, because a) JSON is painful to work with for humans, b) is
|
||||
especially reviled by @jlipps, and c) `ajv` accepts objects, not JSON files.
|
||||
|
||||
It is more straightforward to explain how config files are validated, so we'll start there.
|
||||
|
||||
@@ -15,34 +15,34 @@ To learn more about drivers, check out the [Driver Intro](../intro/drivers.md).
|
||||
|
||||
These drivers are currently maintained by the Appium team:
|
||||
|
||||
### [Chromium](https://appium.github.io/appium-chromium-driver/)
|
||||
### [Chromium](https://github.com/appium/appium-chromium-driver)
|
||||
|
||||
* Target: Desktop Chromium-based browsers (Chrome, Microsoft Edge, etc.)
|
||||
* Target: Desktop and mobile Chromium browsers (Chrome, Microsoft Edge, etc.)
|
||||
* Mode: Web
|
||||
|
||||
```sh title="Install This Driver"
|
||||
appium driver install chromium
|
||||
```
|
||||
|
||||
### [Espresso](https://appium.github.io/appium-espresso-driver/)
|
||||
### [Espresso](https://github.com/appium/appium-espresso-driver)
|
||||
|
||||
* Target: Android applications (mobile, TV, Wear, XR, Automotive)
|
||||
* Mode: Native, Hybrid, Web
|
||||
* Target: Android applications
|
||||
* Mode: Native
|
||||
|
||||
```sh title="Install This Driver"
|
||||
appium driver install espresso
|
||||
```
|
||||
|
||||
### [Gecko](https://appium.github.io/appium-geckodriver/)
|
||||
### [Gecko](https://github.com/appium/appium-geckodriver)
|
||||
|
||||
* Target: Desktop and mobile Gecko-based browsers (Firefox, etc.)
|
||||
* Target: Desktop and mobile Gecko browsers (Firefox)
|
||||
* Mode: Web
|
||||
|
||||
```sh title="Install This Driver"
|
||||
appium driver install gecko
|
||||
```
|
||||
|
||||
### [Mac2](https://appium.github.io/appium-mac2-driver/)
|
||||
### [Mac2](https://github.com/appium/appium-mac2-driver)
|
||||
|
||||
* Target: macOS applications
|
||||
* Mode: Native
|
||||
@@ -51,7 +51,7 @@ appium driver install gecko
|
||||
appium driver install mac2
|
||||
```
|
||||
|
||||
### [Safari](https://appium.github.io/appium-safari-driver/)
|
||||
### [Safari](https://github.com/appium/appium-safari-driver)
|
||||
|
||||
* Target: Desktop and mobile Safari browsers
|
||||
* Mode: Web
|
||||
@@ -60,9 +60,9 @@ appium driver install mac2
|
||||
appium driver install safari
|
||||
```
|
||||
|
||||
### [UiAutomator2](https://appium.github.io/appium-uiautomator2-driver/)
|
||||
### [UiAutomator2](https://github.com/appium/appium-uiautomator2-driver)
|
||||
|
||||
* Target: Android applications (mobile, TV, Wear, XR, Automotive)
|
||||
* Target: Android, Android TV, Android Wear applications
|
||||
* Modes: Native, Hybrid, Web
|
||||
|
||||
```sh title="Install This Driver"
|
||||
@@ -85,7 +85,7 @@ appium driver install windows
|
||||
|
||||
### [XCUITest](https://appium.github.io/appium-xcuitest-driver/)
|
||||
|
||||
* Target: iOS, iPadOS, tvOS, watchOS applications
|
||||
* Target: iOS, iPadOS, tvOS applications
|
||||
* Modes: Native, Hybrid, Web
|
||||
|
||||
```sh title="Install This Driver"
|
||||
@@ -161,7 +161,7 @@ appium driver install --source=npm @itsmeaj/appium-linux-driver
|
||||
[Windows driver](#windows)
|
||||
|
||||
* Target: Windows applications
|
||||
* Mode: Native, Hybrid
|
||||
* Mode: Native
|
||||
* Supported by: Community / Automate The Planet
|
||||
|
||||
```sh title="Install This Driver"
|
||||
|
||||
@@ -12,7 +12,7 @@ for more specialised automation workflows.
|
||||
|
||||
## Official Plugins
|
||||
|
||||
These plugins are currently maintained by the Appium team:
|
||||
These plugins are are currently maintained by the Appium team:
|
||||
|
||||
### [Execute Driver](https://github.com/appium/appium/tree/master/packages/execute-driver-plugin)
|
||||
|
||||
|
||||
@@ -104,44 +104,3 @@ Supported by: `@AppiumTestDistribution`
|
||||
```sh title="Install This Tool"
|
||||
npm install -g appium-installer
|
||||
```
|
||||
|
||||
### [Optics](https://github.com/mozarkai/optics-framework)
|
||||
|
||||
Optics is an open-source test automation framework that uses Appium to drive Android, iOS,
|
||||
Android TV, Samsung Tizen and LG webOS apps (and Selenium or Playwright for web). Tests are written
|
||||
as CSV or YAML keyword steps, and the same keywords are available as a Python library, a Robot
|
||||
Framework library, an HTTP API and an MCP server. Element lookup falls back from XPath to visible
|
||||
text, OCR and image matching.
|
||||
|
||||
Supported by: `@chinmayajha`
|
||||
|
||||
```sh title="Install This Tool"
|
||||
pip install "optics-framework[mobile]"
|
||||
```
|
||||
|
||||
### [XPath to Class Chain](https://github.com/domovou69/xpath-to-class-chain)
|
||||
|
||||
XPath to Class Chain is a command-line tool for migrating iOS XPath locators in test code to
|
||||
`-ios class chain` selectors. It converts the XPaths that have an exact class chain equivalent,
|
||||
converts with a warning those that only have a close one (such as grouped positions `(//X)[n]`),
|
||||
and skips the rest with a reason (for example, sibling or parent axes).
|
||||
|
||||
Supported by: `@domovou69`
|
||||
|
||||
```sh title="Install This Tool"
|
||||
npm install -g xpath-to-class-chain
|
||||
```
|
||||
|
||||
### [XPath to UiSelector](https://github.com/domovou69/xpath-to-uiselector)
|
||||
|
||||
XPath to UiSelector is a command-line tool for migrating Android XPath locators in test code to
|
||||
`-android uiautomator` selectors. It converts the XPaths that have an exact `UiSelector`
|
||||
equivalent, converts with a warning those that only have a close one (such as `//A//B`), and skips
|
||||
the rest with a reason. The strategy call is rewritten together with the string, for example
|
||||
`AppiumBy.xpath` becomes `AppiumBy.androidUIAutomator`.
|
||||
|
||||
Supported by: `@domovou69`
|
||||
|
||||
```sh title="Install This Tool"
|
||||
npm install -g xpath-to-uiselector
|
||||
```
|
||||
|
||||
@@ -52,6 +52,6 @@ After the PR is merged there is no need to use the local plugin/driver deploymen
|
||||
to switch back to the package managed by NPM. Follow the next steps for that:
|
||||
|
||||
- Unlink the installed driver/plugin from the server by running `appium driver uninstall <driver_name>` or
|
||||
`appium plugin uninstall <plugin_name>`.
|
||||
`appium plugin uninstall <driver_name>`.
|
||||
- Delete the local source folder (`rm -rf <full_path_to_plugin_or_driver_folder_with_fetched_sources>`).
|
||||
- Install the driver or the plugin from NPM. Check the component README in order to find a proper command for that.
|
||||
|
||||
@@ -8,14 +8,14 @@ principles, so you could create more performant and efficient test suite executi
|
||||
|
||||
## Why Caching Is Necessary
|
||||
|
||||
Mobile application bundles could reach hundreds of megabytes in size. This could become a serious
|
||||
Mobile application bundles could reach hundreds of megabytes is size. This could become a serious
|
||||
performance issue if a test suite is executed, and it is necessary to fetch/extract the same application
|
||||
bundle for each test.
|
||||
|
||||
## What Is Cached
|
||||
|
||||
Caching could be applied to application bundles generated by
|
||||
[`configureApp`](https://github.com/appium/appium/blob/master/packages/base-driver/lib/basedriver/helpers.ts#L99) helper call.
|
||||
[`configureApp`](https://github.com/appium/appium/blob/master/packages/base-driver/lib/basedriver/helpers.js#L107) helper call.
|
||||
Inherited drivers can customize their caching logic by providing own `onPostProcess`
|
||||
(or both `inDownload` and `onPostProcess`) property definition, but the general
|
||||
rule of thumb is that we need to cache locally all application bundles need to be downloaded and/or extracted
|
||||
|
||||
@@ -24,7 +24,7 @@ to launch. In order to achieve this, Appium defines its own [extension capabilit
|
||||
## Common Appium Capabilities
|
||||
|
||||
According to the WebDriver spec, extension capabilities must include a namespace prefix (signifying
|
||||
the vendor introducing the capability), and the namespace must end in a colon (`:`). Appium's vendor
|
||||
the vendor introducing the capability), and the namespace must end a colon (`:`). Appium's vendor
|
||||
prefix is `appium:`, and so any Appium-specific capabilities must include this prefix. Depending on
|
||||
your Appium client, the prefix may be added automatically or in conjunction with certain interfaces,
|
||||
but it is always a good practice to explicitly include it for clarity.
|
||||
|
||||
@@ -34,7 +34,7 @@ discovered and loaded by Appium:
|
||||
- `appium.config.cjs`
|
||||
- `.appiumrc` (which is considered to be JSON)
|
||||
|
||||
Further, _if your project uses Node.js,_ you can store the configuration inside an `appiumConfig`
|
||||
Further, _if your project uses Node.js,_ you can use store the configuration inside an `appium`
|
||||
property in your `package.json` and it will be automatically discovered.
|
||||
|
||||
### Config File Search
|
||||
|
||||
@@ -6,17 +6,16 @@ title: Retrieving Event Timings
|
||||
---
|
||||
|
||||
Appium comes with the ability to retrieve timing information about startup
|
||||
information and command length. This is an advanced feature; the server records
|
||||
event timings for every session.
|
||||
information and command length. This is an advanced feature; event and
|
||||
command timings are collected automatically for the duration of a session.
|
||||
|
||||
The timings can be retrieved at any point during a session via the
|
||||
`POST /session/:id/appium/events` endpoint (i.e., the response to
|
||||
`driver.logs.events` or similar, depending on client). The response body is the
|
||||
event history object itself. This is its structure:
|
||||
The `POST /session/:id/appium/events` response (i.e., the response to
|
||||
`driver.logs.events` or similar, depending on client) has the following
|
||||
structure:
|
||||
|
||||
```
|
||||
{
|
||||
"<event_type>": [<occurrence_timestamp_1>, ...],
|
||||
"<event_type>": [<occurence_timestamp_1>, ...],
|
||||
"commands": [
|
||||
{
|
||||
"cmd": "<command_name>",
|
||||
@@ -28,7 +27,7 @@ event history object itself. This is its structure:
|
||||
}
|
||||
```
|
||||
|
||||
In other words, the event history object has 2 kinds of properties of its own:
|
||||
In other words, the `events` property has 2 kinds of properties of its own:
|
||||
|
||||
* Properties which are the names of event types
|
||||
* The `commands` property
|
||||
@@ -62,9 +61,7 @@ generate various kinds of reports from event timings output:
|
||||
|
||||
!!! note
|
||||
|
||||
In the past, when the `appium:eventTimings` capability was set to `true`, the event history
|
||||
was also returned as an `events` property of the (now deprecated) `GET /session/:id`
|
||||
response
|
||||
In the past, events were available as a part of `GET /session/:id` response
|
||||
|
||||
## Add a custom event
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ by client libraries. There are two main strategies for this:
|
||||
based client library (including all Selenium and Appium clients).
|
||||
|
||||
There are pros and cons for each strategy, but it is ultimately up to the extension author to
|
||||
decide how they wish to implement new commands.
|
||||
decide how they wish implement new commands.
|
||||
|
||||
This guide is designed to specifically help you understand the "Execute Method" strategy. This
|
||||
pattern is commonly used in official Appium drivers and other third-party extensions.
|
||||
@@ -67,7 +67,7 @@ function, but the function itself—the snippet—is always a string and is the
|
||||
In the world of Appium, we are usually not automating a web browser, which means this command is
|
||||
not particularly useful. But it *is* useful as a way to encode the name of an arbitrary command and
|
||||
to provide parameters. For example, the [XCUITest
|
||||
Driver](https://appium.github.io/appium-xcuitest-driver/) has implemented a command that lets a client
|
||||
Driver](https://github.com/appium/appium-xcuitest-driver) has implemented a command that lets a client
|
||||
terminate a running application if you know the ID (the `bundleId`) of the app. The way that the
|
||||
driver makes this command available is via the Execute Method `mobile: terminateApp`. Instead of
|
||||
providing a JavaScript function to the "Execute Script" command, the user provides a _known string_
|
||||
|
||||
@@ -117,62 +117,3 @@ hub, you'll be able to send all your Appium traffic via the single hub endpoint
|
||||
|
||||
And of course, you're able to link up Appium servers and nodes running on different machines in
|
||||
your network to form a larger grid.
|
||||
|
||||
## Using Selenium Grid 3
|
||||
|
||||
It is possible to register your Appium server with a local [Selenium Grid 3](https://www.selenium.dev/documentation/legacy/selenium_3/grid_3/)
|
||||
([setup docs](https://www.selenium.dev/documentation/legacy/grid_3/setting_up_your_own_grid/)) instance by using the
|
||||
`--nodeconfig` server argument.
|
||||
|
||||
```bash
|
||||
appium server --nodeconfig /path/to/nodeconfig.json --base-path=/wd/hub
|
||||
```
|
||||
|
||||
In the referenced config file you have to define the `browserName`, `version` and `platform`
|
||||
capabilities and based on these parameters the grid will re-direct your test to the right device.
|
||||
You will also need to configure your host details and the Selenium Grid details. For a full list of
|
||||
all parameters and descriptions see
|
||||
[here](https://www.selenium.dev/documentation/legacy/selenium_3/grid_setup/).
|
||||
|
||||
Once you start the Appium server it will register with the grid, and you will see your device on
|
||||
the grid console page:
|
||||
|
||||
`http://**\<grid-ip-address\>**:**\<grid-port\>**/grid/console`
|
||||
|
||||
### Example Grid Node Configuration JSON
|
||||
|
||||
```json
|
||||
{
|
||||
"capabilities":
|
||||
[
|
||||
{
|
||||
"browserName": "<e.g._iPhone5_or_iPad4>",
|
||||
"version":"<version_of_iOS_e.g._7.1>",
|
||||
"maxInstances": 1,
|
||||
"platform":"<platform_e.g._MAC_or_ANDROID>"
|
||||
}
|
||||
],
|
||||
"configuration":
|
||||
{
|
||||
"cleanUpCycle":2000,
|
||||
"timeout":30000,
|
||||
"proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
|
||||
"url":"http://<host_name_appium_server_or_ip-address_appium_server>:<appium_port>/wd/hub",
|
||||
"host": "<host_name_appium_server_or_ip-address_appium_server>",
|
||||
"port": <appium_port>,
|
||||
"maxSession": 1,
|
||||
"register": true,
|
||||
"registerCycle": 5000,
|
||||
"hubPort": <grid_port>,
|
||||
"hubHost": "<Grid_host_name_or_grid_ip-address>",
|
||||
"hubProtocol": "<Protocol_of_Grid_defaults_to_http>"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
If `url`, `host`, and `port` are not given, the config will be auto updated to point to
|
||||
`localhost:<appium-port>`.
|
||||
|
||||
If your Appium server is running on a different machine to your Selenium Grid server, make sure you
|
||||
use an external name/IP address in your `host` and `url` configuration; `localhost` and `127.0.0.1`
|
||||
will prevent Selenium Grid from connecting correctly.
|
||||
|
||||
@@ -18,11 +18,8 @@ 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 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`.
|
||||
- `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.
|
||||
- `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.
|
||||
|
||||
@@ -25,7 +25,7 @@ appium driver install xcuitest
|
||||
```
|
||||
|
||||
This command will install the latest version of the
|
||||
[XCUITest Driver](https://appium.github.io/appium-xcuitest-driver/). The Extension CLI comes with a variety
|
||||
[XCUITest Driver](https://github.com/appium/appium-xcuitest-driver). The Extension CLI comes with a variety
|
||||
of commands and parameters; see the documentation for that command for all the specifics.
|
||||
|
||||
The all-important question when Appium is managing your extensions for you is: where are they installed?
|
||||
@@ -63,7 +63,7 @@ like any other dependency. Basically, whenever you run Appium, if you have not e
|
||||
1. Try to determine whether the _current directory_ is inside an `npm` package.
|
||||
1. If so, it will check whether `appium` is a dependency (dev, prod, or peer) in the project's
|
||||
`package.json`
|
||||
1. If so, _unless you have specified `APPIUM_HOME` in your environment_, Appium will load
|
||||
1. If so, _unless you have specified `APPIUM_HOME` in your environment_, Appium will ignore load
|
||||
drivers and plugins defined in that `package.json` file instead.
|
||||
|
||||
This means you are freely able to add Appium drivers and plugins as regular package dependencies or
|
||||
|
||||
@@ -31,10 +31,6 @@ installing it only installs the core Appium server, without any drivers.
|
||||
|
||||
When it comes to installing Appium 2 drivers, there are several approaches you can take:
|
||||
|
||||
* Add the `--drivers` flag when installing Appium, for example:
|
||||
```bash
|
||||
npm i -g appium --drivers=xcuitest,uiautomator2
|
||||
```
|
||||
* Use the [Appium Extension CLI](../reference/cli/extensions.md), for example:
|
||||
```bash
|
||||
appium driver install uiautomator2
|
||||
@@ -106,10 +102,10 @@ and it is recommended to migrate to the following replacements:
|
||||
|
||||
|Appium 1 Package|Replacement in Appium 2|
|
||||
|--|--|
|
||||
|iOS Driver|[XCUITest Driver](https://appium.github.io/appium-xcuitest-driver/)|
|
||||
|UiAutomator Driver|[UiAutomator2](https://appium.github.io/appium-uiautomator2-driver/)|
|
||||
|iOS Driver|[XCUITest Driver](https://appium.github.io/appium-xcuitest-driver/latest/)|
|
||||
|UiAutomator Driver|[UiAutomator2](https://github.com/appium/appium-uiautomator2-driver/)|
|
||||
|`wd` Client|[WebdriverIO Client](https://webdriver.io/)|
|
||||
|Appium Desktop|[Appium Inspector](https://appium.github.io/appium-inspector/)|
|
||||
|Appium Desktop|[Appium Inspector](https://github.com/appium/appium-inspector)|
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
|
||||
@@ -148,9 +148,9 @@ Icons are used to indicate endpoint support in either certain drivers, or in the
|
||||
|
||||
- :simple-appium:{ .lg } - Appium server
|
||||
- :material-apple:{ .lg } - [XCUITest driver](https://appium.github.io/appium-xcuitest-driver/latest/)
|
||||
- :material-android:{ .lg } - [UiAutomator2 driver](https://appium.github.io/appium-uiautomator2-driver/)
|
||||
- :material-coffee:{ .lg } - [Espresso driver](https://appium.github.io/appium-espresso-driver/)
|
||||
- :material-apple-finder:{ .lg } - [Mac2 driver](https://appium.github.io/appium-mac2-driver/)
|
||||
- :material-android:{ .lg } - [UiAutomator2 driver](https://github.com/appium/appium-uiautomator2-driver/)
|
||||
- :material-coffee:{ .lg } - [Espresso driver](https://github.com/appium/appium-espresso-driver)
|
||||
- :material-apple-finder:{ .lg } - [Mac2 driver](https://github.com/appium/appium-mac2-driver)
|
||||
- :material-microsoft-windows:{ .lg } - [Windows driver](https://github.com/appium/appium-windows-driver)
|
||||
|
||||
</div>
|
||||
@@ -454,6 +454,9 @@ longer accepts, as well as the parameters it continues to accept in Appium 3.
|
||||
* `POST /session/:sessionId/element/:elementId/value`
|
||||
* :octicons-x-24: `value`
|
||||
* :octicons-check-24: `text`
|
||||
* `POST /session/:sessionId/timeouts`
|
||||
* :octicons-x-24: `type`, `ms`
|
||||
* :octicons-check-24: `script`, `pageLoad`, `implicit`
|
||||
* `POST /session/:sessionId/window`
|
||||
* :octicons-x-24: `name`
|
||||
* :octicons-check-24: `handle`
|
||||
|
||||
@@ -0,0 +1,294 @@
|
||||
---
|
||||
title: Migrating to Appium 4
|
||||
---
|
||||
<style>
|
||||
.md-typeset .grid {
|
||||
grid-template-columns: repeat(auto-fit,minmax(min(100%,11rem),1fr));
|
||||
}
|
||||
</style>
|
||||
|
||||
This document is a guide for those who are using Appium 3 and would like to upgrade to Appium 4.
|
||||
It contains a list of breaking changes, as well as suggestions for handling them.
|
||||
|
||||
Appium 4 focuses on modernizing the codebase (Node.js requirements, ESM-only packages, dropping
|
||||
long-deprecated protocol support and APIs) rather than introducing a large number of new
|
||||
user-facing features. Most Appium users only need to check the [Node.js version](#node-2222-required)
|
||||
section below; the remaining breaking changes mostly affect driver and plugin developers, or users
|
||||
of specific removed flags/endpoints.
|
||||
|
||||
## Installation
|
||||
|
||||
Appium 4 is currently only available as a beta release, published under the `beta` npm dist-tag.
|
||||
The installation method otherwise remains the same as for Appium 3. If you want to upgrade, you
|
||||
can simply install Appium 4 on top of your existing installation:
|
||||
|
||||
```bash
|
||||
# optional: `appium setup reset`
|
||||
npm install -g appium@beta
|
||||
```
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
### Node 22.22+ Required
|
||||
|
||||
Appium 3 required Node `^20.19.0 || ^22.12.0 || >=24.0.0`. Appium 4 drops Node 20 support and
|
||||
bumps the minimum required version to `^22.22.2 || ^24.15.0 || >=26.0.0`.
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
Upgrade Node.js to `v22.22.2`/`v24.15.0` or newer
|
||||
|
||||
### All Packages Are Now ESM-Only
|
||||
|
||||
Every `@appium/*` package (and `appium` itself) is now published as `"type": "module"` with no
|
||||
CommonJS build. `require()` no longer works for these packages. This affects anyone importing
|
||||
Appium or a driver/plugin package directly from Node.js code, not just driver/plugin developers.
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
Import Appium packages with ESM `import` syntax, or use dynamic `import()` from CommonJS code
|
||||
|
||||
### `--nodeconfig` Flag Removed
|
||||
|
||||
Support for registering with a legacy Selenium Grid 3 hub has been removed, along with the
|
||||
`--nodeconfig` server argument and the `server.nodeconfig` config file property.
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
If you relied on Grid 3 registration, use the [Selenium Grid 4 relay feature](./grid.md) instead
|
||||
|
||||
### `--allow-cors` Flag Removed
|
||||
|
||||
CORS is now gated behind the same [insecure feature](./security.md) mechanism used for other
|
||||
server-level features (e.g. `session_discovery`), instead of its own dedicated flag.
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
Replace `--allow-cors` with `--allow-insecure=*:cors` (or enable it via `--relaxed-security`)
|
||||
|
||||
### Extension Auto-Install on `npm install` Removed
|
||||
|
||||
The `npm install -g appium --drivers=... --plugins=...` postinstall hook that automatically
|
||||
installed extensions has been removed, since npm postinstall hooks are a supply-chain security
|
||||
risk and newer npm versions no longer support passing custom arguments to them.
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
Use `appium driver install`/`appium plugin install`, or declare extensions in your project's
|
||||
`package.json`, instead of `--drivers`/`--plugins` install-time arguments
|
||||
|
||||
### Default Log Level Changed to `info`
|
||||
|
||||
The default `--log-level` changed from `debug` to `info`. Debug-level logging is very verbose and
|
||||
mostly only useful for troubleshooting.
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
Pass `--log-level debug` explicitly if you rely on the previous verbosity
|
||||
|
||||
### CLI Output Streams Split
|
||||
|
||||
Appium's CLI commands (`driver`/`plugin install|list|update`, `doctor`, etc.) used to write all
|
||||
non-JSON output to `STDERR`. Human-readable output (`log`/`ok`/`info`/`warn`) now goes to
|
||||
`STDOUT`; only `error` output still goes to `STDERR`. The main server's log output (Winston-based)
|
||||
is unaffected, since it already split streams this way.
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
If you have scripts that capture Appium CLI output, make sure they read from the correct stream
|
||||
|
||||
### TLS Server No Longer Negotiates SPDY/HTTP2
|
||||
|
||||
Appium's TLS-enabled server used the unmaintained `spdy` package, which allowed negotiating
|
||||
SPDY/HTTP2 over ALPN. It has been replaced with Node's native `https` module, which only serves
|
||||
plain HTTPS (HTTP/1.1).
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
Clients relying on SPDY or HTTP/2 multiplexing against Appium's TLS listener must switch to
|
||||
plain HTTPS (HTTP/1.1)
|
||||
|
||||
### Timeout Errors Now Return HTTP 500
|
||||
|
||||
Per the W3C WebDriver standard, `TimeoutError` and `ScriptTimeoutError` now map to HTTP `500`
|
||||
instead of `408`. The stale `408` mapping could cause keep-alive clients/proxies to auto-retry an
|
||||
already-executed timed-out command.
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
None, unless your code inspects the raw HTTP status code of a timeout response
|
||||
|
||||
### Timeouts Endpoint Aligned With W3C Standard
|
||||
|
||||
`GET/SET /timeouts` is now closer to [the W3C standard](https://w3c.github.io/webdriver/#timeouts):
|
||||
|
||||
* `POST /session/:sessionId/timeouts` now also accepts the standard `command` parameter; the
|
||||
legacy `type`/`ms` parameters are deprecated
|
||||
* `POST /session/:sessionId/timeouts` no longer errors out when none of `script`/`pageLoad`/`implicit`
|
||||
are provided
|
||||
* `GET /session/:sessionId/timeouts` now also returns `script` and `pageLoad`, in addition to the
|
||||
existing `implicit` and Appium-specific `command` values
|
||||
* Driver-level `timeouts()`/`ISessionHandler` type declarations narrow `implicit` to a `number`,
|
||||
matching `script`/`pageLoad` (the wire endpoint still coerces numeric strings at runtime)
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
Update any code that sends the `type`/`ms` timeout parameters or a `string` value for `implicit`
|
||||
|
||||
### BiDi Commands No Longer Accept Stray `sessionId`/`id` Params
|
||||
|
||||
Unlike HTTP endpoints, WebDriver BiDi commands have no URL-derived session/element id, so a stray
|
||||
`sessionId` or `id` key inside BiDi command params is no longer silently accepted; it is now
|
||||
validated like any other unknown parameter.
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
Remove `sessionId`/`id` from the parameters of any custom BiDi command invocation
|
||||
|
||||
## Endpoint Changes
|
||||
|
||||
The following endpoints have been removed:
|
||||
|
||||
* `GET/POST /session/:sessionId/ime/*` (all IME endpoints, legacy JSONWP)
|
||||
* `GET /session/:sessionId/location`, `POST /session/:sessionId/location` (legacy geolocation, legacy JSONWP)
|
||||
* `GET /session/:sessionId/network_connection`, `POST /session/:sessionId/network_connection` (legacy MJSONWP)
|
||||
* `POST /session/:sessionId/receive_async_response` (legacy JSONWP)
|
||||
* `GET /session/:sessionId/element/:elementId` (undocumented legacy JSONWP stub)
|
||||
* `GET /session/:sessionId` (deprecated `getSession`; see [below](#getsession-command-removed) for
|
||||
its replacement)
|
||||
|
||||
The `orientation`, `context`/`contexts`, and `rotation` deprecated endpoints are unaffected and
|
||||
remain available.
|
||||
|
||||
## Changes for Driver and Plugin Developers
|
||||
|
||||
The following changes primarily affect authors of Appium drivers, plugins, or tools that import
|
||||
Appium's internal packages directly (`@appium/base-driver`, `@appium/base-plugin`,
|
||||
`@appium/support`, `@appium/logger`). They do not affect most Appium end users.
|
||||
|
||||
### Remaining Legacy (M)JSONWP Support Removed From `@appium/base-driver`
|
||||
|
||||
Beyond the removed endpoints above, the internal machinery that translated between the legacy
|
||||
(M)JSONWP protocol and W3C WebDriver has been removed:
|
||||
|
||||
* `ProtocolError` instances no longer carry a `jsonwpCode` property, and error responses no longer
|
||||
include a legacy numeric `status` code (`errorFromMJSONWPStatusCode`, aliased as `errorFromCode`,
|
||||
has been removed; use `errorFromW3CJsonCode`)
|
||||
* Responses no longer duplicate element references under the legacy `ELEMENT` key; only the W3C
|
||||
`element-6066-11e4-a52e-4f735466cecf` key is present
|
||||
* `WebDriverProxy` (formerly `JWProxy`, now removed as a name) no longer converts responses from a
|
||||
downstream automation server speaking legacy MJSONWP; downstream servers must speak W3C WebDriver
|
||||
* `determineProtocol`, `DriverCore#setProtocolMJSONWP()`, and `DriverCore#isMjsonwpProtocol()` have
|
||||
been removed; drivers can no longer produce the legacy `{sessionId, status, value}` response shape
|
||||
* `@appium/base-driver` no longer exports `statusCodes`/`getSummaryByCode` (the `jsonwp-status`
|
||||
module was removed)
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
Ensure any downstream automation server a driver proxies to (via `WebDriverProxy`) speaks pure
|
||||
W3C WebDriver; update code referencing the removed exports to their W3C equivalents
|
||||
|
||||
### `@appium/base-driver` Default Export Removed
|
||||
|
||||
`BaseDriver` is no longer exported as `@appium/base-driver`'s default export, and
|
||||
`basedriver/helpers.js`'s default export has been removed as well. `BaseDriver`'s constructor no
|
||||
longer takes command-mixin machinery into account, and the unused `BaseDriver.reset()` method has
|
||||
been removed.
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
Replace `import BaseDriver from '@appium/base-driver'` with `import {BaseDriver} from '@appium/base-driver'`
|
||||
|
||||
### `@appium/base-plugin` Default Export and Legacy Logger Removed
|
||||
|
||||
`BasePlugin` is no longer the default export of `@appium/base-plugin`. `Plugin#logger` has been
|
||||
removed in favor of `Plugin#log`, and `Plugin#name`/`Plugin#cliArgs` are now read-only.
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
* Replace `import BasePlugin from '@appium/base-plugin'` with `import {BasePlugin} from '@appium/base-plugin'`
|
||||
* Replace `this.logger` with `this.log` in plugin code
|
||||
|
||||
### `@appium/logger` Default Export and Dead APIs Removed
|
||||
|
||||
`@appium/logger` and `@appium/support` no longer export a default `log`. `AppiumLogger#errorAndThrow`
|
||||
has been removed in favor of `errorWithException`. The long-disabled, no-op progress/unicode
|
||||
methods (`enableProgress`, `disableProgress`, `progressEnabled`, `enableUnicode`, `disableUnicode`)
|
||||
have also been removed.
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
* Import the named `log` export instead of the default export
|
||||
* Replace `errorAndThrow` calls with `errorWithException`
|
||||
|
||||
### `driverData` Mechanism Removed
|
||||
|
||||
The deprecated `driverData` mechanism (`Core.driverData`, the `driverData` parameter on
|
||||
`createSession`/`deleteSession`, and the `DriverData` type) has been removed, superseded by
|
||||
`IAppiumIpc`.
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
Drivers overriding `get driverData()` or relying on it for cross-session coordination need to
|
||||
migrate to `IAppiumIpc`
|
||||
|
||||
### `createSession` Multi-Argument Overload Removed
|
||||
|
||||
`createSession` no longer accepts the legacy multi-argument form
|
||||
(`createSession(jwpCaps, reqCaps, w3cCaps)`), a holdover from JSONWP. Only the single
|
||||
`w3cCapabilities` argument is supported now.
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
Update any driver or plugin overriding `createSession` to use the single-argument signature
|
||||
|
||||
### `getSession` Command Removed
|
||||
|
||||
`BaseDriver.getSession` and `ISessionHandler.getSession` have been removed (see [Endpoint
|
||||
Changes](#endpoint-changes) for the removed route), along with the `appium:eventTimings`
|
||||
capability that controlled whether its response included event history.
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
Use `GET /session/:sessionId/appium/capabilities` to retrieve session capabilities, and
|
||||
`POST /session/:sessionId/appium/events` to retrieve event history (now returned unconditionally)
|
||||
|
||||
### `@appium/support` Deprecated APIs Removed
|
||||
|
||||
The following `@appium/support` exports have been removed: `process` (`getProcessIds`,
|
||||
`killProcess`), `mkdirp`, `imageUtil` (`requireSharp`, `cropBase64Image`), `mjpeg` (`MJpegStream`),
|
||||
`net`'s FTP upload support, `util`'s `uuidV1`/`uuidV3`/`uuidV5`/`localIp`/`cancellableDelay`/`multiResolve`,
|
||||
`fs`'s `readPackageJsonFrom`/`findRoot`/`F_OK`/`R_OK`/`W_OK`/`X_OK`, `npm`/`NPM` (moved into the
|
||||
`appium` package), and `env` (moved into the `appium` package). `node.requirePackage()` and
|
||||
`system.macOsxVersion()` have also been removed. `fs.glob()` is now backed by Node's native
|
||||
`fs.promises.glob` instead of the `glob` package, with a narrower `GlobOptions` shape.
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
None for typical drivers/plugins, which don't use these low-level helpers directly. If you do,
|
||||
switch to the suggested replacement or a native Node.js API
|
||||
|
||||
### Legacy Test Pages Removed From `@appium/base-driver`
|
||||
|
||||
The built-in test fixture routes (`/welcome`, `/test/guinea-pig*`, `/produce_error`, `/crash`),
|
||||
the `STATIC_DIR` export, and the `APPIUM_ENABLE_LEGACY_TEST_PAGES` environment variable have been
|
||||
removed.
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
Driver test suites that relied on these fixtures should host their own local test server
|
||||
|
||||
## New Features
|
||||
|
||||
* [`--app-url-rules`](./security.md#restricting-remote-app-urls) lets server operators restrict
|
||||
which hosts/IPs an `appium:app` URL is allowed to be downloaded from (allow/deny lists, HTTPS-only,
|
||||
credentials, redirect limits)
|
||||
* Definitions for all current [WebDriver BiDi](https://w3c.github.io/webdriver-bidi/) commands are
|
||||
now included for introspection/validation purposes
|
||||
* `ExecuteMethodMap` type declarations now check `params` against the target method's signature at
|
||||
compile time, catching mismatched required/optional execute method parameters in driver code
|
||||
* Extension manifests and `extensions.yaml` are now validated with `ajv`/JSON Schema; a corrupted
|
||||
`extensions.yaml` now resets to an empty manifest with a warning instead of crashing later with a
|
||||
confusing error
|
||||
* `appium driver`/`appium plugin` CLI commands now lock the extension manifest while running,
|
||||
preventing concurrent processes from silently clobbering each other's changes
|
||||
@@ -85,3 +85,118 @@ Turn on multiple insecure features for specific drivers:
|
||||
```bash
|
||||
appium --allow-insecure=uiautomator2:adb_shell,xcuitest:get_server_logs
|
||||
```
|
||||
|
||||
## Restricting Remote App URLs
|
||||
|
||||
Several drivers accept a URL instead of a local path in capabilities such as `appium:app`, in which
|
||||
case the Appium server downloads the application package from that URL before starting the session.
|
||||
By default, any `http:` or `https:` URL is accepted. Server hosts who want to control which URLs
|
||||
their server is allowed to download from can do so with the `--app-url-rules` argument (or the
|
||||
`server.app-url-rules` property in a [configuration file](./config.md)). Its value is a JSON object
|
||||
(or a path to a JSON file) with any of the following properties:
|
||||
|
||||
|<div style="width:10em">Rule</div>|Description|Default|
|
||||
|----------------------------------|-----------|-------|
|
||||
|`allow`|List of hostname patterns, IP addresses, or CIDR subnets. If non-empty, a hostname or its resolved address must match _at least one_|`[]`|
|
||||
|`deny`|List of hostname patterns, IP addresses, or CIDR subnets. A matching hostname or resolved address is rejected, even if an `allow` rule also matches|`[]`|
|
||||
|`httpsOnly`|Only accept `https:` URLs|`false`|
|
||||
|`allowCredentials`|Accept URLs containing a username and/or password (e.g. `https://user:pass@host/app.apk`)|`true`|
|
||||
|`maxRedirects`|Maximum number of HTTP redirects to follow while downloading. Set to `0` to reject any redirect|`21`|
|
||||
|
||||
Hostnames are normalized (lowercased, converted to Punycode, trailing dot removed) before matching
|
||||
and resolved on every download. Address rules apply to literal addresses and all dynamically
|
||||
resolved IPv4/IPv6 addresses. The rules are also applied to every redirect, so redirects cannot be
|
||||
used to escape them. If a URL violates any rule, the session is not created and a generic error
|
||||
is returned. The violated rule is deliberately neither reported to the client nor written to the
|
||||
server log, since server logs are often handed over to clients as well. URL schemes, ports, paths,
|
||||
queries, and fragments are not matched.
|
||||
|
||||
Hostname patterns use the [picomatch](https://github.com/micromatch/picomatch#globbing-features)
|
||||
glob syntax and are matched against the whole hostname:
|
||||
|
||||
|Pattern|Matches|
|
||||
|-------|-------|
|
||||
|`artifacts.example.com`|Exactly this hostname|
|
||||
|`*.example.com`|Any subdomain of `example.com` (including nested ones, like `a.b.example.com`), but not `example.com` itself|
|
||||
|`*example.com`|Any hostname ending with `example.com`, including `example.com` itself|
|
||||
|`apps.{staging,prod}.example.com`|`apps.staging.example.com` and `apps.prod.example.com`|
|
||||
|`build-?.example.com`|`build-1.example.com`, `build-a.example.com`, etc.|
|
||||
|`node[0-9].example.com`|`node0.example.com` to `node9.example.com`|
|
||||
|
||||
IP address rules match a single address (`192.0.2.10`, `2001:db8::1`) or a whole subnet in CIDR
|
||||
notation (`10.0.0.0/8`, `2001:db8::/32`). IPv4 rules also match IPv4-mapped IPv6 addresses
|
||||
(e.g. `::ffff:10.1.2.3`).
|
||||
|
||||
!!! note
|
||||
|
||||
These rules only apply to URLs the server downloads via the standard app configuration helper,
|
||||
which is used for `appium:app` and similar capabilities by all official drivers. Drivers may
|
||||
define custom capabilities with URLs that are processed differently and thus are not covered.
|
||||
|
||||
!!! note
|
||||
|
||||
If the server downloads applications through an HTTP proxy (configured via the `HTTP_PROXY`,
|
||||
`HTTPS_PROXY` and `NO_PROXY` environment variables), the proxy resolves the destination host
|
||||
itself, so rules containing IP addresses or subnets cannot be enforced for proxied downloads.
|
||||
Such downloads are rejected; either exclude the download hosts from proxying via `NO_PROXY`
|
||||
or only use hostname-based rules.
|
||||
|
||||
### Examples
|
||||
|
||||
Only allow HTTPS downloads from an internal artifact server, without credentials in the URL and
|
||||
without following redirects:
|
||||
|
||||
```bash
|
||||
appium --app-url-rules='{"allow": ["artifacts.example.com", "10.0.0.0/8"], "httpsOnly": true, "allowCredentials": false, "maxRedirects": 0}'
|
||||
```
|
||||
|
||||
The same configuration as part of a config file:
|
||||
|
||||
```yaml
|
||||
server:
|
||||
app-url-rules:
|
||||
allow:
|
||||
- 'artifacts.example.com'
|
||||
- '10.0.0.0/8'
|
||||
httpsOnly: true
|
||||
allowCredentials: false
|
||||
maxRedirects: 0
|
||||
```
|
||||
|
||||
Allow downloads from any subdomain of `example.com` and from two IPv6 subnets, except from the
|
||||
staging environment:
|
||||
|
||||
```yaml
|
||||
server:
|
||||
app-url-rules:
|
||||
allow:
|
||||
- '*.example.com'
|
||||
- '2001:db8:1::/48'
|
||||
- '2001:db8:2::/48'
|
||||
deny:
|
||||
- '*.staging.example.com'
|
||||
```
|
||||
|
||||
Allow downloads from anywhere, except from the server itself, private networks, link-local
|
||||
addresses (such as cloud metadata services), and any `.internal` hostname:
|
||||
|
||||
```yaml
|
||||
server:
|
||||
app-url-rules:
|
||||
deny:
|
||||
- 'localhost'
|
||||
- '*.internal'
|
||||
- '127.0.0.0/8'
|
||||
- '10.0.0.0/8'
|
||||
- '172.16.0.0/12'
|
||||
- '192.168.0.0/16'
|
||||
- '169.254.0.0/16'
|
||||
- '::1/128'
|
||||
- 'fc00::/7'
|
||||
- 'fe80::/10'
|
||||
```
|
||||
|
||||
The rules in the last example are applied to the addresses each hostname resolves to, so they
|
||||
cannot be bypassed via DNS. Note that the `deny` list also blocks any download from the server's
|
||||
own private network, so a private artifact server must be excluded from the `deny` rules in order
|
||||
to work.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
hide:
|
||||
- toc
|
||||
|
||||
title: SSL/TLS/SPDY Support
|
||||
title: SSL/TLS Support
|
||||
---
|
||||
|
||||
Appium 2.2 introduces the option to start the Appium server with SSL/TLS support.
|
||||
@@ -19,15 +19,14 @@ Both arguments must be provided and should contain paths to a valid
|
||||
[X509 PEM](https://www.ssl.com/guide/pem-der-crt-and-cer-x-509-encodings-and-conversions/)
|
||||
certificate and its corresponding private key.
|
||||
|
||||
After the server is started use the `https` protocol and a client supporting SSL/TLS or
|
||||
[SPDY](https://en.wikipedia.org/wiki/SPDY) to communicate to it.
|
||||
After the server is started use the `https` protocol and a client supporting SSL/TLS to
|
||||
communicate to it.
|
||||
|
||||
### Supported Features
|
||||
|
||||
Once a secure server socket is established it supports the following protocols:
|
||||
`['h2', 'spdy/3.1', 'spdy/3', 'spdy/2', 'http/1.1', 'http/1.0']`. See
|
||||
[the SPDY node module documentation](https://www.npmjs.com/package/spdy) to get more details about
|
||||
its features. All insecure client connections will be rejected by the server.
|
||||
Once a secure server socket is established it uses Node.js' native
|
||||
[`https`](https://nodejs.org/api/https.html) module to serve connections. All insecure client
|
||||
connections will be rejected by the server.
|
||||
|
||||
### Self-Signed Certificates
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ a driver does this by relying on platform-specific automation technologies. For
|
||||
maintains an iOS automation technology called
|
||||
[XCUITest](https://developer.apple.com/documentation/xctest/user_interface_tests). The Appium
|
||||
driver that supports iOS app automation is called the [XCUITest
|
||||
Driver](https://appium.github.io/appium-xcuitest-driver/) because ultimately what it does is
|
||||
Driver](https://github.com/appium/appium-xcuitest-driver) because ultimately what it does is
|
||||
convert the WebDriver protocol to XCUITest library calls.
|
||||
|
||||
One of the reasons that drivers are independent, pluggable modules is that they work completely
|
||||
|
||||
@@ -39,6 +39,16 @@ So, for example, the `Find Element` command corresponds to an HTTP `POST` reques
|
||||
endpoint `/session/:sessionid/element` (where in this case, `:sessionid` is a placeholder for the
|
||||
unique session ID generated by the server in a previous call to `Create Session`).
|
||||
|
||||
If the client disconnects before Appium finishes sending a `Create Session` response and the
|
||||
request has no `X-Idempotency-Key`, Appium deletes the new session once driver setup completes.
|
||||
Setup is not interrupted. With an accepted idempotency key, a retry that arrives before setup
|
||||
finishes waits for the same session ID, or the same error if setup failed. If the original client
|
||||
and all waiting retries disconnect before setup finishes, Appium deletes the new session and
|
||||
discards its cached result; a later retry starts a new session. Otherwise, Appium keeps the session
|
||||
and caches its response for replay while it remains in the bounded, in-memory idempotency cache.
|
||||
Disconnecting after a response was sent, or during a command in an existing session, does not
|
||||
automatically end that session. Use `Delete Session` when you are done.
|
||||
|
||||
This information is primarily useful for people developing technology that works with the WebDriver
|
||||
spec. It's not particularly useful for people trying to write Appium or Selenium tests. When you
|
||||
write an Appium test, you want to use a programming language you're familiar with. Luckily, there
|
||||
|
||||
@@ -19,7 +19,7 @@ Appium, called `BaseDriver`. You could have something very close to a "working"
|
||||
very simple lines of code:
|
||||
|
||||
```js
|
||||
import BaseDriver from '@appium/base-driver'
|
||||
import {BaseDriver} from '@appium/base-driver'
|
||||
|
||||
class MyNewDriver extends BaseDriver {
|
||||
}
|
||||
@@ -49,8 +49,8 @@ async setUrl(url) {
|
||||
|
||||
[^1]: You might notice that `setUrl` doesn't look anything like `Navigate To`, so how did we know
|
||||
to use it rather than some other random string? Well, Appium's WebDriver-protocol-to-method-name
|
||||
mappings are defined in special files within the `@appium/base-driver` package's
|
||||
[routes/](https://github.com/appium/appium/tree/master/packages/base-driver/lib/protocol/routes) directory.
|
||||
mapping is defined in a special file within the `@appium/base-driver` package called
|
||||
[routes.js](https://github.com/appium/appium/blob/master/packages/base-driver/lib/protocol/routes.js).
|
||||
So if you're writing a driver, this is where you would go to figure out what method names to use
|
||||
and what parameters to expect. Or you could look at the source for any of the main Appium
|
||||
drivers!
|
||||
@@ -81,7 +81,7 @@ from there is up to you, the driver author!
|
||||
## Automation mapping
|
||||
|
||||
But *typically* what driver authors want to do is to provide automation behaviours for a given
|
||||
platform(s) that are semantically very similar to the WebDriver spec implementations for
|
||||
platform(s) that are semantically very similar to the the WebDriver spec implementations for
|
||||
browsers. When you want to find an element, you should get a reference to a UI element. When you
|
||||
want to click or tap that element, the resulting behaviour should be the same as if a person were
|
||||
to click or tap on the element. And so on.
|
||||
@@ -175,7 +175,7 @@ be passed back directly to the client, without any XCUITest driver code seeing i
|
||||
This architectural pattern provides a nice bonus for driver authors who choose to deal with the
|
||||
WebDriver protocol everywhere, rather than constructing bespoke protocols. It also means that
|
||||
Appium can create wrapper drivers for any other existing WebDriver implementation very easily. If
|
||||
you look at the [Appium Safari driver](https://appium.github.io/appium-safari-driver/) code, for
|
||||
you look at the [Appium Safari driver](https://github.com/appium/appium-safari-driver) code, for
|
||||
example, you'll see that it implements basically no standard commands, because all of these are
|
||||
proxied directly to an underlying SafariDriver process.
|
||||
|
||||
|
||||
@@ -1,142 +0,0 @@
|
||||
# Appium
|
||||
|
||||
> 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.
|
||||
@@ -13,7 +13,7 @@ The basic plan for this quickstart is as follows:
|
||||
|
||||
1. Install Appium
|
||||
1. Install an Appium driver and its dependencies
|
||||
- This guide provides instructions for the [UiAutomator2 driver](https://appium.github.io/appium-uiautomator2-driver/)
|
||||
- This guide provides instructions for the [UiAutomator2 driver](https://github.com/appium/appium-uiautomator2-driver)
|
||||
1. Install an Appium client library in your language of choice
|
||||
- This guide contains options for JavaScript, Python, Java, Ruby, and .NET
|
||||
1. Write and run a simple Appium automation script using a sample application
|
||||
|
||||
@@ -14,7 +14,7 @@ reference materials especially for beginners:
|
||||
- [Capabilities](../guides/caps.md)
|
||||
- [Settings](../guides/settings.md)
|
||||
|
||||
You'll also find that the [Appium Inspector](https://appium.github.io/appium-inspector/) is an
|
||||
You'll also find that the [Appium Inspector](https://github.com/appium/appium-inspector) is an
|
||||
indispensable tool for writing Appium tests, as it enables visual inspection of apps and
|
||||
helps you to discover element locators for use in your test scripts.
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ The `appium_lib_core` is the main part as an Appium client.
|
||||
`appium_lib_core` does not have such a global variable.
|
||||
|
||||
This example is by the `appium_lib_core` with `test-unit` gem module.
|
||||
Test code in `appium_lib` should be similar.
|
||||
Tes code in `appium_lib` should be similar.
|
||||
|
||||
```ruby title="test.rb"
|
||||
--8<-- "./sample-code/quickstarts/rb/test.rb"
|
||||
|
||||
@@ -12,7 +12,7 @@ interface that allows Appium to automate a particular platform.
|
||||
(whereas the iOS driver, for example, requires you to be using macOS).
|
||||
|
||||
The driver we're going to use is called the [UiAutomator2
|
||||
Driver](https://appium.github.io/appium-uiautomator2-driver/). It's worth visiting that driver's
|
||||
Driver](https://github.com/appium/appium-uiautomator2-driver). It's worth visiting that driver's
|
||||
documentation and bookmarking it, because it will be an invaluable reference down the line.
|
||||
|
||||
## Set up Android automation requirements
|
||||
@@ -105,7 +105,7 @@ appium setup
|
||||
```
|
||||
|
||||
Running this will install Appium's mobile-specific drivers: UiAutomator2, [XCUITest](https://appium.github.io/appium-xcuitest-driver/)
|
||||
(only if running macOS), and [Espresso](https://appium.github.io/appium-espresso-driver/).
|
||||
(only if running macOS), and [Espresso](https://github.com/appium/appium-espresso-driver).
|
||||
|
||||
You can also use this command to batch install drivers for desktop applications or desktop browsers.
|
||||
For more details on this, refer to the [Setup command documentation](../reference/cli/setup.md).
|
||||
|
||||
@@ -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-maps.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.ts)
|
||||
for a detailed structure of this object.
|
||||
|
||||
### listExtensions
|
||||
@@ -103,7 +103,7 @@ 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-maps.ts)
|
||||
origin (driver-specific or plugin-specific). Refer to [the type definition file](https://github.com/appium/appium/blob/master/packages/types/lib/command.ts)
|
||||
for a detailed structure of this object.
|
||||
|
||||
### getCurrentAppiumContext
|
||||
|
||||
@@ -56,7 +56,7 @@ session.unsubscribe
|
||||
|
||||
> WebDriver BiDi documentation: [session.unsubscribe](https://w3c.github.io/webdriver-bidi/#command-session-unsubscribe)
|
||||
|
||||
Unsubscribes using either previously returned subscription IDs or event names.
|
||||
Unsubscribes using previously returned subscription IDs, or the legacy event/context form.
|
||||
Removing a subscription ID preserves any overlapping subscriptions.
|
||||
|
||||
#### Parameters
|
||||
@@ -64,8 +64,8 @@ Removing a subscription ID preserves any overlapping subscriptions.
|
||||
|Name|Description|Type|Default|
|
||||
|--|--|--|--|
|
||||
|`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[]||
|
||||
|`contexts?`|Legacy form only: contexts in which to unsubscribe from the specified events. By default, the global scope is applied.|string[]|`['']`|
|
||||
|`events?`|Legacy form: 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.
|
||||
|
||||
@@ -10,125 +10,6 @@ title: JSON Wire Protocol
|
||||
The following is a list of legacy [JSON Wire Protocol (JSONWP)](https://www.selenium.dev/documentation/legacy/json_wire_protocol/)
|
||||
endpoints supported in Appium.
|
||||
|
||||
### getSession
|
||||
|
||||
```
|
||||
GET /session/:sessionId
|
||||
```
|
||||
|
||||
> JSONWP documentation: [/session/:sessionId](https://www.selenium.dev/documentation/legacy/json_wire_protocol/#sessionsessionid)
|
||||
|
||||
Retrieves the capabilities of the current session.
|
||||
|
||||
Appium implements a modified version of this endpoint. If the `appium:eventTimings` capability is
|
||||
set to `true`, the returned result will additionally include the `events` key, whose value contains
|
||||
the event history and timings.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
For retrieving capabilities, please use [`getAppiumSessionCapabilities`](./appium.md#getappiumsessioncapabilities).<br />
|
||||
For retrieving event history, please use [`getLogEvents`](./appium.md#getlogevents).
|
||||
|
||||
#### Response
|
||||
|
||||
`Capabilities` - an object containing the session capabilities, and the event history (if applicable)
|
||||
|
||||
### availableIMEEngines
|
||||
|
||||
```
|
||||
GET /session/:sessionId/ime/available_engines
|
||||
```
|
||||
|
||||
> JSONWP documentation: [/session/:sessionId/ime/available_engines](https://www.selenium.dev/documentation/legacy/json_wire_protocol/#sessionsessionidimeavailable_engines)
|
||||
|
||||
Retrieves all IME (input method editor) engines available on the device under test.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
In the future, this endpoint will be moved to the [UiAutomator2 and Espresso drivers](../../ecosystem/drivers.md)
|
||||
|
||||
#### Response
|
||||
|
||||
`string[]` - a list of available IME engines
|
||||
|
||||
### getActiveIMEEngine
|
||||
|
||||
```
|
||||
GET /session/:sessionId/ime/active_engine
|
||||
```
|
||||
|
||||
> JSONWP documentation: [/session/:sessionId/ime/active_engine](https://www.selenium.dev/documentation/legacy/json_wire_protocol/#sessionsessionidimeactive_engine)
|
||||
|
||||
Retrieves the name of the active IME engine.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
In the future, this endpoint will be moved to the UiAutomator2 and Espresso drivers
|
||||
|
||||
#### Response
|
||||
|
||||
`string` - the name of the active IME engine
|
||||
|
||||
### isIMEActivated
|
||||
|
||||
```
|
||||
GET /session/:sessionId/ime/activated
|
||||
```
|
||||
|
||||
> JSONWP documentation: [/session/:sessionId/ime/activated](https://www.selenium.dev/documentation/legacy/json_wire_protocol/#sessionsessionidimeactivated)
|
||||
|
||||
Determines if IME input is available and active.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
In the future, this endpoint will be moved to the UiAutomator2 and Espresso drivers
|
||||
|
||||
#### Response
|
||||
|
||||
`boolean` - `true` if IME is active, otherwise `false`
|
||||
|
||||
### deactivateIMEEngine
|
||||
|
||||
```
|
||||
POST /session/:sessionId/ime/deactivate
|
||||
```
|
||||
|
||||
> JSONWP documentation: [/session/:sessionId/ime/deactivate](https://www.selenium.dev/documentation/legacy/json_wire_protocol/#sessionsessionidimedeactivate)
|
||||
|
||||
Deactivates the currently active IME engine.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
In the future, this endpoint will be moved to the UiAutomator2 and Espresso drivers
|
||||
|
||||
#### Response
|
||||
|
||||
`null`
|
||||
|
||||
### activateIMEEngine
|
||||
|
||||
```
|
||||
POST /session/:sessionId/ime/activate
|
||||
```
|
||||
|
||||
> JSONWP documentation: [/session/:sessionId/ime/activate](https://www.selenium.dev/documentation/legacy/json_wire_protocol/#sessionsessionidimeactivate)
|
||||
|
||||
Activates an IME engine.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
In the future, this endpoint will be moved to the UiAutomator2 and Espresso drivers
|
||||
|
||||
#### Parameters
|
||||
|
||||
|Name|Description|Type|
|
||||
|--|--|--|
|
||||
|`engine`|Name of the IME engine to activate|string|
|
||||
|
||||
#### Response
|
||||
|
||||
`null`
|
||||
|
||||
### getOrientation
|
||||
|
||||
```
|
||||
@@ -170,53 +51,3 @@ Sets the orientation of the device under test.
|
||||
#### Response
|
||||
|
||||
`null`
|
||||
|
||||
### getGeoLocation
|
||||
|
||||
```
|
||||
GET /session/:sessionId/location
|
||||
```
|
||||
|
||||
> JSONWP documentation: [/session/:sessionId/location](https://www.selenium.dev/documentation/legacy/json_wire_protocol/#sessionsessionidlocation)
|
||||
|
||||
Retrieves the current location of the device under test.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Please use driver-specific extension methods such as `mobile: getGeoLocation` or
|
||||
`mobile: getSimulatedLocation`
|
||||
|
||||
#### Response
|
||||
|
||||
`Location` - an object with the following properties:
|
||||
|
||||
|Name|Description|Type|
|
||||
|--|--|--|
|
||||
|`altitude`|Altitude of the device location|number|
|
||||
|`latitude`|Latitude of the device location|number|
|
||||
|`longitude`|Longitude of the device location|number|
|
||||
|
||||
### setGeoLocation
|
||||
|
||||
```
|
||||
POST /session/:sessionId/location
|
||||
```
|
||||
|
||||
> JSONWP documentation: [/session/:sessionId/location](https://www.selenium.dev/documentation/legacy/json_wire_protocol/#sessionsessionidlocation)
|
||||
|
||||
Sets the current location of the device under test.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Please use driver-specific extension methods such as `mobile: setGeoLocation` or
|
||||
`mobile: setSimulatedLocation`
|
||||
|
||||
#### Parameters
|
||||
|
||||
|Name|Description|Type|
|
||||
|--|--|--|
|
||||
|`location`|New device latitude, longitude and altitude|[`Location`](#response_6)|
|
||||
|
||||
#### Response
|
||||
|
||||
`null`
|
||||
|
||||
@@ -119,53 +119,3 @@ Retrieves all available application contexts.
|
||||
#### Response
|
||||
|
||||
`string[]` - the names of available contexts
|
||||
|
||||
### getNetworkConnection
|
||||
|
||||
```
|
||||
GET /session/:sessionId/network_connection
|
||||
```
|
||||
|
||||
> MJSONWP documentation: [Device Modes](https://github.com/SeleniumHQ/mobile-spec/blob/master/spec-draft.md#device-modes)
|
||||
|
||||
Retrieves the current state of network types (data, Wi-Fi, airplane mode).
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Please use driver-specific extension methods such as `mobile: getConnectivity`
|
||||
|
||||
#### Response
|
||||
|
||||
`NetworkConnectionState` - a number indicating the current network state:
|
||||
|
||||
|Value|Data|Wi-Fi|Airplane Mode|
|
||||
|--|--|--|--|
|
||||
|`0`|OFF|OFF|OFF|
|
||||
|`1`|OFF|OFF|ON|
|
||||
|`2`|OFF|ON|OFF|
|
||||
|`4`|ON|OFF|OFF|
|
||||
|`6`|ON|ON|OFF|
|
||||
|
||||
### setNetworkConnection
|
||||
|
||||
```
|
||||
POST /session/:sessionId/network_connection
|
||||
```
|
||||
|
||||
> MJSONWP documentation: [Device Modes](https://github.com/SeleniumHQ/mobile-spec/blob/master/spec-draft.md#device-modes)
|
||||
|
||||
Sets the state of network types (data, Wi-Fi, airplane mode).
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Please use driver-specific extension methods such as `mobile: setConnectivity`
|
||||
|
||||
#### Parameters
|
||||
|
||||
|<div style="width:6em">Name</div>|Description|<div style="width:18em">Type</div>|
|
||||
|--|--|--|
|
||||
|`parameters`|Object containing the `type` key, whose value is the desired network state|`{"type": `[`NetworkConnectionState`](#response_5)`}`|
|
||||
|
||||
#### Response
|
||||
|
||||
[`NetworkConnectionState`](#response_5) - the new network state
|
||||
|
||||
@@ -265,6 +265,43 @@ preserved, and only the incomplete uploads will be stopped.
|
||||
|
||||
## Universal XML Plugin
|
||||
|
||||
Translation is on by default. It can be turned off and on during a session with the
|
||||
[execute methods](../../guides/execute-methods.md) below, and applies only to the current session.
|
||||
|
||||
### execute
|
||||
|
||||
```
|
||||
POST /session/:sessionId/execute/sync
|
||||
```
|
||||
|
||||
Modifies the [`execute`](./webdriver.md#execute) endpoint:
|
||||
|
||||
* Adds the `universalXml: setEnabled` and `universalXml: isEnabled` execute methods. Any other
|
||||
script is passed on unchanged
|
||||
|
||||
#### universalXml: setEnabled
|
||||
|
||||
Turns translation on or off for the current session. While it is off, `findElement`,
|
||||
`findElements` and `getPageSource` are passed on unchanged.
|
||||
|
||||
##### Parameters
|
||||
|
||||
|Name|Description|Type|
|
||||
|--|--|--|
|
||||
|`enabled`|Whether node/attribute names should be translated|boolean|
|
||||
|
||||
##### Response
|
||||
|
||||
`null`
|
||||
|
||||
#### universalXml: isEnabled
|
||||
|
||||
Returns whether translation is on for the current session.
|
||||
|
||||
##### Response
|
||||
|
||||
`boolean` - `true` if translation is on
|
||||
|
||||
### findElement
|
||||
|
||||
```
|
||||
|
||||
@@ -25,18 +25,11 @@ POST /session
|
||||
|
||||
Creates a new WebDriver session.
|
||||
|
||||
Appium implements a modified version of this endpoint for historical reasons. While the W3C
|
||||
endpoint only accepts 1 parameter, Appium's implementation allows up to 3 parameters, as this was
|
||||
required by the legacy JSON Wire Protocol (JSONWP). Since Appium 2, the JSONWP format is no longer
|
||||
supported, and any of the 3 parameters can be used to specify the W3C capabilities.
|
||||
|
||||
#### Parameters
|
||||
|
||||
|Name|Description|Type|
|
||||
|--|--|--|
|
||||
|`w3cCapabilities1?`|Capabilities of the new session|`W3CDriverCaps`|
|
||||
|`w3cCapabilities2?`|Another location for the new session capabilities (legacy)|`W3CDriverCaps`|
|
||||
|`w3cCapabilities?`|Another location for the new session capabilities (legacy)|`W3CDriverCaps`|
|
||||
|`capabilities?`|Capabilities of the new session|`W3CDriverCaps`|
|
||||
|
||||
#### Response
|
||||
|
||||
@@ -91,14 +84,19 @@ GET /session/:sessionId/timeouts
|
||||
|
||||
Retrieves the timeout values of the current session.
|
||||
|
||||
Appium implements a modified version of this endpoint, by also returning the value of the `command`
|
||||
timeout for supported drivers and contexts.
|
||||
|
||||
#### Response
|
||||
|
||||
`GetTimeoutsResult` - an object with the following properties:
|
||||
|
||||
|Name|Description|Type|
|
||||
|--|--|--|
|
||||
|`command`|Command timeout|number|
|
||||
|`script`|Script timeout|number|
|
||||
|`pageLoad`|Page load timeout|number|
|
||||
|`implicit`|Implicit wait timeout|number|
|
||||
|`command`|Appium command timeout|number|
|
||||
|
||||
### timeouts
|
||||
|
||||
@@ -110,13 +108,17 @@ POST /session/:sessionId/timeouts
|
||||
|
||||
Sets the timeout values of the current session.
|
||||
|
||||
Appium implements a modified version of this endpoint by adding the optional `command` parameter
|
||||
for supported drivers and contexts.
|
||||
|
||||
#### Parameters
|
||||
|
||||
|Name|Description|Type|
|
||||
|--|--|--|
|
||||
|`script?`|Script timeout (in milliseconds)|number|
|
||||
|`implicit?`|Implicit wait timeout (in milliseconds)|number|
|
||||
|`pageLoad?`|Page load timeout (in milliseconds)|number|
|
||||
|`script?`|Script timeout (in milliseconds)|number|
|
||||
|`command?`|Appium command timeout (in milliseconds)|number|
|
||||
|
||||
#### Response
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ appium {driver|plugin} install <install-spec>
|
||||
|--|--|
|
||||
|None|The short name of an official extension, with optional modifiers as supported by `npm install` (e.g. version or tag)|
|
||||
|`git`|The Git URL of the extension|
|
||||
|`github`|The GitHub repository slug of the extension, in the form `<org>/<repo>`|
|
||||
|`github`|The GitHub repository URL of the extension|
|
||||
|`local`|The local path to the extension containing its `package.json` file|
|
||||
|`npm`|The name of the `npm` package, with optional modifiers as supported by `npm install` (e.g. version or tag)|
|
||||
|
||||
@@ -114,7 +114,7 @@ appium {driver|plugin} install <install-spec>
|
||||
- Install the XCUITest driver from GitHub:
|
||||
|
||||
```
|
||||
appium driver install appium/appium-xcuitest-driver --source=github --package=appium-xcuitest-driver
|
||||
appium driver install https://github.com/appium/appium-xcuitest-driver --source=github --package=appium-xcuitest-driver
|
||||
```
|
||||
|
||||
- Install the XCUITest driver using a Git URL:
|
||||
|
||||
@@ -14,6 +14,7 @@ they can only be enabled using the wildcard (`*`) prefix:
|
||||
| Feature Name | Description |
|
||||
|-------------------|-------------------------------------------------------------------------------|
|
||||
|`session_discovery`|Allows retrieving the list of active server sessions via `GET /appium/sessions`|
|
||||
|`cors` |Allows web browser connections to the server from any host |
|
||||
|
||||
|
||||
Of course, Appium drivers and plugins are free to define additional insecure features of their own.
|
||||
|
||||
@@ -26,12 +26,12 @@ appium
|
||||
|
||||
|<div style="width:15em">Argument</div>|Description|Type|<div style="width:7em">Default</div>|
|
||||
|--|--|--|--|
|
||||
|`--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`|
|
||||
|`--address`, `-a`|IPv4/IPv6 address to listen on|string|`0.0.0.0`|
|
||||
|`--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`|
|
||||
|`--app-url-rules`|Rules that remote application URLs (e.g. in the `appium:app` capability) must satisfy before the server downloads them. See the [Restricting Remote App URLs](../../guides/security.md#restricting-remote-app-urls) guide for details. Can be a path to a JSON file or raw JSON.|object||
|
||||
|`--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|same as `--address`|
|
||||
|`--callback-address`, `-ca`|Callback IP address|string|`0.0.0.0`|
|
||||
|`--callback-port`, `-cp`|Callback port|integer|`4723`|
|
||||
|`--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`|
|
||||
@@ -44,7 +44,7 @@ appium
|
||||
|`--local-timezone`|Use local timezone for log timestamps|boolean|`false`|
|
||||
|`--log`, `-g`|Path to a file where the server logs should be output. This does not affect output on the console.|string||
|
||||
|`--log-filters`|List of log filtering rules. See the [log filtering guide](../../guides/log-filters.md) for details.|array||
|
||||
|`--log-level`|The log level for the server logs. Supported values are `debug`, `info`, `warn`, or `error`. Combining two supported values using a colon (e.g. `warn:debug`) allows to set separate log levels for the console and file outputs, respectively.|string|`debug`|
|
||||
|`--log-level`|The log level for the server logs. Supported values are `debug`, `info`, `warn`, or `error`. Combining two supported values using a colon (e.g. `warn:debug`) allows to set separate log levels for the console and file outputs, respectively.|string|`info`|
|
||||
|`--log-format`|The log format of the server logs. Supported values are `text`, `json`, or `pretty_json`. Setting the value to `json` disables colors.|string|`text`|
|
||||
|`--log-no-colors`|Disable colors in the server log|boolean|`false`|
|
||||
|`--log-timestamp`|Show timestamps in the server log|boolean|`false`|
|
||||
@@ -52,7 +52,6 @@ appium
|
||||
|`--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||
|
||||
|`--plugins-import-chunk-size`|Maximum number of plugins that can be imported in parallel on server startup|number|`7`|
|
||||
|`--port`, `-p`|Port to listen on|integer|`4723`|
|
||||
|
||||
@@ -32,9 +32,8 @@ default value.
|
||||
| <div style="width:19em">Capability</div> | Description | Type | Default |
|
||||
|--|--|--|--|
|
||||
| `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 page source and its printing to the Appium log, whenever a request to find an element fails | `boolean` ||
|
||||
| `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` ||
|
||||
|
||||
### Validated Capabilities
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ cd appium
|
||||
|
||||
!!! info
|
||||
|
||||
If you are VS Code user, you can easily check out the project using [Runme](https://runme.dev/).
|
||||
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).
|
||||
|
||||
Install dependencies:
|
||||
|
||||
@@ -109,27 +109,6 @@ export APPIUM_WORKSPACE=@appium/base-driver
|
||||
npm run test:unit -w $APPIUM_WORKSPACE
|
||||
```
|
||||
|
||||
### Code Style
|
||||
|
||||
#### JSDoc
|
||||
|
||||
Add concise JSDoc to all public class methods and exported functions.
|
||||
|
||||
#### Module Ordering
|
||||
|
||||
Place exported functions and classes before non-exported functions and classes in each module.
|
||||
This rule does not apply to constants or variables.
|
||||
|
||||
#### Class Member Ordering
|
||||
|
||||
When adding or moving class methods, follow these conventions:
|
||||
|
||||
- Order methods by visibility: public → protected → private. Methods without an explicit visibility
|
||||
modifier belong to the public group.
|
||||
- Place private helper methods at the end of the class.
|
||||
- Preserve existing order within each visibility group.
|
||||
- Before finishing, check the ordering of methods you added or moved.
|
||||
|
||||
### Documentation
|
||||
|
||||
The documentation for this project is [available in the project repository itself](https://github.com/appium/appium/tree/master/packages/appium/docs).
|
||||
|
||||
@@ -50,7 +50,7 @@ npx appium-docs init
|
||||
This will:
|
||||
|
||||
1. Create a `tsconfig.json` if one does not already exist. This is necessary even if your extension
|
||||
is not written in TypeScript.
|
||||
is not written in TypeScript.
|
||||
2. Create a `mkdocs.yml` with the necessary configuration for MkDocs.
|
||||
|
||||
### Documenting Your Extension
|
||||
@@ -62,33 +62,6 @@ them in `docs`, and add links to these files in `mkdocs.yml`.
|
||||
Refer to the [MkDocs documentation](https://www.mkdocs.org/user-guide/writing-your-docs/) for
|
||||
information on how to organize and structure your documentation.
|
||||
|
||||
### Helping LLMs Use Your Documentation
|
||||
|
||||
The [`/llms.txt` convention](https://llmstxt.org/) is a Markdown file at the root of a
|
||||
documentation site, listing its most useful pages so that large language models can navigate the
|
||||
site without crawling it. Appium's own documentation provides one at
|
||||
[appium.io/docs/en/latest/llms.txt](https://appium.io/docs/en/latest/llms.txt), and you may want to
|
||||
do the same for your extension.
|
||||
|
||||
MkDocs copies any non-Markdown file in your `docs` directory to the built site as-is, so all you
|
||||
need to do is write an `llms.txt` and place it alongside your Markdown files. No plugin or build
|
||||
configuration is required.
|
||||
|
||||
The value of this file lies in the parts a crawler could not have worked out on its own, so it is
|
||||
worth writing by hand rather than generating it from your navigation:
|
||||
|
||||
- A short description of what your extension automates, and which platforms it targets
|
||||
- The handful of things models reliably get wrong about your extension - removed capabilities,
|
||||
renamed commands, patterns from an older major version that no longer apply
|
||||
- Links to the pages that matter, with a description of each
|
||||
|
||||
Because links in `llms.txt` are read out of context, they must be absolute URLs. If you use Mike
|
||||
for versioning, point them at your version alias (for example `latest`) rather than at a pinned
|
||||
version, so that the file does not go stale. Note that a hand-written file can drift as pages are
|
||||
renamed; Appium validates its own with a
|
||||
[script](https://github.com/appium/appium/blob/master/packages/appium/docs/scripts/check-llmstxt.js)
|
||||
that runs in CI, which you are welcome to adapt.
|
||||
|
||||
### Building the Docs
|
||||
|
||||
At this point, you can use the `appium-docs` CLI tool. Run this tool with no arguments to get the
|
||||
|
||||
@@ -80,9 +80,8 @@ The required subfields are:
|
||||
capability to tell Appium to use _your_ driver.
|
||||
- `platformNames`: this is an array of one or more platform names considered valid for your driver.
|
||||
When a user sends in the `platformName` capability to start a session, it must be included in
|
||||
this list for your driver to handle the session. These names should generally include the
|
||||
operating systems your driver is targeting - for example, a driver targeting iOS would include
|
||||
`iOS`, while a driver targeting the Chrome browser on Windows would include `Windows`.
|
||||
this list for your driver to handle the session. Known platform name strings include: `iOS`,
|
||||
`tvOS`, `macOS`, `Windows`, `Android`.
|
||||
- `mainClass`: this is a named export (in CommonJS style) from your `main` field. It must be a
|
||||
class which extends Appium's `BaseDriver` (see below).
|
||||
|
||||
@@ -284,8 +283,8 @@ You handle WebDriver commands by implementing functions in your driver class. Ea
|
||||
WebDriver Protocol, plus the various Appium extensions, has a corresponding function that you
|
||||
implement if you want to support that command in your driver. The best way to see which commands
|
||||
Appium supports and which method you need to implement for each command is to look at Appium's
|
||||
[routes/](https://github.com/appium/appium/tree/master/packages/base-driver/lib/protocol/routes).
|
||||
Each route object in this directory's files tells you the command name as well as the parameters you'd expect to
|
||||
[routes.js](https://github.com/appium/appium/blob/master/packages/base-driver/lib/protocol/routes.js).
|
||||
Each route object in this file tells you the command name as well as the parameters you'd expect to
|
||||
receive for that command.
|
||||
|
||||
Let's take this block for example:
|
||||
@@ -328,7 +327,7 @@ Websockets. Implementing handlers for BiDi commands works just the same as imple
|
||||
for WebDriver classic commands (described in the previous section). You simply define a method on
|
||||
your driver of the appropriate name, and it will be called when the BiDi command is requested by
|
||||
the client. To see which specific names you should use for BiDi commands, have a look at
|
||||
[bidi-commands.ts](https://github.com/appium/appium/blob/master/packages/base-driver/lib/protocol/bidi-commands.ts)
|
||||
[bidi-commands.js](https://github.com/appium/appium/blob/master/packages/base-driver/lib/protocol/bidi-commands.js)
|
||||
|
||||
You are not limited to BiDi commands that are defined in the official BiDi specification. If you
|
||||
wish to define new commands, you may do so; you just need to tell Appium about them! See
|
||||
|
||||
@@ -482,7 +482,7 @@ capability.
|
||||
|
||||
You probably don't normally need to update the Appium server object (which is an
|
||||
[Express](https://expressjs.com/) server having already been
|
||||
[configured](https://github.com/appium/appium/blob/master/packages/base-driver/lib/express/server.ts)
|
||||
[configured](https://github.com/appium/appium/blob/master/packages/base-driver/lib/express/server.js)
|
||||
in a variety of ways). But, for example, you could add new routes to the server to support your
|
||||
plugin's requirements. To update the server you must implement the `static async updateServer`
|
||||
method in your class. This method takes three parameters:
|
||||
|
||||
@@ -65,7 +65,7 @@ functionality (e.g., the `plugin` or `driver` subcommands).
|
||||
Note that this file is the _base_ schema; this will become painfully relevant.
|
||||
```
|
||||
|
||||
This file is _not_ a JSON file, because a) JSON is painful to work with for humans, b) is
|
||||
This file is is _not_ a JSON file, because a) JSON is painful to work with for humans, b) is
|
||||
especially reviled by @jlipps, and c) `ajv` accepts objects, not JSON files.
|
||||
|
||||
It is more straightforward to explain how config files are validated, so we'll start there.
|
||||
|
||||
@@ -17,34 +17,34 @@ If you maintain an Appium driver that you would like to be listed here, feel fre
|
||||
|
||||
These drivers are currently maintained by the Appium team:
|
||||
|
||||
### [Chromium](https://appium.github.io/appium-chromium-driver/)
|
||||
### [Chromium](https://github.com/appium/appium-chromium-driver)
|
||||
|
||||
- Target: Desktop Chromium-based browsers (Chrome, Microsoft Edge, etc.)
|
||||
- Target: Desktop and mobile Chromium browsers (Chrome, Microsoft Edge, etc.)
|
||||
- Mode: Web
|
||||
|
||||
```sh title="Install This Driver"
|
||||
appium driver install chromium
|
||||
```
|
||||
|
||||
### [Espresso](https://appium.github.io/appium-espresso-driver/)
|
||||
### [Espresso](https://github.com/appium/appium-espresso-driver)
|
||||
|
||||
- Target: Android applications (mobile, TV, Wear, XR, Automotive)
|
||||
- Mode: Native, Hybrid, Web
|
||||
- Target: Android applications
|
||||
- Mode: Native
|
||||
|
||||
```sh title="Install This Driver"
|
||||
appium driver install espresso
|
||||
```
|
||||
|
||||
### [Gecko](https://appium.github.io/appium-geckodriver/)
|
||||
### [Gecko](https://github.com/appium/appium-geckodriver)
|
||||
|
||||
- Target: Desktop and mobile Gecko-based browsers (Firefox, etc.)
|
||||
- Target: Desktop and mobile Gecko browsers (Firefox)
|
||||
- Mode: Web
|
||||
|
||||
```sh title="Install This Driver"
|
||||
appium driver install gecko
|
||||
```
|
||||
|
||||
### [Mac2](https://appium.github.io/appium-mac2-driver/)
|
||||
### [Mac2](https://github.com/appium/appium-mac2-driver)
|
||||
|
||||
- Target: macOS applications
|
||||
- Mode: Native
|
||||
@@ -53,7 +53,7 @@ appium driver install gecko
|
||||
appium driver install mac2
|
||||
```
|
||||
|
||||
### [Safari](https://appium.github.io/appium-safari-driver/)
|
||||
### [Safari](https://github.com/appium/appium-safari-driver)
|
||||
|
||||
- Target: Desktop and mobile Safari browsers
|
||||
- Mode: Web
|
||||
@@ -62,9 +62,9 @@ appium driver install mac2
|
||||
appium driver install safari
|
||||
```
|
||||
|
||||
### [UiAutomator2](https://appium.github.io/appium-uiautomator2-driver/)
|
||||
### [UiAutomator2](https://github.com/appium/appium-uiautomator2-driver)
|
||||
|
||||
- Target: Android applications (mobile, TV, Wear, XR, Automotive)
|
||||
- Target: Android, Android TV, Android Wear applications
|
||||
- Modes: Native, Hybrid, Web
|
||||
|
||||
```sh title="Install This Driver"
|
||||
@@ -89,7 +89,7 @@ appium driver install windows
|
||||
|
||||
### [XCUITest](https://appium.github.io/appium-xcuitest-driver/)
|
||||
|
||||
- Target: iOS, iPadOS, tvOS, watchOS applications
|
||||
- Target: iOS, iPadOS, tvOS applications
|
||||
- Modes: Native, Hybrid, Web
|
||||
|
||||
```sh title="Install This Driver"
|
||||
@@ -169,7 +169,7 @@ This driver is recommended as a drop-in replacement for the partially unmaintain
|
||||
```
|
||||
|
||||
- Target: Windows applications
|
||||
- Mode: Native, Hybrid
|
||||
- Mode: Native
|
||||
- Supported by: Community / Automate The Planet
|
||||
|
||||
```sh title="Install This Driver"
|
||||
|
||||
@@ -14,7 +14,7 @@ If you maintain an Appium plugin that you would like to be listed here, feel fre
|
||||
|
||||
## Official Plugins
|
||||
|
||||
These plugins are currently maintained by the Appium team:
|
||||
These plugins are are currently maintained by the Appium team:
|
||||
|
||||
### [Execute Driver](https://github.com/appium/appium/tree/master/packages/execute-driver-plugin)
|
||||
|
||||
|
||||
@@ -113,30 +113,3 @@ Supported by: `@AppiumTestDistribution`
|
||||
```sh title="Install This Tool"
|
||||
npm install -g appium-installer
|
||||
```
|
||||
|
||||
### [Optics](https://github.com/mozarkai/optics-framework)
|
||||
|
||||
Optics is an open-source test automation framework that uses Appium to drive Android, iOS,
|
||||
Android TV, Samsung Tizen and LG webOS apps (and Selenium or Playwright for web). Tests are written
|
||||
as CSV or YAML keyword steps, and the same keywords are available as a Python library, a Robot
|
||||
Framework library, an HTTP API and an MCP server. Element lookup falls back from XPath to visible
|
||||
text, OCR and image matching.
|
||||
|
||||
Supported by: `@chinmayajha`
|
||||
|
||||
```sh title="Install This Tool"
|
||||
pip install "optics-framework[mobile]"
|
||||
```
|
||||
|
||||
### [XPath to Class Chain](https://github.com/domovou69/xpath-to-class-chain)
|
||||
|
||||
XPath to Class Chain is a command-line tool for migrating iOS XPath locators in test code to
|
||||
`-ios class chain` selectors. It converts the XPaths that have an exact class chain equivalent,
|
||||
converts with a warning those that only have a close one (such as grouped positions `(//X)[n]`),
|
||||
and skips the rest with a reason (for example, sibling or parent axes).
|
||||
|
||||
Supported by: `@domovou69`
|
||||
|
||||
```sh title="Install This Tool"
|
||||
npm install -g xpath-to-class-chain
|
||||
```
|
||||
|
||||
@@ -52,6 +52,6 @@ After the PR is merged there is no need to use the local plugin/driver deploymen
|
||||
to switch back to the package managed by NPM. Follow the next steps for that:
|
||||
|
||||
- Unlink the installed driver/plugin from the server by running `appium driver uninstall <driver_name>` or
|
||||
`appium plugin uninstall <plugin_name>`.
|
||||
`appium plugin uninstall <driver_name>`.
|
||||
- Delete the local source folder (`rm -rf <full_path_to_plugin_or_driver_folder_with_fetched_sources>`).
|
||||
- Install the driver or the plugin from NPM. Check the component README in order to find a proper command for that.
|
||||
|
||||
@@ -8,14 +8,14 @@ principles, so you could create more performant and efficient test suite executi
|
||||
|
||||
## Why Caching Is Necessary
|
||||
|
||||
Mobile application bundles could reach hundreds of megabytes in size. This could become a serious
|
||||
Mobile application bundles could reach hundreds of megabytes is size. This could become a serious
|
||||
performance issue if a test suite is executed, and it is necessary to fetch/extract the same application
|
||||
bundle for each test.
|
||||
|
||||
## What Is Cached
|
||||
|
||||
Caching could be applied to application bundles generated by
|
||||
[`configureApp`](https://github.com/appium/appium/blob/master/packages/base-driver/lib/basedriver/helpers.ts#L99) helper call.
|
||||
[`configureApp`](https://github.com/appium/appium/blob/master/packages/base-driver/lib/basedriver/helpers.js#L107) helper call.
|
||||
Inherited drivers can customize their caching logic by providing own `onPostProcess`
|
||||
(or both `inDownload` and `onPostProcess`) property definition, but the general
|
||||
rule of thumb is that we need to cache locally all application bundles need to be downloaded and/or extracted
|
||||
|
||||
@@ -24,7 +24,7 @@ to launch. In order to achieve this, Appium defines its own [extension capabilit
|
||||
## 一般的なAppiumのCapabilities
|
||||
|
||||
According to the WebDriver spec, extension capabilities must include a namespace prefix (signifying
|
||||
the vendor introducing the capability), and the namespace must end in a colon (`:`). Appium's vendor
|
||||
the vendor introducing the capability), and the namespace must end a colon (`:`). Appium's vendor
|
||||
prefix is `appium:`, and so any Appium-specific capabilities must include this prefix. Depending on
|
||||
your Appium client, the prefix may be added automatically or in conjunction with certain interfaces,
|
||||
but it is always a good practice to explicitly include it for clarity.
|
||||
@@ -78,7 +78,7 @@ BiDi commands, so make sure to reference their documentation.
|
||||
|
||||
## `appium:options` を使用して機能をグループ化する
|
||||
|
||||
テストで `appium:` 機能を多用すると、繰り返しが多くなる可能性があります。代わりに、すべての機能を単一の `appium:options` 機能のオブジェクト値として組み合わせることもできます。その場合、オブジェクト内の機能にプレフィックスを使用する必要はありません。例:
|
||||
テストで `appium:` 機能を多用すると、繰り返しが多くなる可能性があります。 代わりに、すべての機能を単一の `appium:options` 機能のオブジェクト値として組み合わせることもできます。その場合、オブジェクト内の機能にプレフィックスを使用する必要はありません。 例:
|
||||
|
||||
```json
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ discovered and loaded by Appium:
|
||||
- `appium.config.cjs`
|
||||
- `.appiumrc` (which is considered to be JSON)
|
||||
|
||||
Further, _if your project uses Node.js,_ you can store the configuration inside an `appiumConfig`
|
||||
Further, _if your project uses Node.js,_ you can use store the configuration inside an `appium`
|
||||
property in your `package.json` and it will be automatically discovered.
|
||||
|
||||
### Config File Search
|
||||
@@ -98,5 +98,5 @@ The above configuration corresponds to the `--driver-xcuitest-webkit-debug-proxy
|
||||
```
|
||||
|
||||
All properties are case-sensitive and will be in
|
||||
[kebab-case](https://en.wikipedia.org/wiki/Naming_convention_(programming)#Delimiter-separated_words).
|
||||
[kebab-case](https://en.wikipedia.org/wiki/Naming_convention_\(programming\)#Delimiter-separated_words).
|
||||
For example, `callback-port` is allowed, but `callbackPort` is not.
|
||||
|
||||
@@ -6,17 +6,18 @@ title: Retrieving Event Timings
|
||||
---
|
||||
|
||||
Appium comes with the ability to retrieve timing information about startup
|
||||
information and command length. This is an advanced feature; the server records
|
||||
event timings for every session.
|
||||
information and command length. This is an advanced feature that is controlled
|
||||
by the use of the `appium:eventTimings` capability (set it to `true` to log event
|
||||
timings).
|
||||
|
||||
The timings can be retrieved at any point during a session via the
|
||||
`POST /session/:id/appium/events` endpoint (i.e., the response to
|
||||
`driver.logs.events` or similar, depending on client). The response body is the
|
||||
event history object itself. This is its structure:
|
||||
With this capability turned on, the `POST /session/:id/appium/events` response (i.e.,
|
||||
the response to `driver.logs.events` or similar, depending on client) will be
|
||||
decorated with an `events` property. This is the structure of that `events`
|
||||
property:
|
||||
|
||||
```
|
||||
{
|
||||
"<event_type>": [<occurrence_timestamp_1>, ...],
|
||||
"<event_type>": [<occurence_timestamp_1>, ...],
|
||||
"commands": [
|
||||
{
|
||||
"cmd": "<command_name>",
|
||||
@@ -28,7 +29,7 @@ event history object itself. This is its structure:
|
||||
}
|
||||
```
|
||||
|
||||
In other words, the event history object has 2 kinds of properties of its own:
|
||||
In other words, the `events` property has 2 kinds of properties of its own:
|
||||
|
||||
- Properties which are the names of event types
|
||||
- The `commands` property
|
||||
@@ -63,9 +64,7 @@ generate various kinds of reports from event timings output:
|
||||
!!! note
|
||||
|
||||
```
|
||||
In the past, when the `appium:eventTimings` capability was set to `true`, the event history
|
||||
was also returned as an `events` property of the (now deprecated) `GET /session/:id`
|
||||
response
|
||||
In the past, events were available as a part of `GET /session/:id` response
|
||||
```
|
||||
|
||||
## Add a custom event
|
||||
|
||||
@@ -10,13 +10,13 @@ defined by the W3C WebDriver spec, Appium needs a way for these "extended" comma
|
||||
by client libraries. There are two main strategies for this:
|
||||
|
||||
1. Appium drivers define new W3C-compatible API routes, and Appium clients are updated to include
|
||||
support for those new routes.
|
||||
support for those new routes.
|
||||
2. Appium drivers define so-called "Execute Methods" which provide new functionality by
|
||||
overloading the existing `Execute Script` command which is already available in any WebDriver-
|
||||
based client library (including all Selenium and Appium clients).
|
||||
overloading the existing `Execute Script` command which is already available in any WebDriver-
|
||||
based client library (including all Selenium and Appium clients).
|
||||
|
||||
There are pros and cons for each strategy, but it is ultimately up to the extension author to
|
||||
decide how they wish to implement new commands.
|
||||
decide how they wish implement new commands.
|
||||
|
||||
This guide is designed to specifically help you understand the "Execute Method" strategy. This
|
||||
pattern is commonly used in official Appium drivers and other third-party extensions.
|
||||
@@ -134,9 +134,9 @@ Javascript execution:
|
||||
|
||||
1. The script string is just a command name; it will be provided by the driver documentation
|
||||
2. The standard way to provide parameters is as a _single_ object with keys representing parameter
|
||||
names and values representing parameter values. So in this case, we had to specify both the
|
||||
parameter name (`bundleId`) as the key of the parameters object, and the parameter value
|
||||
(`com.my.app`) as the value for that key. A driver can define parameters as _required_ or _optional_.
|
||||
names and values representing parameter values. So in this case, we had to specify both the
|
||||
parameter name (`bundleId`) as the key of the parameters object, and the parameter value
|
||||
(`com.my.app`) as the value for that key. A driver can define parameters as _required_ or _optional_.
|
||||
|
||||
Of course, always refer to the documentation for the particular Execute Method in case the author
|
||||
has made any alterations to the standard access method.
|
||||
|
||||
@@ -137,7 +137,7 @@ all parameters and descriptions see
|
||||
Once you start the Appium server it will register with the grid, and you will see your device on
|
||||
the grid console page:
|
||||
|
||||
`http://**\<grid-ip-address\>**:**\<grid-port\>**/grid/console`
|
||||
`http://**\<grid-ip-adress\>**:**\<grid-port\>**/grid/console`
|
||||
|
||||
### Example Grid Node Configuration JSON
|
||||
|
||||
|
||||
@@ -18,11 +18,8 @@ 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 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`.
|
||||
- `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.
|
||||
- `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.
|
||||
|
||||
@@ -27,7 +27,7 @@ appium driver install xcuitest
|
||||
```
|
||||
|
||||
This command will install the latest version of the
|
||||
[XCUITest Driver](https://appium.github.io/appium-xcuitest-driver/). The Extension CLI comes with a variety
|
||||
[XCUITest Driver](https://github.com/appium/appium-xcuitest-driver). The Extension CLI comes with a variety
|
||||
of commands and parameters; see the documentation for that command for all the specifics.
|
||||
|
||||
The all-important question when Appium is managing your extensions for you is: where are they installed?
|
||||
@@ -65,7 +65,7 @@ like any other dependency. Basically, whenever you run Appium, if you have not e
|
||||
1. Try to determine whether the _current directory_ is inside an `npm` package.
|
||||
2. If so, it will check whether `appium` is a dependency (dev, prod, or peer) in the project's
|
||||
`package.json`
|
||||
3. If so, _unless you have specified `APPIUM_HOME` in your environment_, Appium will load
|
||||
3. If so, _unless you have specified `APPIUM_HOME` in your environment_, Appium will ignore load
|
||||
drivers and plugins defined in that `package.json` file instead.
|
||||
|
||||
This means you are freely able to add Appium drivers and plugins as regular package dependencies or
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
title: Appium 2 へ移行する
|
||||
---
|
||||
|
||||
このドキュメントは既にAppium 1 を利用している人がAppium 2 に移行するための手引きです。破壊的変更の一覧や、実行環境・テストコードをAppium 2 互換にするための方法が含まれます。
|
||||
このドキュメントは既にAppium 1 を利用している人がAppium 2 に移行するための手引きです。 破壊的変更の一覧や、実行環境・テストコードをAppium 2 互換にするための方法が含まれます。
|
||||
|
||||
Appium 2 is the biggest Appium release in over 5 years. It is _not_ focused on changing the
|
||||
automation behavior for any particular platform, but instead re-envisions Appium into an
|
||||
@@ -111,12 +111,12 @@ The Appium 1 ecosystem included several drivers, clients and other packages that
|
||||
deprecated and replaced with newer packages. Appium 2 no longer includes support for these packages,
|
||||
and it is recommended to migrate to the following replacements:
|
||||
|
||||
| Appium 1 Package | Replacement in Appium 2 |
|
||||
| ------------------ | -------------------------------------------------------------------- |
|
||||
| iOS Driver | [XCUITest Driver](https://appium.github.io/appium-xcuitest-driver/) |
|
||||
| UiAutomator Driver | [UiAutomator2](https://appium.github.io/appium-uiautomator2-driver/) |
|
||||
| `wd` Client | [WebdriverIO Client](https://webdriver.io/) |
|
||||
| Appium Desktop | [Appium Inspector](https://appium.github.io/appium-inspector/) |
|
||||
| Appium 1 Package | Replacement in Appium 2 |
|
||||
| ------------------ | -------------------------------------------------------------------------- |
|
||||
| iOS Driver | [XCUITest Driver](https://appium.github.io/appium-xcuitest-driver/latest/) |
|
||||
| UiAutomator Driver | [UiAutomator2](https://github.com/appium/appium-uiautomator2-driver/) |
|
||||
| `wd` Client | [WebdriverIO Client](https://webdriver.io/) |
|
||||
| Appium Desktop | [Appium Inspector](https://github.com/appium/appium-inspector) |
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ title: Appium 3 へ移行する
|
||||
}
|
||||
</style>
|
||||
|
||||
このドキュメントは既にAppium 2 を利用している人がAppium 3 に移行するための手引きです。破壊的変更と、それらを処理するためのヒントが含まれています。
|
||||
このドキュメントは既にAppium 2 を利用している人がAppium 3 に移行するための手引きです。
|
||||
破壊的変更と、それらを処理するためのヒントが含まれています。
|
||||
|
||||
Appium 2 はAppiumアーキテクチャ全体の大きな見直しをしました。 Appium 3 は限られた破壊的変更のみの比較的小さな更新であり、移行プロセスがはるかに簡易になります。
|
||||
|
||||
@@ -141,293 +142,293 @@ Icons are used to indicate endpoint support in either certain drivers, or in the
|
||||
|
||||
- :simple-appium:{ .lg } - Appium server
|
||||
- :material-apple:{ .lg } - [XCUITest driver](https://appium.github.io/appium-xcuitest-driver/latest/)
|
||||
- :material-android:{ .lg } - [UiAutomator2 driver](https://appium.github.io/appium-uiautomator2-driver/)
|
||||
- :material-coffee:{ .lg } - [Espresso driver](https://appium.github.io/appium-espresso-driver/)
|
||||
- :material-apple-finder:{ .lg } - [Mac2 driver](https://appium.github.io/appium-mac2-driver/)
|
||||
- :material-android:{ .lg } - [UiAutomator2 driver](https://github.com/appium/appium-uiautomator2-driver/)
|
||||
- :material-coffee:{ .lg } - [Espresso driver](https://github.com/appium/appium-espresso-driver)
|
||||
- :material-apple-finder:{ .lg } - [Mac2 driver](https://github.com/appium/appium-mac2-driver)
|
||||
- :material-microsoft-windows:{ .lg } - [Windows driver](https://github.com/appium/appium-windows-driver)
|
||||
|
||||
</div>
|
||||
|
||||
- `GET /sessions`
|
||||
- :octicons-arrow-right-24: `GET /appium/sessions` :simple-appium:
|
||||
- :octicons-arrow-right-24: `GET /appium/sessions` :simple-appium:
|
||||
- `POST /session/:sessionId/accept_alert`
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/alert/accept` :simple-appium:
|
||||
- :octicons-arrow-right-24: `mobile: alert` [execute method](./execute-methods.md) :material-apple:
|
||||
- :octicons-arrow-right-24: `mobile: acceptAlert` execute method :material-android:
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/alert/accept` :simple-appium:
|
||||
- :octicons-arrow-right-24: `mobile: alert` [execute method](./execute-methods.md) :material-apple:
|
||||
- :octicons-arrow-right-24: `mobile: acceptAlert` execute method :material-android:
|
||||
- `GET /session/:sessionId/alert_text`
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/alert/text` :simple-appium:
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/alert/text` :simple-appium:
|
||||
- `POST /session/:sessionId/alert_text`
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/alert/text` :simple-appium:
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/alert/text` :simple-appium:
|
||||
- `POST /session/:sessionId/appium/app/background`
|
||||
- :octicons-arrow-right-24: `mobile: backgroundApp` execute method :material-apple: :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: backgroundApp` execute method :material-apple: :material-android: :material-coffee:
|
||||
- `POST /session/:sessionId/appium/app/close`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `mobile: terminateApp` execute method :material-apple: :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: terminateApp` execute method :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: closeApp` execute method :material-microsoft-windows:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `mobile: terminateApp` execute method :material-apple: :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: terminateApp` execute method :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: closeApp` execute method :material-microsoft-windows:
|
||||
- `POST /session/:sessionId/appium/app/end_test_coverage`
|
||||
- :octicons-arrow-right-24: `mobile: shell` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: shell` execute method :material-android: :material-coffee:
|
||||
- `POST /session/:sessionId/appium/app/launch`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `mobile: launchApp` execute method :material-apple:
|
||||
- :octicons-arrow-right-24: `mobile: activateApp` or `mobile: startActivity` execute methods :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: launchApp` or `macos: activateApp` execute methods :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: launchApp` execute method :material-microsoft-windows:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `mobile: launchApp` execute method :material-apple:
|
||||
- :octicons-arrow-right-24: `mobile: activateApp` or `mobile: startActivity` execute methods :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: launchApp` or `macos: activateApp` execute methods :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: launchApp` execute method :material-microsoft-windows:
|
||||
- `POST /session/:sessionId/appium/app/reset`
|
||||
- :octicons-arrow-right-24: `mobile: clearApp` execute method :material-apple: [^sim] :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: clearApp` execute method :material-apple: [^sim] :material-android: :material-coffee:
|
||||
- `POST /session/:sessionId/appium/app/strings`
|
||||
- :octicons-arrow-right-24: `mobile: getAppStrings` execute method :material-apple: :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: getAppStrings` execute method :material-apple: :material-android: :material-coffee:
|
||||
- `GET /session/:sessionId/appium/device/app_state`
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/appium/device/app_state` :simple-appium:
|
||||
- :octicons-arrow-right-24: `mobile: queryAppState` execute method :material-apple: :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: queryAppState` execute method :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/appium/device/app_state` :simple-appium:
|
||||
- :octicons-arrow-right-24: `mobile: queryAppState` execute method :material-apple: :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: queryAppState` execute method :material-apple-finder:
|
||||
- `GET /session/:sessionId/appium/device/current_activity`
|
||||
- :octicons-arrow-right-24: `mobile: getCurrentActivity` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: getCurrentActivity` execute method :material-android: :material-coffee:
|
||||
- `GET /session/:sessionId/appium/device/current_package`
|
||||
- :octicons-arrow-right-24: `mobile: getCurrentPackage` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: getCurrentPackage` execute method :material-android: :material-coffee:
|
||||
- `GET /session/:sessionId/appium/device/display_density`
|
||||
- :octicons-arrow-right-24: `mobile: getDisplayDensity` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: getDisplayDensity` execute method :material-android: :material-coffee:
|
||||
- `POST /session/:sessionId/appium/device/finger_print`
|
||||
- :octicons-arrow-right-24: `mobile: fingerPrint` execute method :material-android: [^sim] :material-coffee: [^sim]
|
||||
- :octicons-arrow-right-24: `mobile: fingerPrint` execute method :material-android: [^sim] :material-coffee: [^sim]
|
||||
- `POST /session/:sessionId/appium/device/get_clipboard`
|
||||
- :octicons-check-24: Moved to drivers: :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: getClipboard` execute method :material-apple: :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: getPasteboard` execute method :material-apple: [^sim]
|
||||
- :octicons-arrow-right-24: `windows: getClipboard` execute method :material-microsoft-windows:
|
||||
- :octicons-check-24: Moved to drivers: :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: getClipboard` execute method :material-apple: :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: getPasteboard` execute method :material-apple: [^sim]
|
||||
- :octicons-arrow-right-24: `windows: getClipboard` execute method :material-microsoft-windows:
|
||||
- `POST /session/:sessionId/appium/device/gsm_call`
|
||||
- :octicons-arrow-right-24: `mobile: gsmCall` execute method :material-android: [^sim] :material-coffee: [^sim]
|
||||
- :octicons-arrow-right-24: `mobile: gsmCall` execute method :material-android: [^sim] :material-coffee: [^sim]
|
||||
- `POST /session/:sessionId/appium/device/gsm_signal`
|
||||
- :octicons-arrow-right-24: `mobile: gsmSignal` execute method :material-android: [^sim] :material-coffee: [^sim]
|
||||
- :octicons-arrow-right-24: `mobile: gsmSignal` execute method :material-android: [^sim] :material-coffee: [^sim]
|
||||
- `POST /session/:sessionId/appium/device/gsm_voice`
|
||||
- :octicons-arrow-right-24: `mobile: gsmVoice` execute method :material-android: [^sim] :material-coffee: [^sim]
|
||||
- :octicons-arrow-right-24: `mobile: gsmVoice` execute method :material-android: [^sim] :material-coffee: [^sim]
|
||||
- `POST /session/:sessionId/appium/device/is_locked`
|
||||
- :octicons-arrow-right-24: `mobile: isLocked` execute method :material-apple: :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: isLocked` execute method :material-apple: :material-android: :material-coffee:
|
||||
- `POST /session/:sessionId/appium/device/keyevent`
|
||||
- :octicons-arrow-right-24: `mobile: keys` execute method :material-apple: (iPadOS only)
|
||||
- :octicons-arrow-right-24: `mobile: pressKey` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: keys` execute method :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `mobile: keys` execute method :material-apple: (iPadOS only)
|
||||
- :octicons-arrow-right-24: `mobile: pressKey` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: keys` execute method :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:
|
||||
- `POST /session/:sessionId/appium/device/lock`
|
||||
- :octicons-arrow-right-24: `mobile: lock` execute method :material-apple: :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: lock` execute method :material-apple: :material-android: :material-coffee:
|
||||
- `POST /session/:sessionId/appium/device/long_press_keycode`
|
||||
- :octicons-arrow-right-24: `mobile: pressKey` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: pressKey` execute method :material-android: :material-coffee:
|
||||
- `POST /session/:sessionId/appium/device/network_speed`
|
||||
- :octicons-arrow-right-24: `mobile: networkSpeed` execute method :material-android: [^sim] :material-coffee: [^sim]
|
||||
- :octicons-arrow-right-24: `mobile: networkSpeed` execute method :material-android: [^sim] :material-coffee: [^sim]
|
||||
- `POST /session/:sessionId/appium/device/open_notifications`
|
||||
- :octicons-arrow-right-24: `mobile: statusBar` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: openNotifications` execute method :material-android:
|
||||
- :octicons-arrow-right-24: `mobile: statusBar` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: openNotifications` execute method :material-android:
|
||||
- `POST /session/:sessionId/appium/device/power_ac`
|
||||
- :octicons-arrow-right-24: `mobile: powerAC` execute method :material-android: [^sim] :material-coffee: [^sim]
|
||||
- :octicons-arrow-right-24: `mobile: powerAC` execute method :material-android: [^sim] :material-coffee: [^sim]
|
||||
- `POST /session/:sessionId/appium/device/power_capacity`
|
||||
- :octicons-arrow-right-24: `mobile: powerCapacity` execute method :material-android: [^sim] :material-coffee: [^sim]
|
||||
- :octicons-arrow-right-24: `mobile: powerCapacity` execute method :material-android: [^sim] :material-coffee: [^sim]
|
||||
- `POST /session/:sessionId/appium/device/press_keycode`
|
||||
- :octicons-arrow-right-24: `mobile: keys` execute method :material-apple: (iPadOS only)
|
||||
- :octicons-arrow-right-24: `mobile: pressKey` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: keys` execute method :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `mobile: keys` execute method :material-apple: (iPadOS only)
|
||||
- :octicons-arrow-right-24: `mobile: pressKey` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: keys` execute method :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:
|
||||
- `POST /session/:sessionId/appium/device/send_sms`
|
||||
- :octicons-arrow-right-24: `mobile: sendSms` execute method :material-android: [^sim] :material-coffee: [^sim]
|
||||
- :octicons-arrow-right-24: `mobile: sendSms` execute method :material-android: [^sim] :material-coffee: [^sim]
|
||||
- `POST /session/:sessionId/appium/device/set_clipboard`
|
||||
- :octicons-arrow-right-24: `mobile: setClipboard` execute method :material-apple: :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: setPasteboard` execute method :material-apple: [^sim]
|
||||
- :octicons-arrow-right-24: `windows: setClipboard` execute method :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `mobile: setClipboard` execute method :material-apple: :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: setPasteboard` execute method :material-apple: [^sim]
|
||||
- :octicons-arrow-right-24: `windows: setClipboard` execute method :material-microsoft-windows:
|
||||
- `POST /session/:sessionId/appium/device/shake`
|
||||
- :octicons-arrow-right-24: `mobile: shake` execute method :material-apple: [^sim]
|
||||
- :octicons-arrow-right-24: `mobile: shake` execute method :material-apple: [^sim]
|
||||
- `POST /session/:sessionId/appium/device/start_activity`
|
||||
- :octicons-arrow-right-24: `mobile: startActivity` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: startActivity` execute method :material-android: :material-coffee:
|
||||
- `GET /session/:sessionId/appium/device/system_bars`
|
||||
- :octicons-arrow-right-24: `mobile: deviceScreenInfo` execute method :material-apple:
|
||||
- :octicons-arrow-right-24: `mobile: getSystemBars` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: deviceScreenInfo` execute method :material-apple:
|
||||
- :octicons-arrow-right-24: `mobile: getSystemBars` execute method :material-android: :material-coffee:
|
||||
- `POST /session/:sessionId/appium/device/toggle_airplane_mode`
|
||||
- :octicons-arrow-right-24: `mobile: setConnectivity` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: setConnectivity` execute method :material-android: :material-coffee:
|
||||
- `POST /session/:sessionId/appium/device/toggle_data`
|
||||
- :octicons-arrow-right-24: `mobile: setConnectivity` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: setConnectivity` execute method :material-android: :material-coffee:
|
||||
- `POST /session/:sessionId/appium/device/toggle_location_services`
|
||||
- :octicons-arrow-right-24: `mobile: toggleGps` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: toggleGps` execute method :material-android: :material-coffee:
|
||||
- `POST /session/:sessionId/appium/device/toggle_wifi`
|
||||
- :octicons-arrow-right-24: `mobile: setConnectivity` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: setConnectivity` execute method :material-android: :material-coffee:
|
||||
- `POST /session/:sessionId/appium/device/unlock`
|
||||
- :octicons-arrow-right-24: `mobile: unlock` execute method :material-apple: :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: unlock` execute method :material-apple: :material-android: :material-coffee:
|
||||
- `POST /session/:sessionId/appium/element/:elementId/value`
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/element/:elementId/value` :simple-appium:
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/element/:elementId/value` :simple-appium:
|
||||
- `POST /session/:sessionId/appium/element/:elementId/replace_value`
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/element/:elementId/value` :simple-appium:
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/element/:elementId/value` :simple-appium:
|
||||
- `POST /session/:sessionId/appium/getPerformanceData`
|
||||
- :octicons-arrow-right-24: `mobile: getPerformanceData` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: getPerformanceData` execute method :material-android: :material-coffee:
|
||||
- `POST /session/:sessionId/appium/performanceData/types`
|
||||
- :octicons-arrow-right-24: `mobile: getPerformanceDataTypes` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `mobile: getPerformanceDataTypes` execute method :material-android: :material-coffee:
|
||||
- `POST /session/:sessionId/appium/receive_async_response`
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/execute/async` :simple-appium:
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/execute/async` :simple-appium:
|
||||
- `POST /session/:sessionId/appium/simulator/toggle_touch_id_enrollment`
|
||||
- :octicons-arrow-right-24: `mobile: enrollBiometric` execute method :material-apple: [^sim]
|
||||
- :octicons-arrow-right-24: `mobile: enrollBiometric` execute method :material-apple: [^sim]
|
||||
- `POST /session/:sessionId/appium/simulator/touch_id`
|
||||
- :octicons-arrow-right-24: `mobile: sendBiometricMatch` execute method :material-apple: [^sim]
|
||||
- :octicons-arrow-right-24: `mobile: sendBiometricMatch` execute method :material-apple: [^sim]
|
||||
- `POST /session/:sessionId/appium/start_recording_screen`
|
||||
- :octicons-check-24: Moved to drivers: :material-apple: :material-android: :material-coffee: :material-apple-finder: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `mobile: startXCTestScreenRecording` execute method :material-apple:
|
||||
- :octicons-arrow-right-24: `mobile: startMediaProjectionRecording` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: startRecordingScreen` or `macos: startNativeScreenRecording` execute methods :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: startRecordingScreen` execute method :material-microsoft-windows:
|
||||
- :octicons-check-24: Moved to drivers: :material-apple: :material-android: :material-coffee: :material-apple-finder: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `mobile: startXCTestScreenRecording` execute method :material-apple:
|
||||
- :octicons-arrow-right-24: `mobile: startMediaProjectionRecording` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: startRecordingScreen` or `macos: startNativeScreenRecording` execute methods :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: startRecordingScreen` execute method :material-microsoft-windows:
|
||||
- `POST /session/:sessionId/appium/stop_recording_screen`
|
||||
- :octicons-check-24: Moved to drivers: :material-apple: :material-android: :material-coffee: :material-apple-finder: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `mobile: stopXCTestScreenRecording` execute method :material-apple:
|
||||
- :octicons-arrow-right-24: `mobile: stopMediaProjectionRecording` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: stopRecordingScreen` or `macos: stopNativeScreenRecording` execute methods :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: stopRecordingScreen` execute method :material-microsoft-windows:
|
||||
- :octicons-check-24: Moved to drivers: :material-apple: :material-android: :material-coffee: :material-apple-finder: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `mobile: stopXCTestScreenRecording` execute method :material-apple:
|
||||
- :octicons-arrow-right-24: `mobile: stopMediaProjectionRecording` execute method :material-android: :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: stopRecordingScreen` or `macos: stopNativeScreenRecording` execute methods :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: stopRecordingScreen` execute method :material-microsoft-windows:
|
||||
- `GET /session/:sessionId/application_cache/status`
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- `POST /session/:sessionId/buttondown`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: [W3C Actions API](https://www.selenium.dev/documentation/webdriver/actions_api/) (`pointerDown`) :simple-appium:
|
||||
- :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: [W3C Actions API](https://www.selenium.dev/documentation/webdriver/actions_api/) (`pointerDown`) :simple-appium:
|
||||
- :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:
|
||||
- `POST /session/:sessionId/buttonup`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerUp`) :simple-appium:
|
||||
- :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerUp`) :simple-appium:
|
||||
- :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:
|
||||
- `POST /session/:sessionId/click`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerDown` & `pointerUp`) :simple-appium:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerDown` & `pointerUp`) :simple-appium:
|
||||
- `POST /session/:sessionId/dismiss_alert`
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/alert/dismiss` :simple-appium:
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/alert/dismiss` :simple-appium:
|
||||
- `POST /session/:sessionId/doubleclick`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerDown` & `pointerUp`) :simple-appium:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerDown` & `pointerUp`) :simple-appium:
|
||||
- `POST /session/:sessionId/element/active`
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/element/active` :simple-appium:
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/element/active` :simple-appium:
|
||||
- `GET /session/:sessionId/element/:elementId/equals/:otherId`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- `GET /session/:sessionId/element/:elementId/location`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/element/:elementId/rect` :simple-appium:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/element/:elementId/rect` :simple-appium:
|
||||
- `GET /session/:sessionId/element/:elementId/location_in_view`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- `GET /session/:sessionId/element/:elementId/pageIndex`
|
||||
- :octicons-no-entry-24: MJSONWP protocol command with no direct replacement
|
||||
- :octicons-no-entry-24: MJSONWP protocol command with no direct replacement
|
||||
- `GET /session/:sessionId/element/:elementId/size`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/element/:elementId/rect` :simple-appium:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/element/:elementId/rect` :simple-appium:
|
||||
- `POST /session/:sessionId/element/:elementId/submit`
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- `POST /session/:sessionId/execute`
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/execute/sync` :simple-appium:
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/execute/sync` :simple-appium:
|
||||
- `POST /session/:sessionId/execute_async`
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/execute/async` :simple-appium:
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/execute/async` :simple-appium:
|
||||
- `POST /session/:sessionId/keys`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`keyDown` & `keyUp`) :simple-appium:
|
||||
- Selenium-based clients can also use [Send Keys](https://www.selenium.dev/documentation/webdriver/actions_api/keyboard/#send-keys)
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`keyDown` & `keyUp`) :simple-appium:
|
||||
- Selenium-based clients can also use [Send Keys](https://www.selenium.dev/documentation/webdriver/actions_api/keyboard/#send-keys)
|
||||
- `GET /session/:sessionId/local_storage`
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- `POST /session/:sessionId/local_storage`
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- `DELETE /session/:sessionId/local_storage`
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- `GET /session/:sessionId/local_storage/key/:key`
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- `DELETE /session/:sessionId/local_storage/key/:key`
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- `GET /session/:sessionId/local_storage/size`
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- `POST /session/:sessionId/log`
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/se/log` :simple-appium:
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/se/log` :simple-appium:
|
||||
- `GET /session/:sessionId/log/types`
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/se/log/types` :simple-appium:
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/se/log/types` :simple-appium:
|
||||
- `POST /session/:sessionId/moveto`
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerMove`) :simple-appium:
|
||||
- Selenium-based clients can also use [Move by Offset](https://www.selenium.dev/documentation/webdriver/actions_api/mouse/#move-by-offset)
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerMove`) :simple-appium:
|
||||
- Selenium-based clients can also use [Move by Offset](https://www.selenium.dev/documentation/webdriver/actions_api/mouse/#move-by-offset)
|
||||
- `GET /session/:sessionId/screenshot/:elementId`
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/element/:elementId/screenshot` :simple-appium:
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/element/:elementId/screenshot` :simple-appium:
|
||||
- `GET /session/:sessionId/session_storage`
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- `POST /session/:sessionId/session_storage`
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- `DELETE /session/:sessionId/session_storage`
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- `GET /session/:sessionId/session_storage/key/:key`
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- `DELETE /session/:sessionId/session_storage/key/:key`
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- `GET /session/:sessionId/session_storage/size`
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- :octicons-no-entry-24: JSONWP protocol command with no direct replacement
|
||||
- `POST /session/:sessionId/timeouts/async_script`
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/timeouts` :simple-appium:
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/timeouts` :simple-appium:
|
||||
- `POST /session/:sessionId/timeouts/implicit_wait`
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/timeouts` :simple-appium:
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/timeouts` :simple-appium:
|
||||
- `POST /session/:sessionId/touch/click`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerDown` & `pointerUp`) :simple-appium:
|
||||
- Selenium-based clients can also use [Click and Release](https://www.selenium.dev/documentation/webdriver/actions_api/mouse/#click-and-release)
|
||||
- :octicons-arrow-right-24: `mobile: tap` or `mobile: tapWithNumberOfTaps` execute methods :material-apple:
|
||||
- :octicons-arrow-right-24: `mobile: clickGesture` execute method :material-android:
|
||||
- :octicons-arrow-right-24: `mobile: clickAction` execute method :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: click`, `macos: rightClick`, `macos: press` or `macos: tap` execute methods :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: click` execute method :material-microsoft-windows:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerDown` & `pointerUp`) :simple-appium:
|
||||
- Selenium-based clients can also use [Click and Release](https://www.selenium.dev/documentation/webdriver/actions_api/mouse/#click-and-release)
|
||||
- :octicons-arrow-right-24: `mobile: tap` or `mobile: tapWithNumberOfTaps` execute methods :material-apple:
|
||||
- :octicons-arrow-right-24: `mobile: clickGesture` execute method :material-android:
|
||||
- :octicons-arrow-right-24: `mobile: clickAction` execute method :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: click`, `macos: rightClick`, `macos: press` or `macos: tap` execute methods :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: click` execute method :material-microsoft-windows:
|
||||
- `POST /session/:sessionId/touch/doubleclick`
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerDown` & `pointerUp`) :simple-appium:
|
||||
- Selenium-based clients can also use [Double Click](https://www.selenium.dev/documentation/webdriver/actions_api/mouse/#double-click)
|
||||
- :octicons-arrow-right-24: `mobile: doubleTap` or `mobile: tapWithNumberOfTaps` execute methods :material-apple:
|
||||
- :octicons-arrow-right-24: `mobile: doubleClickGesture` execute method :material-android:
|
||||
- :octicons-arrow-right-24: `mobile: clickAction` execute method :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: doubleClick` or `macos: doubleTap` execute methods :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: click` execute method :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerDown` & `pointerUp`) :simple-appium:
|
||||
- Selenium-based clients can also use [Double Click](https://www.selenium.dev/documentation/webdriver/actions_api/mouse/#double-click)
|
||||
- :octicons-arrow-right-24: `mobile: doubleTap` or `mobile: tapWithNumberOfTaps` execute methods :material-apple:
|
||||
- :octicons-arrow-right-24: `mobile: doubleClickGesture` execute method :material-android:
|
||||
- :octicons-arrow-right-24: `mobile: clickAction` execute method :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: doubleClick` or `macos: doubleTap` execute methods :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: click` execute method :material-microsoft-windows:
|
||||
- `POST /session/:sessionId/touch/down`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerDown`) :simple-appium:
|
||||
- :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerDown`) :simple-appium:
|
||||
- :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:
|
||||
- `POST /session/:sessionId/touch/flick`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerDown`, `pointerMove` & `pointerUp`) :simple-appium:
|
||||
- :octicons-arrow-right-24: `mobile: flingGesture` execute method :material-android:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerDown`, `pointerMove` & `pointerUp`) :simple-appium:
|
||||
- :octicons-arrow-right-24: `mobile: flingGesture` execute method :material-android:
|
||||
- `POST /session/:sessionId/touch/longclick`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerDown`, `pause` & `pointerUp`) :simple-appium:
|
||||
- :octicons-arrow-right-24: `mobile: touchAndHold` execute method :material-apple:
|
||||
- :octicons-arrow-right-24: `mobile: longClickGesture` execute method :material-android:
|
||||
- :octicons-arrow-right-24: `mobile: clickAction` execute method :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: press` execute method :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: click` execute method :material-microsoft-windows:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerDown`, `pause` & `pointerUp`) :simple-appium:
|
||||
- :octicons-arrow-right-24: `mobile: touchAndHold` execute method :material-apple:
|
||||
- :octicons-arrow-right-24: `mobile: longClickGesture` execute method :material-android:
|
||||
- :octicons-arrow-right-24: `mobile: clickAction` execute method :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: press` execute method :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: click` execute method :material-microsoft-windows:
|
||||
- `POST /session/:sessionId/touch/multi/perform`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/actions` :simple-appium:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/actions` :simple-appium:
|
||||
- `POST /session/:sessionId/touch/move`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerMove`) :simple-appium:
|
||||
- Selenium-based clients can also use [Move by Offset](https://www.selenium.dev/documentation/webdriver/actions_api/mouse/#move-by-offset)
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerMove`) :simple-appium:
|
||||
- Selenium-based clients can also use [Move by Offset](https://www.selenium.dev/documentation/webdriver/actions_api/mouse/#move-by-offset)
|
||||
- `POST /session/:sessionId/touch/perform`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/actions` :simple-appium:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/actions` :simple-appium:
|
||||
- `POST /session/:sessionId/touch/scroll`
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerDown`, `pointerMove` & `pointerUp`) :simple-appium:
|
||||
- :octicons-arrow-right-24: `mobile: scroll` or `mobile: swipe` execute methods :material-apple:
|
||||
- :octicons-arrow-right-24: `mobile: scrollGesture` or `mobile: swipeGesture` execute methods :material-android:
|
||||
- :octicons-arrow-right-24: `mobile: swipe` execute method :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: scroll` or `macos: swipe` execute methods :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: scroll` execute method :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerDown`, `pointerMove` & `pointerUp`) :simple-appium:
|
||||
- :octicons-arrow-right-24: `mobile: scroll` or `mobile: swipe` execute methods :material-apple:
|
||||
- :octicons-arrow-right-24: `mobile: scrollGesture` or `mobile: swipeGesture` execute methods :material-android:
|
||||
- :octicons-arrow-right-24: `mobile: swipe` execute method :material-coffee:
|
||||
- :octicons-arrow-right-24: `macos: scroll` or `macos: swipe` execute methods :material-apple-finder:
|
||||
- :octicons-arrow-right-24: `windows: scroll` execute method :material-microsoft-windows:
|
||||
- `POST /session/:sessionId/touch/up`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerUp`) :simple-appium:
|
||||
- :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: W3C Actions API (`pointerUp`) :simple-appium:
|
||||
- :octicons-arrow-right-24: `windows: keys` execute method :material-microsoft-windows:
|
||||
- `GET /session/:sessionId/window_handle`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/window` :simple-appium:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/window` :simple-appium:
|
||||
- `GET /session/:sessionId/window_handles`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/window/handles` :simple-appium:
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/window/handles` :simple-appium:
|
||||
- `GET /session/:sessionId/window/handle`
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/window` :simple-appium:
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/window` :simple-appium:
|
||||
- `POST /session/:sessionId/window/:windowhandle/maximize`
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/window/maximize` :simple-appium:
|
||||
- :fontawesome-solid-triangle-exclamation: Only supported for the current window
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/window/maximize` :simple-appium:
|
||||
- :fontawesome-solid-triangle-exclamation: Only supported for the current window
|
||||
- `GET /session/:sessionId/window/:windowhandle/position`
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/window/rect` :simple-appium:
|
||||
- :fontawesome-solid-triangle-exclamation: Only supported for the current window
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/window/rect` :simple-appium:
|
||||
- :fontawesome-solid-triangle-exclamation: Only supported for the current window
|
||||
- `POST /session/:sessionId/window/:windowhandle/position`
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/window/rect` :simple-appium:
|
||||
- :fontawesome-solid-triangle-exclamation: Only supported for the current window
|
||||
- :octicons-arrow-right-24: `POST /session/:sessionId/window/rect` :simple-appium:
|
||||
- :fontawesome-solid-triangle-exclamation: Only supported for the current window
|
||||
- `GET /session/:sessionId/window/:windowhandle/size`
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/window/rect` :simple-appium:
|
||||
- :fontawesome-solid-triangle-exclamation: Only supported for the current window
|
||||
- :octicons-check-24: Moved to drivers: :material-microsoft-windows:
|
||||
- :octicons-arrow-right-24: `GET /session/:sessionId/window/rect` :simple-appium:
|
||||
- :fontawesome-solid-triangle-exclamation: Only supported for the current window
|
||||
|
||||
### Modified
|
||||
|
||||
@@ -436,19 +437,22 @@ parameters (note that no new parameters have been added). Each endpoint lists th
|
||||
longer accepts, as well as the parameters it continues to accept in Appium 3.
|
||||
|
||||
- `POST /session`
|
||||
- :octicons-x-24: `desiredCapabilities`, `requiredCapabilities`
|
||||
- :octicons-check-24: `capabilities`
|
||||
- :octicons-x-24: `desiredCapabilities`, `requiredCapabilities`
|
||||
- :octicons-check-24: `capabilities`
|
||||
- `POST /session/:sessionId/alert/text`
|
||||
- :octicons-x-24: `value`
|
||||
- :octicons-check-24: `text`
|
||||
- :octicons-x-24: `value`
|
||||
- :octicons-check-24: `text`
|
||||
- `GET /session/:sessionId/appium/device/system_time`
|
||||
- :octicons-x-24: `format`
|
||||
- :octicons-check-24: None
|
||||
- :octicons-x-24: `format`
|
||||
- :octicons-check-24: None
|
||||
- `POST /session/:sessionId/element/:elementId/value`
|
||||
- :octicons-x-24: `value`
|
||||
- :octicons-check-24: `text`
|
||||
- :octicons-x-24: `value`
|
||||
- :octicons-check-24: `text`
|
||||
- `POST /session/:sessionId/timeouts`
|
||||
- :octicons-x-24: `type`, `ms`
|
||||
- :octicons-check-24: `script`, `pageLoad`, `implicit`
|
||||
- `POST /session/:sessionId/window`
|
||||
- :octicons-x-24: `name`
|
||||
- :octicons-check-24: `handle`
|
||||
- :octicons-x-24: `name`
|
||||
- :octicons-check-24: `handle`
|
||||
|
||||
[^sim]: Supported in emulators/simulators only
|
||||
|
||||
@@ -23,9 +23,9 @@ title: How Does Appium Work?
|
||||
|
||||
iOSとAndroidだけでなくより多くのアプリプラットフォームが存在していることを考えると、その背景には別の、より大きな疑問が潜んでいます。
|
||||
|
||||
- どのようにして_全ての_プラットフォームに対して自動化を実現するか?
|
||||
- どのようにして_全ての_プラットフォームに対して自動化を実現するか?
|
||||
|
||||
これらの疑問へのAppiumの答えを知ることは、Appiumが何かを学ぶ最短の方法ではないかもしれませんが、確かな道になります。では、見ていきましょう。
|
||||
これらの疑問へのAppiumの答えを知ることは、Appiumが何かを学ぶ最短の方法ではないかもしれませんが、確かな道になります。 では、見ていきましょう。
|
||||
|
||||
## Appium's choice of API
|
||||
|
||||
|
||||
@@ -49,8 +49,8 @@ async setUrl(url) {
|
||||
|
||||
[^1]: You might notice that `setUrl` doesn't look anything like `Navigate To`, so how did we know
|
||||
to use it rather than some other random string? Well, Appium's WebDriver-protocol-to-method-name
|
||||
mappings are defined in special files within the `@appium/base-driver` package's
|
||||
[routes/](https://github.com/appium/appium/tree/master/packages/base-driver/lib/protocol/routes) directory.
|
||||
mapping is defined in a special file within the `@appium/base-driver` package called
|
||||
[routes.js](https://github.com/appium/appium/blob/master/packages/base-driver/lib/protocol/routes.js).
|
||||
So if you're writing a driver, this is where you would go to figure out what method names to use
|
||||
and what parameters to expect. Or you could look at the source for any of the main Appium
|
||||
drivers!
|
||||
@@ -81,7 +81,7 @@ from there is up to you, the driver author!
|
||||
## Automation mapping
|
||||
|
||||
But _typically_ what driver authors want to do is to provide automation behaviours for a given
|
||||
platform(s) that are semantically very similar to the WebDriver spec implementations for
|
||||
platform(s) that are semantically very similar to the the WebDriver spec implementations for
|
||||
browsers. When you want to find an element, you should get a reference to a UI element. When you
|
||||
want to click or tap that element, the resulting behaviour should be the same as if a person were
|
||||
to click or tap on the element. And so on.
|
||||
@@ -175,7 +175,7 @@ be passed back directly to the client, without any XCUITest driver code seeing i
|
||||
This architectural pattern provides a nice bonus for driver authors who choose to deal with the
|
||||
WebDriver protocol everywhere, rather than constructing bespoke protocols. It also means that
|
||||
Appium can create wrapper drivers for any other existing WebDriver implementation very easily. If
|
||||
you look at the [Appium Safari driver](https://appium.github.io/appium-safari-driver/) code, for
|
||||
you look at the [Appium Safari driver](https://github.com/appium/appium-safari-driver) code, for
|
||||
example, you'll see that it implements basically no standard commands, because all of these are
|
||||
proxied directly to an underlying SafariDriver process.
|
||||
|
||||
|
||||
@@ -5,19 +5,19 @@ hide:
|
||||
title: Getting Started
|
||||
---
|
||||
|
||||
さっそくAppiumを使ってみましょう!このクイックスタートをうまく使うために、[はじめに](../intro/index.md)を読み、Appiumの実行やスクリプトの記述に関わる概念を理解することをお勧めします。
|
||||
さっそくAppiumを使ってみましょう! このクイックスタートをうまく使うために、[はじめに](../intro/index.md)を読み、Appiumの実行やスクリプトの記述に関わる概念を理解することをお勧めします。
|
||||
|
||||
このクイックスタートは以下の通り進めます:
|
||||
|
||||
1. Appiumをインストールする
|
||||
2. Appiumドライバーとその依存関係をインストールする
|
||||
- This guide provides instructions for the [UiAutomator2 driver](https://appium.github.io/appium-uiautomator2-driver/)
|
||||
- このガイドでは、[UiAutomator2 driver](https://github.com/appium/appium-uiautomator2-driver) について説明します
|
||||
3. お好みの言語でAppiumクライアント・ライブラリをインストールする
|
||||
- このガイドでは、JavaScript、Python、Java、Ruby、.NETの例で説明します
|
||||
4. サンプルアプリケーションを使用した簡単なAppiumでの自動化スクリプトの作成と実行
|
||||
|
||||
### 必要条件
|
||||
|
||||
始める前に、お使いのシステムが[要件](../quickstart/requirements.md) を満たしていることを確認してください。追加要件については、UiAutomator2 ドライバーのインストールと合わせて説明します。また、このガイドでは基本的なコマンド実行や環境変数の設定と保持などができることを前提としています。
|
||||
始める前に、お使いのシステムが[要件](../quickstart/requirements.md) を満たしていることを確認してください。 追加要件については、UiAutomator2 ドライバーのインストールと合わせて説明します。 また、このガイドでは基本的なコマンド実行や環境変数の設定と保持などができることを前提としています。
|
||||
|
||||
さあ、これで準備は整いました! [Appiumのインストール](./install.md)に進んでください。
|
||||
|
||||
@@ -5,16 +5,14 @@ hide:
|
||||
title: 次のステップ
|
||||
---
|
||||
|
||||
Android自動化用のシステムの設定と簡単なテストの実行が完了したら、このドキュメントを引き続き参照してください。特に初心者にとって、これらは優れたガイドと参考資料です:
|
||||
Android自動化用のシステムの設定と簡単なテストの実行が完了したら、このドキュメントを引き続き参照してください。 特に初心者にとって、これらは優れたガイドと参考資料です:
|
||||
|
||||
- [エコシステム](../ecosystem/index.md) ページ: 利用可能なドライバー、クライアント、プラグイン、ツールを見る
|
||||
- [Appium ドライバーとプラグインの管理](../guides/managing-exts.md)
|
||||
- [Capabilities](../guides/caps.md)
|
||||
- [Settings](../guides/settings.md)
|
||||
|
||||
You'll also find that the [Appium Inspector](https://appium.github.io/appium-inspector/) is an
|
||||
indispensable tool for writing Appium tests, as it enables visual inspection of apps and
|
||||
helps you to discover element locators for use in your test scripts.
|
||||
また、[Appium Inspector](https://github.com/appium/appium-inspector) は、アプリの視覚的な検査を可能にし、テストスクリプトで使用する要素ロケーターを見つけるのに役立つ、Appium テストの作成に不可欠なツールです。
|
||||
|
||||
また、多くのオンライン Appium コースもご活用いただけます。
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ The `appium_lib_core` is the main part as an Appium client.
|
||||
`appium_lib_core` does not have such a global variable.
|
||||
|
||||
This example is by the `appium_lib_core` with `test-unit` gem module.
|
||||
Test code in `appium_lib` should be similar.
|
||||
Tes code in `appium_lib` should be similar.
|
||||
|
||||
```ruby title="test.rb"
|
||||
--8<-- "./sample-code/quickstarts/rb/test.rb"
|
||||
|
||||
@@ -109,7 +109,7 @@ appium setup
|
||||
```
|
||||
|
||||
Running this will install Appium's mobile-specific drivers: UiAutomator2, [XCUITest](https://appium.github.io/appium-xcuitest-driver/)
|
||||
(only if running macOS), and [Espresso](https://appium.github.io/appium-espresso-driver/).
|
||||
(only if running macOS), and [Espresso](https://github.com/appium/appium-espresso-driver).
|
||||
|
||||
You can also use this command to batch install drivers for desktop applications or desktop browsers.
|
||||
For more details on this, refer to the [Setup command documentation](../reference/cli/setup.md).
|
||||
|
||||
@@ -90,7 +90,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-maps.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.ts)
|
||||
for a detailed structure of this object.
|
||||
|
||||
### listExtensions
|
||||
@@ -104,7 +104,7 @@ 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-maps.ts)
|
||||
origin (driver-specific or plugin-specific). Refer to [the type definition file](https://github.com/appium/appium/blob/master/packages/types/lib/command.ts)
|
||||
for a detailed structure of this object.
|
||||
|
||||
### getCurrentAppiumContext
|
||||
|
||||
@@ -47,7 +47,7 @@ Subscribes to one or more BiDi events.
|
||||
|
||||
#### Response
|
||||
|
||||
`{subscription: string}` — a unique subscription ID that can be passed to `session.unsubscribe`.
|
||||
`null`
|
||||
|
||||
### bidiUnsubscribe
|
||||
|
||||
@@ -57,20 +57,15 @@ session.unsubscribe
|
||||
|
||||
> WebDriver BiDi documentation: [session.unsubscribe](https://w3c.github.io/webdriver-bidi/#command-session-unsubscribe)
|
||||
|
||||
Unsubscribes using either previously returned subscription IDs or event names.
|
||||
Removing a subscription ID preserves any overlapping subscriptions.
|
||||
Unsubscribes from one or more BiDi events.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Description | Type | Default |
|
||||
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | ------- |
|
||||
| `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.
|
||||
| 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[] | |
|
||||
|
||||
#### Response
|
||||
|
||||
`{}`
|
||||
`null`
|
||||
|
||||
@@ -82,7 +82,7 @@ appium {driver|plugin} install <install-spec>
|
||||
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| None | The short name of an official extension, with optional modifiers as supported by `npm install` (e.g. version or tag) |
|
||||
| `git` | The Git URL of the extension |
|
||||
| `github` | The GitHub repository slug of the extension, in the form `<org>/<repo>` |
|
||||
| `github` | The GitHub repository URL of the extension |
|
||||
| `local` | The local path to the extension containing its `package.json` file |
|
||||
| `npm` | The name of the `npm` package, with optional modifiers as supported by `npm install` (e.g. version or tag) |
|
||||
|
||||
@@ -115,7 +115,7 @@ appium {driver|plugin} install <install-spec>
|
||||
- Install the XCUITest driver from GitHub:
|
||||
|
||||
```
|
||||
appium driver install appium/appium-xcuitest-driver --source=github --package=appium-xcuitest-driver
|
||||
appium driver install https://github.com/appium/appium-xcuitest-driver --source=github --package=appium-xcuitest-driver
|
||||
```
|
||||
|
||||
- Install the XCUITest driver using a Git URL:
|
||||
|
||||
@@ -26,12 +26,12 @@ appium
|
||||
|
||||
| <div style="width:15em">Argument</div> | Description | Type | <div style="width:7em">Default</div> |
|
||||
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -------------------------------------------------------- |
|
||||
| `--address`, `-a` | IPv4/IPv6 address or a hostname to listen on | string | `0.0.0.0` |
|
||||
| `--address`, `-a` | IPv4/IPv6 address 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 | same as `--address` |
|
||||
| `--callback-address`, `-ca` | Callback IP address | string | `0.0.0.0` |
|
||||
| `--callback-port`, `-cp` | Callback port | integer | `4723` |
|
||||
| `--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` |
|
||||
|
||||
@@ -34,7 +34,7 @@ default value.
|
||||
| `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 page source and its printing to the Appium log, whenever a request to find an element fails | `boolean` | |
|
||||
| `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` | |
|
||||
|
||||
### Validated Capabilities
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ nav:
|
||||
- reference/api/plugins.md
|
||||
- Guides:
|
||||
- Migration:
|
||||
- guides/migrating-3-to-4.md
|
||||
- guides/migrating-2-to-3.md
|
||||
- guides/migrating-1-to-2.md
|
||||
- Server/Driver Configuration:
|
||||
|
||||
@@ -10,18 +10,16 @@
|
||||
/* eslint-disable promise/prefer-await-to-callbacks */
|
||||
/* eslint-disable promise/prefer-await-to-then */
|
||||
|
||||
const {
|
||||
log,
|
||||
LANGS,
|
||||
DOCS_DIR,
|
||||
DOCS_BRANCH,
|
||||
DOCS_PREFIX,
|
||||
DOCS_REMOTE,
|
||||
LATEST_ALIAS,
|
||||
} = require('./utils');
|
||||
const path = require('node:path');
|
||||
const semver = require('semver');
|
||||
const {version} = require('../../package.json');
|
||||
import {readFileSync} from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import {fileURLToPath} from 'node:url';
|
||||
|
||||
import {deploy, buildSite} from '@appium/docutils';
|
||||
import semver from 'semver';
|
||||
|
||||
import {log, LANGS, DOCS_DIR, DOCS_BRANCH, DOCS_PREFIX, DOCS_REMOTE, LATEST_ALIAS} from './utils.js';
|
||||
|
||||
const {version} = JSON.parse(readFileSync(new URL('../../package.json', import.meta.url), 'utf8'));
|
||||
|
||||
const branch = process.env.APPIUM_DOCS_BRANCH ?? DOCS_BRANCH;
|
||||
const basePrefix = process.env.APPIUM_DOCS_PREFIX ?? DOCS_PREFIX;
|
||||
@@ -34,9 +32,6 @@ const push = Boolean(process.env.APPIUM_DOCS_PUBLISH);
|
||||
* Builds and optionally deploys docs for each supported language.
|
||||
*/
|
||||
async function main() {
|
||||
// @appium/docutils is ESM-only; this file is CommonJS, so it must be loaded dynamically
|
||||
const {deploy, buildSite} = await import('@appium/docutils');
|
||||
|
||||
log.info(`Building Appium docs and committing to ${DOCS_BRANCH}`);
|
||||
|
||||
const semVersion = semver.parse(version);
|
||||
@@ -69,10 +64,10 @@ async function main() {
|
||||
}
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
if (process.argv[1] === fileURLToPath(import.meta.url)) {
|
||||
main().catch((err) => {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = main;
|
||||
export default main;
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
/**
|
||||
* Validates `docs/en/llms.txt` against the documentation sources.
|
||||
*
|
||||
* `llms.txt` is hand-written, so nothing regenerates it when a page is added, renamed or removed.
|
||||
* This check fails the build when it points at a page that no longer exists, and when a page has
|
||||
* been added without being listed.
|
||||
*
|
||||
* For simplicity this file is not transpiled and is run directly via an npm script.
|
||||
* @module
|
||||
*/
|
||||
|
||||
// @ts-check
|
||||
|
||||
/* eslint-disable no-console */
|
||||
|
||||
const fs = require('node:fs/promises');
|
||||
const path = require('node:path');
|
||||
|
||||
const DOCS_EN_DIR = path.resolve(__dirname, '..', 'en');
|
||||
const LLMS_TXT_PATH = path.join(DOCS_EN_DIR, 'llms.txt');
|
||||
|
||||
/**
|
||||
* Base URL that every link to our own documentation must use. `llms.txt` is served from a versioned
|
||||
* directory but is consumed out of context, so the links inside it have to be absolute, and they
|
||||
* have to point at the `latest` alias rather than at a pinned version.
|
||||
*/
|
||||
const SITE_BASE_URL = 'https://appium.io/docs/en/latest';
|
||||
|
||||
/**
|
||||
* Pages that are deliberately absent from `llms.txt`, and should not be warned about.
|
||||
*/
|
||||
const UNLISTED_PAGES = [
|
||||
// individual blog posts; the blog index is listed instead
|
||||
/^blog\/posts\//,
|
||||
];
|
||||
|
||||
/**
|
||||
* Extracts the target of every Markdown link in `contents`.
|
||||
* @param {string} contents
|
||||
* @returns {string[]}
|
||||
*/
|
||||
function extractLinks(contents) {
|
||||
return [...contents.matchAll(/\[[^\]]+\]\(([^)\s]+)\)/g)].map(([, url]) => url);
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps a documentation URL back to the source files that could have produced it.
|
||||
*
|
||||
* MkDocs builds directory URLs by default, so `guides/caps.md` is served at `guides/caps/`, and
|
||||
* `intro/index.md` is served at `intro/`. Both spellings are accepted here.
|
||||
*
|
||||
* @param {string} url an URL underneath {@linkcode SITE_BASE_URL}
|
||||
* @returns {string[]} candidate paths, relative to the `en` docs dir
|
||||
*/
|
||||
function candidateSourcePaths(url) {
|
||||
const withoutBase = url.slice(SITE_BASE_URL.length);
|
||||
const pagePath = withoutBase.replace(/#.*$/, '').replace(/^\//, '').replace(/\/$/, '');
|
||||
if (!pagePath) {
|
||||
return ['index.md'];
|
||||
}
|
||||
return [`${pagePath}.md`, path.posix.join(pagePath, 'index.md')];
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds every Markdown page in the English docs, as paths relative to the `en` docs dir.
|
||||
* @returns {Promise<string[]>}
|
||||
*/
|
||||
async function findAllPages() {
|
||||
const entries = await fs.readdir(DOCS_EN_DIR, {recursive: true});
|
||||
return entries
|
||||
.map((entry) => entry.split(path.sep).join(path.posix.sep))
|
||||
.filter((entry) => entry.endsWith('.md'))
|
||||
.sort();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that every documentation link in `llms.txt` resolves to a source file.
|
||||
* @param {string[]} links
|
||||
* @returns {Promise<string[]>} error messages
|
||||
*/
|
||||
async function findBrokenLinks(links) {
|
||||
const errors = [];
|
||||
for (const link of links) {
|
||||
const isOurDocs = link.includes('appium.io/docs/') || link.startsWith('/docs/');
|
||||
// relative and site-relative links do not survive being read out of context, and a link to our
|
||||
// docs that is not under the `latest` alias goes stale as soon as a new version is released
|
||||
const isAbsolute = /^[a-z][a-z\d+.-]*:/i.test(link);
|
||||
if ((!isAbsolute || isOurDocs) && !link.startsWith(SITE_BASE_URL)) {
|
||||
errors.push(`${link}\n must be an absolute link under ${SITE_BASE_URL}`);
|
||||
continue;
|
||||
}
|
||||
if (!link.startsWith(SITE_BASE_URL)) {
|
||||
// external link; not ours to validate
|
||||
continue;
|
||||
}
|
||||
const candidates = candidateSourcePaths(link);
|
||||
const found = await Promise.all(
|
||||
candidates.map(async (candidate) => {
|
||||
try {
|
||||
await fs.access(path.join(DOCS_EN_DIR, candidate));
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
);
|
||||
if (!found.includes(true)) {
|
||||
errors.push(`${link}\n no such page (looked for ${candidates.join(' and ')})`);
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds pages that exist but are not linked from `llms.txt`.
|
||||
* @param {string[]} links
|
||||
* @param {string[]} pages
|
||||
* @returns {string[]}
|
||||
*/
|
||||
function findUnlistedPages(links, pages) {
|
||||
const linked = new Set(
|
||||
links
|
||||
.filter((link) => link.startsWith(SITE_BASE_URL))
|
||||
.flatMap((link) => candidateSourcePaths(link))
|
||||
);
|
||||
return pages.filter(
|
||||
(page) => !linked.has(page) && !UNLISTED_PAGES.some((pattern) => pattern.test(page))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates `llms.txt`. Both broken links and unlisted pages fail the build.
|
||||
*/
|
||||
async function main() {
|
||||
const contents = await fs.readFile(LLMS_TXT_PATH, 'utf-8');
|
||||
const links = extractLinks(contents);
|
||||
const pages = await findAllPages();
|
||||
|
||||
const brokenLinks = await findBrokenLinks(links);
|
||||
const unlistedPages = findUnlistedPages(links, pages);
|
||||
|
||||
if (unlistedPages.length) {
|
||||
console.error(
|
||||
`\nERROR: ${unlistedPages.length} page(s) are not listed in llms.txt. Add them, or add ` +
|
||||
`them to UNLISTED_PAGES in this script if they are intentionally omitted:`
|
||||
);
|
||||
for (const page of unlistedPages) {
|
||||
console.error(` - ${page}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (brokenLinks.length) {
|
||||
console.error(`\nERROR: ${brokenLinks.length} link(s) in llms.txt do not resolve:`);
|
||||
for (const error of brokenLinks) {
|
||||
console.error(` - ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (brokenLinks.length || unlistedPages.length) {
|
||||
throw new Error(
|
||||
`llms.txt has ${brokenLinks.length} broken link(s) and is missing ` +
|
||||
`${unlistedPages.length} page(s)`
|
||||
);
|
||||
}
|
||||
|
||||
console.log(`\nllms.txt is valid: ${links.length} link(s) checked, ${pages.length} page(s) found`);
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
main().catch((err) => {
|
||||
console.error(err.message);
|
||||
process.exitCode = 1;
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = main;
|
||||
@@ -3,11 +3,14 @@
|
||||
/* eslint-disable promise/prefer-await-to-callbacks */
|
||||
/* eslint-disable promise/prefer-await-to-then */
|
||||
|
||||
const path = require('node:path');
|
||||
const {fs} = require('@appium/support');
|
||||
const {AppiumConfigJsonSchema} = require('@appium/schema');
|
||||
import {realpathSync} from 'node:fs';
|
||||
import path from 'node:path';
|
||||
import {fileURLToPath} from 'node:url';
|
||||
|
||||
const DOC_PATH = path.resolve(__dirname, '..', 'en', 'cli', 'args.md');
|
||||
import {AppiumConfigJsonSchema} from '@appium/schema';
|
||||
import {fs} from '@appium/support';
|
||||
|
||||
const DOC_PATH = path.resolve(import.meta.dirname, '..', 'en', 'cli', 'args.md');
|
||||
|
||||
const START_TAG = `<!-- AUTOGEN-START -->`;
|
||||
const STOP_TAG = `<!-- AUTOGEN-STOP -->`;
|
||||
@@ -89,10 +92,10 @@ async function writeNewDoc(preStart, argTable, postEnd) {
|
||||
await fs.writeFile(DOC_PATH, newContents);
|
||||
}
|
||||
|
||||
if (require.main === module) {
|
||||
if (process.argv[1] && fileURLToPath(import.meta.url) === realpathSync(process.argv[1])) {
|
||||
main().catch((err) => {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = main;
|
||||
export default main;
|
||||
|
||||
@@ -2,28 +2,19 @@
|
||||
|
||||
// for simplicity this file is not transpiled and is run directly via an npm script
|
||||
//
|
||||
const {logger} = require('@appium/support');
|
||||
const path = require('node:path');
|
||||
import path from 'node:path';
|
||||
|
||||
import {logger} from '@appium/support';
|
||||
|
||||
const log = logger.getLogger('Docs');
|
||||
|
||||
const DOCS_REMOTE = 'origin';
|
||||
const DOCS_BRANCH = 'gh-pages';
|
||||
const DOCS_PREFIX = 'docs';
|
||||
const DOCS_DIR = path.resolve(__dirname, '..');
|
||||
const DOCS_DIR = path.resolve(import.meta.dirname, '..');
|
||||
const LATEST_ALIAS = 'latest';
|
||||
const ASSETS_DIR = path.join(DOCS_DIR, 'assets');
|
||||
const LANGS = ['en', 'ja', 'zh'];
|
||||
const DEFAULT_LANG = 'en';
|
||||
|
||||
module.exports = {
|
||||
log,
|
||||
DOCS_DIR,
|
||||
ASSETS_DIR,
|
||||
LANGS,
|
||||
DEFAULT_LANG,
|
||||
DOCS_BRANCH,
|
||||
DOCS_PREFIX,
|
||||
DOCS_REMOTE,
|
||||
LATEST_ALIAS,
|
||||
};
|
||||
export {log, DOCS_DIR, ASSETS_DIR, LANGS, DEFAULT_LANG, DOCS_BRANCH, DOCS_PREFIX, DOCS_REMOTE, LATEST_ALIAS};
|
||||
|
||||
@@ -7,7 +7,7 @@ date: 2024-07-13
|
||||
|
||||
# Appium Conf 2024: 现在开始征集提案
|
||||
|
||||
我们很兴奋地宣布,Appium Conf 已回归并在2024年上线!这是官方的Appium会议,您可以在会上了解Appium 2中的所有新内容。 并探索设备自动化测试、移动应用程序和桌面应用程序的最新版本。
|
||||
我们很兴奋地宣布,Appium Conf 已回归并在2024年上线! 这是官方的Appium会议,您可以在会上了解Appium 2中的所有新内容。 并探索设备自动化测试、移动应用程序和桌面应用程序的最新版本。
|
||||
|
||||
<!-- more -->
|
||||
|
||||
@@ -19,7 +19,7 @@ date: 2024-07-13
|
||||
|
||||
## 标记您的日历:2024年9月13日
|
||||
|
||||
2024年9月13日,请加入我们,参加Appium团队和世界顶级移动测试和自动化专家为期一天的鼓舞人心且实用的演讲。随着Appium 2.0的成熟,这是您深入了解并学习如何最大限度地发挥其潜力的机会。
|
||||
2024年9月13日,请加入我们,参加Appium团队和世界顶级移动测试和自动化专家为期一天的鼓舞人心且实用的演讲。 随着Appium 2.0的成熟,这是您深入了解并学习如何最大限度地发挥其潜力的机会。
|
||||
|
||||
## 为什么参加了2024年的Appium Conf ?
|
||||
|
||||
@@ -30,16 +30,16 @@ date: 2024-07-13
|
||||
|
||||
## 征集提案:分享您的知识!
|
||||
|
||||
我们正在寻找来自全球各地的各种演讲者,他们渴望分享移动测试自动化的创新想法和用例。如果您有使用Appium的经验和见解,可以使测试从业者社区受益,我们想听听您的意见!
|
||||
我们正在寻找来自全球各地的各种演讲者,他们渴望分享移动测试自动化的创新想法和用例。 如果您有使用Appium的经验和见解,可以使测试从业者社区受益,我们想听听您的意见!
|
||||
|
||||
不要错过这个机会,为Appium社区做出贡献,并在全球舞台上展示你的专业知识。
|
||||
|
||||
## 如何提交您的提案
|
||||
|
||||
访问我们的网站 [https://appiumconf.com/](https://appiumconf.com/) 并[提交提案](https://confengine.com/conferences/appium-conf-2024/proposals?utm_medium=referal&utm_source=appium.io&utm_campaign=launch)。我们很高兴看到您在 Appium 中的创新想法和经验!
|
||||
访问我们的网站 [https://appiumconf.com/](https://appiumconf.com/) 并[提交提案](https://confengine.com/conferences/appium-conf-2024/proposals?utm_medium=referal&utm_source=appium.io&utm_campaign=launch)。 我们很高兴看到您在 Appium 中的创新想法和经验!
|
||||
|
||||
## 敬请期待
|
||||
|
||||
关注我们的网站和社交媒体频道以了解会议日程安排的更新, 主旨演讲人和2024年Appium Conf 的更令人兴奋的细节。
|
||||
|
||||
加入我们来塑造移动设备测试自动化的未来。立即提交您的提案,成为这一激动人心的活动的一部分!
|
||||
加入我们来塑造移动设备测试自动化的未来。 立即提交您的提案,成为这一激动人心的活动的一部分!
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user