mirror of
https://github.com/appium/appium.git
synced 2026-11-01 06:45:05 +08:00
Compare commits
289
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b85f158e1 | ||
|
|
b3ee58d357 | ||
|
|
6351d119f7 | ||
|
|
6081d41388 | ||
|
|
2c2820242f | ||
|
|
e967b607d7 | ||
|
|
60acd1d3d8 | ||
|
|
dddd2c3051 | ||
|
|
66ee0e46fb | ||
|
|
cc531cf436 | ||
|
|
5f2e7685bb | ||
|
|
b09e3c57cd | ||
|
|
6a680adbf5 | ||
|
|
db41945811 | ||
|
|
9ed545596d | ||
|
|
e0cf688b50 | ||
|
|
aea41abf53 | ||
|
|
43100de428 | ||
|
|
8b37725d8f | ||
|
|
f915b6c320 | ||
|
|
4c753a134d | ||
|
|
a6a69d36d3 | ||
|
|
fa75288c5e | ||
|
|
76acef9339 | ||
|
|
353e9b11e3 | ||
|
|
f0d549c46c | ||
|
|
8d85580b22 | ||
|
|
815fd3e3ca | ||
|
|
01de9bfb7d | ||
|
|
522f3975e1 | ||
|
|
c7a88ebf37 | ||
|
|
88ea09a90f | ||
|
|
fff33c6666 | ||
|
|
f10fdf776b | ||
|
|
355d8630fb | ||
|
|
a9542ae474 | ||
|
|
7ea5b75bfd | ||
|
|
b995004d1a | ||
|
|
99ace58ff8 | ||
|
|
85371dd4e5 | ||
|
|
23abcdef70 | ||
|
|
76481a7494 | ||
|
|
17173e4dda | ||
|
|
6f74c79a4e | ||
|
|
c63c31155e | ||
|
|
d49b48984a | ||
|
|
2bc0a2e15a | ||
|
|
5d30656828 | ||
|
|
034f50cdb7 | ||
|
|
3c20d79238 | ||
|
|
011a1b7fd4 | ||
|
|
d9b8e2d2b9 | ||
|
|
f1e215880b | ||
|
|
11a484bed7 | ||
|
|
c65aaa9953 | ||
|
|
241d2b29aa | ||
|
|
1a21c6f3e7 | ||
|
|
f06e2f81cb | ||
|
|
94a89dafc5 | ||
|
|
615a2a40c5 | ||
|
|
e8a09d2ad8 | ||
|
|
d88ec034cd | ||
|
|
8f57e0492c | ||
|
|
253180c168 | ||
|
|
a7f59de487 | ||
|
|
d649360618 | ||
|
|
42eaf8ecda | ||
|
|
613752a609 | ||
|
|
6db1e00041 | ||
|
|
14110e50b0 | ||
|
|
08c86049c1 | ||
|
|
5f5f711184 | ||
|
|
f2f0e2cc05 | ||
|
|
68d0fa4ab7 | ||
|
|
4a6c92680c | ||
|
|
61e18086dc | ||
|
|
6f68dc9093 | ||
|
|
0dc96de9a9 | ||
|
|
868b7b67d4 | ||
|
|
e560924400 | ||
|
|
5fbd98ec29 | ||
|
|
96d130ad93 | ||
|
|
f986375024 | ||
|
|
e9dc5d6374 | ||
|
|
62413002a8 | ||
|
|
77945ddaf1 | ||
|
|
061d995735 | ||
|
|
596ece7f11 | ||
|
|
73e587fe3d | ||
|
|
01d2b8f1e4 | ||
|
|
607a1ecf81 | ||
|
|
e621c6fe87 | ||
|
|
c27ced0d1d | ||
|
|
7a3190e5e5 | ||
|
|
1ca4bc311c | ||
|
|
a85a35e87d | ||
|
|
43bb05cba0 | ||
|
|
28e9501374 | ||
|
|
eed26a25fc | ||
|
|
ecabd78fa1 | ||
|
|
e33b47f96b | ||
|
|
bbf849380d | ||
|
|
ac93158af5 | ||
|
|
2bec48ebc0 | ||
|
|
9173346c3c | ||
|
|
9396d6d3b0 | ||
|
|
359ef4ba89 | ||
|
|
ac2c78c822 | ||
|
|
59ab921d8e | ||
|
|
c051454e87 | ||
|
|
3c48508904 | ||
|
|
9509d19e1b | ||
|
|
7723622d57 | ||
|
|
eb5ce47b17 | ||
|
|
7df378f401 | ||
|
|
4dd2e2d47d | ||
|
|
dacc42ba0a | ||
|
|
2502f538ff | ||
|
|
3f38f5cd74 | ||
|
|
6891dd4eae | ||
|
|
4e8e334cbc | ||
|
|
3423e36689 | ||
|
|
14a9d98641 | ||
|
|
f79fafb816 | ||
|
|
443b0bdd03 | ||
|
|
80fbf957c8 | ||
|
|
0443c84ec0 | ||
|
|
a47fdb8e05 | ||
|
|
e2c8f09bb9 | ||
|
|
dc16d6970f | ||
|
|
abfe1243a1 | ||
|
|
9bbf6b72bf | ||
|
|
0fa9c9bd80 | ||
|
|
9a70a44c83 | ||
|
|
65e14685a8 | ||
|
|
29eeb28f86 | ||
|
|
ac412b8723 | ||
|
|
68740320d2 | ||
|
|
9dc6cd0019 | ||
|
|
81c8b9da0a | ||
|
|
726348c2d5 | ||
|
|
6c911debd7 | ||
|
|
8ccb436701 | ||
|
|
f522b64456 | ||
|
|
3180558086 | ||
|
|
9d07f6bc5e | ||
|
|
b234e2b56b | ||
|
|
b635641f24 | ||
|
|
6d720b1112 | ||
|
|
6ab17feb71 | ||
|
|
afa4837530 | ||
|
|
1ada93cf76 | ||
|
|
b32e28d36d | ||
|
|
119e21f067 | ||
|
|
6ba6faf6f5 | ||
|
|
422362a259 | ||
|
|
62bfe1566a | ||
|
|
8a9350b8e9 | ||
|
|
bf51d27137 | ||
|
|
de00df0afa | ||
|
|
c3a48181c8 | ||
|
|
77dc09af36 | ||
|
|
59af10a17c | ||
|
|
6e989bd89a | ||
|
|
557e71f766 | ||
|
|
63d94d03c6 | ||
|
|
8a0022c147 | ||
|
|
72ee77d139 | ||
|
|
70a01da4b2 | ||
|
|
1b705bcd24 | ||
|
|
574bd6cbfb | ||
|
|
9c00b86ce7 | ||
|
|
0c4da64aea | ||
|
|
dafc5985bb | ||
|
|
02443f98d6 | ||
|
|
b4097b54d4 | ||
|
|
b67de03966 | ||
|
|
2b39493e98 | ||
|
|
e916673e32 | ||
|
|
76ff5aa69a | ||
|
|
b1b313b989 | ||
|
|
658f88d8c1 | ||
|
|
3999208fc0 | ||
|
|
1f945716a0 | ||
|
|
0a3ad48419 | ||
|
|
17be28c750 | ||
|
|
746073148f | ||
|
|
73ef2f7d43 | ||
|
|
6fb07a5dbc | ||
|
|
5dd80daf63 | ||
|
|
05e36962e6 | ||
|
|
eaa824f601 | ||
|
|
6cb62d21e8 | ||
|
|
8254a7a3b5 | ||
|
|
83e99bc752 | ||
|
|
147c0bcac3 | ||
|
|
ddd4251108 | ||
|
|
b19bd7878b | ||
|
|
91446df648 | ||
|
|
d5b316031e | ||
|
|
737cf77b6e | ||
|
|
c35a12a51d | ||
|
|
5c2aafa208 | ||
|
|
4422d99d45 | ||
|
|
ce50dd7fa7 | ||
|
|
f06226b7bb | ||
|
|
33459705ed | ||
|
|
f4ca259852 | ||
|
|
a49ae68f13 | ||
|
|
50bd67e59d | ||
|
|
549b4d4179 | ||
|
|
26ffad4f24 | ||
|
|
1a81ac88f3 | ||
|
|
c9fca97cae | ||
|
|
7d87b26047 | ||
|
|
87930a2df1 | ||
|
|
29ee04cf03 | ||
|
|
8892b1022d | ||
|
|
b97fe497cf | ||
|
|
a729d86637 | ||
|
|
e5bd73272b | ||
|
|
037b42454a | ||
|
|
5cf259f974 | ||
|
|
1486078c82 | ||
|
|
01a4eaec49 | ||
|
|
10086b543f | ||
|
|
68ce0e2bdd | ||
|
|
ae4ca98826 | ||
|
|
1d1631e64e | ||
|
|
5721d50b3a | ||
|
|
bd3a120587 | ||
|
|
3e2592804a | ||
|
|
93c0842dbb | ||
|
|
13e8834405 | ||
|
|
3ab2320e1b | ||
|
|
258fc2245a | ||
|
|
5dd9baf5ea | ||
|
|
481807f8db | ||
|
|
8a90e74af3 | ||
|
|
ea9595ff53 | ||
|
|
5d796139f6 | ||
|
|
b3f8a5eea6 | ||
|
|
ae549c8613 | ||
|
|
af8efc0882 | ||
|
|
63103cfa0d | ||
|
|
b0938e6334 | ||
|
|
4b0cc9d37f | ||
|
|
909cc3d4c0 | ||
|
|
1a8f88029b | ||
|
|
3a8049887d | ||
|
|
2ed7bb04d8 | ||
|
|
db87f3cdd4 | ||
|
|
2c0f3fd9e3 | ||
|
|
63b167c408 | ||
|
|
406dfad41f | ||
|
|
85574e7e80 | ||
|
|
336395fcfa | ||
|
|
d9e8b3ba73 | ||
|
|
e625408f55 | ||
|
|
d2a981a45f | ||
|
|
76f2dd3b36 | ||
|
|
03dac9d6e8 | ||
|
|
eb93d49802 | ||
|
|
3f21bcf1a7 | ||
|
|
d708029325 | ||
|
|
485b8d7a70 | ||
|
|
c688932525 | ||
|
|
77d159838f | ||
|
|
c733c090f6 | ||
|
|
2a07c2818c | ||
|
|
52cbfd2708 | ||
|
|
a551c38171 | ||
|
|
0f42831afa | ||
|
|
5c870329a3 | ||
|
|
a236fdbc97 | ||
|
|
a2e9cef145 | ||
|
|
7d72502769 | ||
|
|
12a91e5293 | ||
|
|
d093b76bef | ||
|
|
120b9ddfac | ||
|
|
281e61c297 | ||
|
|
8ac6bfcc3b | ||
|
|
cdd448800e | ||
|
|
e977a29b0b | ||
|
|
2d8fa2662e | ||
|
|
b96c8fa718 | ||
|
|
c6a88e7dd7 | ||
|
|
087a83a27e | ||
|
|
6a241d760a |
+1
-1
@@ -1,7 +1,7 @@
|
||||
# editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
[*.{js,cjs,mjs,jsx,ts,cts,mts,tsx,json,jsonc}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
|
||||
@@ -20,7 +20,7 @@ runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Use Node.js ${{ inputs.node-version }}
|
||||
uses: actions/setup-node@v7.0.0
|
||||
uses: actions/setup-node@v7.1.0
|
||||
with:
|
||||
node-version: ${{ inputs.node-version }}
|
||||
cache: npm
|
||||
@@ -33,8 +33,44 @@ runs:
|
||||
run: |
|
||||
# Replace npm with sfw npm in the install command
|
||||
install_cmd="${{ inputs.install-command }}"
|
||||
install_cmd="${install_cmd//npm /sfw npm }"
|
||||
$install_cmd
|
||||
sfw_install_cmd="${install_cmd//npm /sfw npm }"
|
||||
|
||||
# Socket Firewall can fail to reach its own backend (a transient
|
||||
# network error unrelated to the actual npm install) and, in that
|
||||
# case, either exit non-zero or exit 0 without having actually
|
||||
# completed the install, leaving node_modules incomplete. We only
|
||||
# want to fall back to a plain (non-firewalled) install when we can
|
||||
# positively attribute the failure to *that* Socket Firewall error —
|
||||
# a real npm/package problem (bad version, checksum mismatch, failing
|
||||
# postinstall script, etc.) must fail the job as-is, not be silently
|
||||
# retried and potentially masked.
|
||||
sfw_log="$(mktemp)"
|
||||
set +e
|
||||
$sfw_install_cmd 2>&1 | tee "$sfw_log"
|
||||
sfw_exit="${PIPESTATUS[0]}"
|
||||
set -e
|
||||
|
||||
sfw_infra_failure=0
|
||||
if grep -qi 'Socket Firewall encountered an unexpected error' "$sfw_log"; then
|
||||
sfw_infra_failure=1
|
||||
fi
|
||||
|
||||
install_incomplete=0
|
||||
if [ "$sfw_exit" -eq 0 ]; then
|
||||
npm ls --depth=0 >/dev/null 2>&1 || install_incomplete=1
|
||||
fi
|
||||
rm -f "$sfw_log"
|
||||
|
||||
if [ "$sfw_infra_failure" -eq 1 ] && { [ "$sfw_exit" -ne 0 ] || [ "$install_incomplete" -eq 1 ]; }; then
|
||||
echo "::warning::Socket Firewall failed to reach its backend; retrying with a plain npm install"
|
||||
$install_cmd
|
||||
elif [ "$sfw_exit" -ne 0 ]; then
|
||||
echo "::error::npm install failed"
|
||||
exit "$sfw_exit"
|
||||
elif [ "$install_incomplete" -eq 1 ]; then
|
||||
echo "::error::npm install appears incomplete and is not attributable to a Socket Firewall failure"
|
||||
exit 1
|
||||
fi
|
||||
- name: Build packages
|
||||
if: ${{ inputs.run-build == 'true' }}
|
||||
shell: bash
|
||||
|
||||
@@ -197,3 +197,5 @@ jobs:
|
||||
run: npm run lint:ci
|
||||
- name: Format check
|
||||
run: npm run format:check
|
||||
- name: Verify changelog generation
|
||||
run: npm run verify:changelog-generation
|
||||
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v7.0.1
|
||||
- name: Use Node.js LTS
|
||||
uses: actions/setup-node@v7.0.0
|
||||
uses: actions/setup-node@v7.1.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.0.0
|
||||
uses: actions/setup-node@v7.1.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.0.0
|
||||
uses: actions/setup-node@v7.1.0
|
||||
with:
|
||||
node-version: lts/*
|
||||
cache: 'npm'
|
||||
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
steps:
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@v7.0.0
|
||||
uses: actions/setup-node@v7.1.0
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Install Appium
|
||||
|
||||
@@ -49,5 +49,9 @@ 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.0.0
|
||||
uses: actions/setup-node@v7.1.0
|
||||
with:
|
||||
node-version: lts/*
|
||||
cache: 'npm'
|
||||
|
||||
@@ -8,6 +8,16 @@ on:
|
||||
required: true
|
||||
type: boolean
|
||||
default: true
|
||||
recover_missing_only:
|
||||
description: 'Recovery mode: skip version bump, publish only packages missing on npm at their current package.json version'
|
||||
required: true
|
||||
type: boolean
|
||||
default: false
|
||||
bootstrap_packages:
|
||||
description: 'One-time beta-branch bootstrap only: comma-separated package names (e.g. @appium/base-driver,@appium/support) to force-bump to their next-major beta (premajor --preid beta), bypassing conventional-commit detection. Leave empty for a normal release.'
|
||||
required: false
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
@@ -18,7 +28,11 @@ permissions:
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/master' && contains(fromJSON('["mykola-mokhnach", "jlipps", "eglitise", "KazuCocoa"]'), github.actor)
|
||||
# keep this branch name in sync with env.BETA_BRANCH below - the `env` context isn't available
|
||||
# to jobs.<job_id>.if (GitHub Actions resolves it before job-level env is set up)
|
||||
if: (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/appium4') && contains(fromJSON('["mykola-mokhnach", "jlipps", "eglitise", "KazuCocoa"]'), github.actor)
|
||||
env:
|
||||
BETA_BRANCH: appium4
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@@ -43,15 +57,148 @@ jobs:
|
||||
# for lerna createRelease
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
DRY_RUN: ${{ inputs.dry_run }}
|
||||
RECOVER_MISSING_ONLY: ${{ inputs.recover_missing_only }}
|
||||
BOOTSTRAP_PACKAGES: ${{ inputs.bootstrap_packages }}
|
||||
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).
|
||||
BETA_FLAGS=""
|
||||
DIST_TAG_FLAGS=""
|
||||
if [ "${{ github.ref_name }}" = "$BETA_BRANCH" ]; then
|
||||
BETA_FLAGS="--conventional-prerelease --preid beta"
|
||||
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() {
|
||||
for pkg_json in packages/*/package.json; do
|
||||
if [ ! -f "$pkg_json" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ "$(jq -r '.private // false' "$pkg_json")" = "true" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
pkg_name="$(jq -r '.name // empty' "$pkg_json")"
|
||||
pkg_version="$(jq -r '.version // empty' "$pkg_json")"
|
||||
if [ -z "$pkg_name" ] || [ -z "$pkg_version" ]; then
|
||||
echo "Skipping malformed package manifest: $pkg_json" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
pkg_spec="${pkg_name}@${pkg_version}"
|
||||
if ! npm view "$pkg_spec" version >/dev/null 2>&1; then
|
||||
echo "$pkg_spec"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Resolves the workspace directory of a package given its npm name.
|
||||
package_dir_for() {
|
||||
local target="$1"
|
||||
for pkg_json in packages/*/package.json; do
|
||||
if [ ! -f "$pkg_json" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ "$(jq -r '.name // empty' "$pkg_json")" = "$target" ]; then
|
||||
dirname "$pkg_json"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
# Publishes each "<pkg_name>@<pkg_version>" package spec passed as an argument.
|
||||
# `lerna publish` has no per-package scope filter, so this runs `npm publish`
|
||||
# directly from each package's directory instead. Returns non-zero if any
|
||||
# individual publish failed; npm publish's own exit code is taken as authoritative,
|
||||
# no npm registry re-scan is done to double-check it.
|
||||
publish_missing_packages() {
|
||||
echo "Publishing missing packages one-by-one"
|
||||
local overall_status=0
|
||||
for pkg_spec in "$@"; do
|
||||
pkg_name="${pkg_spec%@*}"
|
||||
pkg_dir="$(package_dir_for "$pkg_name")"
|
||||
if [ -z "$pkg_dir" ]; then
|
||||
echo "Could not resolve workspace directory for ${pkg_name}"
|
||||
overall_status=1
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "Publishing ${pkg_spec}"
|
||||
set +e
|
||||
(cd "$pkg_dir" && npm publish $DIST_TAG_FLAGS)
|
||||
publish_exit_code=$?
|
||||
set -e
|
||||
if [ $publish_exit_code -ne 0 ]; then
|
||||
echo "npm publish failed for ${pkg_spec} (exit code ${publish_exit_code})"
|
||||
overall_status=1
|
||||
fi
|
||||
done
|
||||
return $overall_status
|
||||
}
|
||||
|
||||
if [ "$RECOVER_MISSING_ONLY" = "true" ]; then
|
||||
echo "Recovery mode: scanning for packages missing on npm at their current package.json version"
|
||||
mapfile -t missing < <(find_missing_packages)
|
||||
|
||||
if [ ${#missing[@]} -eq 0 ]; then
|
||||
echo "No missing packages found; nothing to do"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Missing package versions on npm:"
|
||||
printf ' - %s\n' "${missing[@]}"
|
||||
|
||||
if [ "$DRY_RUN" = "true" ]; then
|
||||
echo "Dry run: not publishing"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! publish_missing_packages "${missing[@]}"; then
|
||||
echo "Recovery incomplete: one or more packages failed to publish"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "All missing packages published successfully"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
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
|
||||
printf "n\n" | npx lerna version --exact --no-git-tag-version --no-push $BETA_FLAGS
|
||||
else
|
||||
echo "Running lerna publish for real"
|
||||
set +e
|
||||
release_output="$(npm run release -- --yes 2>&1)"
|
||||
release_output="$(npm run release -- --yes $BETA_FLAGS $DIST_TAG_FLAGS 2>&1)"
|
||||
release_exit_code=$?
|
||||
set -e
|
||||
printf '%s\n' "$release_output"
|
||||
@@ -76,55 +223,13 @@ jobs:
|
||||
fi
|
||||
|
||||
git checkout "$tagged_commit"
|
||||
missing=()
|
||||
for pkg_json in packages/*/package.json; do
|
||||
if [ ! -f "$pkg_json" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
if [ "$(jq -r '.private // false' "$pkg_json")" = "true" ]; then
|
||||
continue
|
||||
fi
|
||||
|
||||
pkg_name="$(jq -r '.name // empty' "$pkg_json")"
|
||||
pkg_version="$(jq -r '.version // empty' "$pkg_json")"
|
||||
if [ -z "$pkg_name" ] || [ -z "$pkg_version" ]; then
|
||||
echo "Skipping malformed package manifest: $pkg_json"
|
||||
continue
|
||||
fi
|
||||
|
||||
pkg_spec="${pkg_name}@${pkg_version}"
|
||||
if ! npm view "$pkg_spec" version >/dev/null 2>&1; then
|
||||
missing+=("$pkg_spec")
|
||||
fi
|
||||
done
|
||||
mapfile -t missing < <(find_missing_packages)
|
||||
|
||||
if [ ${#missing[@]} -gt 0 ]; then
|
||||
echo "Missing package versions on npm before scoped recovery:"
|
||||
printf ' - %s\n' "${missing[@]}"
|
||||
echo "Publishing missing packages one-by-one with scope"
|
||||
for pkg_spec in "${missing[@]}"; do
|
||||
pkg_name="${pkg_spec%@*}"
|
||||
echo "Publishing ${pkg_name}"
|
||||
set +e
|
||||
npx lerna publish from-package --yes --scope "$pkg_name"
|
||||
scoped_exit_code=$?
|
||||
set -e
|
||||
if [ $scoped_exit_code -ne 0 ]; then
|
||||
echo "Scoped publish exited non-zero for ${pkg_name}; will verify on npm"
|
||||
fi
|
||||
done
|
||||
|
||||
final_missing=()
|
||||
for pkg_spec in "${missing[@]}"; do
|
||||
if ! npm view "$pkg_spec" version >/dev/null 2>&1; then
|
||||
final_missing+=("$pkg_spec")
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ${#final_missing[@]} -gt 0 ]; then
|
||||
echo "Recovery incomplete after scoped retries. Still missing:"
|
||||
printf ' - %s\n' "${final_missing[@]}"
|
||||
if ! publish_missing_packages "${missing[@]}"; then
|
||||
echo "Recovery incomplete: one or more packages failed to publish"
|
||||
exit $release_exit_code
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -15,7 +15,11 @@ permissions:
|
||||
jobs:
|
||||
version:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref == 'refs/heads/master' && contains(fromJSON('["mykola-mokhnach", "jlipps", "eglitise", "KazuCocoa"]'), github.actor)
|
||||
# keep this branch name in sync with env.BETA_BRANCH below - the `env` context isn't available
|
||||
# to jobs.<job_id>.if (GitHub Actions resolves it before job-level env is set up)
|
||||
if: (github.ref == 'refs/heads/master' || github.ref == 'refs/heads/appium4') && contains(fromJSON('["mykola-mokhnach", "jlipps", "eglitise", "KazuCocoa"]'), github.actor)
|
||||
env:
|
||||
BETA_BRANCH: appium4
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
@@ -38,4 +42,9 @@ jobs:
|
||||
- name: Run Lerna version
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: npx lerna version --exact --yes
|
||||
run: |
|
||||
BETA_FLAGS=""
|
||||
if [ "${{ github.ref_name }}" = "$BETA_BRANCH" ]; then
|
||||
BETA_FLAGS="--conventional-prerelease --preid beta"
|
||||
fi
|
||||
npx lerna version --exact --yes $BETA_FLAGS
|
||||
|
||||
@@ -2,10 +2,12 @@ name: Publish docs
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
workflow_run:
|
||||
workflows: ['Appium Server Release']
|
||||
types:
|
||||
- completed
|
||||
push:
|
||||
# Runs when any new Appium tag is pushed = there is a new release
|
||||
# Does not trigger for tags with a slash, e.g. 1.0/beta
|
||||
tags:
|
||||
- appium@*
|
||||
- '!appium@*beta*'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
@@ -13,6 +15,8 @@ jobs:
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v7.0.1
|
||||
with:
|
||||
fetch-depth: 0 # ensure the docs branch is also fetched
|
||||
- run: |
|
||||
git config user.name github-actions
|
||||
git config user.email github-actions@github.com
|
||||
@@ -24,9 +28,20 @@ jobs:
|
||||
run-build: 'true'
|
||||
- name: Install dependencies (Python)
|
||||
run: npm run install-docs-deps
|
||||
- name: Fetch gh-pages
|
||||
run: |
|
||||
git fetch origin gh-pages:gh-pages || true
|
||||
- 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: |
|
||||
npm run docs:publish
|
||||
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
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# Repository guidance
|
||||
|
||||
Before changing code, read and follow the
|
||||
[contributor style guide](packages/appium/docs/en/contributing/index.md#code-style).
|
||||
@@ -29,8 +29,10 @@ to driver/client documentation
|
||||
* [fake-plugin](packages/fake-plugin/CHANGELOG.md)
|
||||
* [logger](packages/logger/CHANGELOG.md)
|
||||
* [opencv](packages/opencv/CHANGELOG.md)
|
||||
* [oxc-config](packages/oxc-config/CHANGELOG.md)
|
||||
* [plugin-test-support](packages/plugin-test-support/CHANGELOG.md)
|
||||
* [schema](packages/schema/CHANGELOG.md)
|
||||
* [semantic-release-config](packages/semantic-release-config/CHANGELOG.md)
|
||||
* [strongbox](packages/strongbox/CHANGELOG.md)
|
||||
* [support](packages/support/CHANGELOG.md)
|
||||
* [tsconfig](packages/tsconfig/CHANGELOG.md)
|
||||
|
||||
@@ -149,6 +149,31 @@ 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](http://appium.io/docs/en/latest/cli/server/)
|
||||
where your client library expects it to listen. [Appium's command-line interface](https://appium.io/docs/en/latest/reference/cli/)
|
||||
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://github.com/appium/appium-inspector) can be used to visually inspect
|
||||
6. [Appium Inspector](https://appium.github.io/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
-1
@@ -14,7 +14,7 @@
|
||||
"version": {
|
||||
"conventionalCommits": true,
|
||||
"createRelease": "github",
|
||||
"allowBranch": ["master", "appium3"],
|
||||
"allowBranch": ["master", "appium4"],
|
||||
"exact": true
|
||||
}
|
||||
},
|
||||
|
||||
Generated
+5942
-7831
File diff suppressed because it is too large
Load Diff
+17
-34
@@ -46,6 +46,7 @@
|
||||
"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",
|
||||
@@ -75,71 +76,53 @@
|
||||
"test:types": "lerna run test:types",
|
||||
"test:unit": "lerna run test",
|
||||
"upload": "gulp github-upload",
|
||||
"verify:changelog-generation": "node ./scripts/verify-changelog-generation.mjs",
|
||||
"zip": "zip -qr ./appium.zip ./packages/appium",
|
||||
"zip-and-upload": "run-s zip upload"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@appium/oxc-config": "1.0.0",
|
||||
"@eslint/js": "10.0.1",
|
||||
"@stylistic/eslint-plugin": "5.10.0",
|
||||
"@tsconfig/node20": "20.1.9",
|
||||
"@tsconfig/node20": "20.1.10",
|
||||
"@types/async-lock": "1.4.2",
|
||||
"@types/bluebird": "3.5.42",
|
||||
"@types/chai": "5.2.3",
|
||||
"@types/chai-as-promised": "8.0.2",
|
||||
"@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.7",
|
||||
"@types/klaw": "3.0.8",
|
||||
"@types/lockfile": "1.0.4",
|
||||
"@types/lodash": "4.17.24",
|
||||
"@types/method-override": "3.0.0",
|
||||
"@types/morgan": "1.9.10",
|
||||
"@types/mv": "2.1.4",
|
||||
"@types/node": "24.13.3",
|
||||
"@types/node": "24.19.2",
|
||||
"@types/plist": "3.0.5",
|
||||
"@types/pluralize": "0.0.33",
|
||||
"@types/semver": "7.7.1",
|
||||
"@types/semver": "7.8.0",
|
||||
"@types/serve-favicon": "2.5.7",
|
||||
"@types/shell-quote": "1.7.5",
|
||||
"@types/sinon": "22.0.0",
|
||||
"@types/sinon-chai": "4.0.0",
|
||||
"@types/sinon": "22.0.2",
|
||||
"@types/which": "3.0.4",
|
||||
"@types/ws": "8.18.1",
|
||||
"@types/xmldom": "0.1.34",
|
||||
"@types/ws": "8.18.2",
|
||||
"@types/yargs": "17.0.35",
|
||||
"asyncbox": "6.3.5",
|
||||
"chai": "6.2.2",
|
||||
"chai-as-promised": "8.0.2",
|
||||
"conventional-changelog-conventionalcommits": "7.0.2",
|
||||
"asyncbox": "6.5.0",
|
||||
"conventional-changelog-conventionalcommits": "9.3.1",
|
||||
"cpy-cli": "7.0.0",
|
||||
"cross-env": "10.1.0",
|
||||
"eslint": "10.7.0",
|
||||
"eslint-config-prettier": "10.1.8",
|
||||
"eslint-import-resolver-typescript": "4.4.5",
|
||||
"eslint-plugin-import-x": "4.17.1",
|
||||
"eslint-plugin-mocha": "11.3.0",
|
||||
"eslint-plugin-n": "18.2.2",
|
||||
"eslint-plugin-promise": "7.3.0",
|
||||
"finalhandler": "2.1.1",
|
||||
"json-schema-to-typescript": "15.0.4",
|
||||
"lerna": "9.0.7",
|
||||
"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.2",
|
||||
"npm-run-all2": "9.0.4",
|
||||
"rewiremock": "3.14.6",
|
||||
"rimraf": "6.1.3",
|
||||
"serve-static": "2.2.1",
|
||||
"sinon": "22.1.0",
|
||||
"sinon-chai": "4.0.1",
|
||||
"teen_process": "4.1.9",
|
||||
"teen_process": "4.2.1",
|
||||
"tsd": "0.33.0",
|
||||
"typescript": "6.0.3",
|
||||
"typescript-eslint": "8.65.0",
|
||||
"webdriverio": "9.29.1",
|
||||
"ws": "8.21.1"
|
||||
"webdriverio": "9.32.0",
|
||||
"ws": "8.22.0"
|
||||
},
|
||||
"overrides": {
|
||||
"@sidvind/better-ajv-errors": {
|
||||
@@ -148,7 +131,7 @@
|
||||
"ajv-formats": {
|
||||
"ajv": "8.20.0"
|
||||
},
|
||||
"http-cache-semantics": "4.2.0"
|
||||
"http-cache-semantics": "4.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.12.0 || >=24.0.0",
|
||||
|
||||
@@ -3,6 +3,47 @@
|
||||
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)
|
||||
|
||||
### 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))
|
||||
|
||||
### 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))
|
||||
|
||||
|
||||
## [3.8.0](https://github.com/appium/appium/compare/appium@3.7.0...appium@3.8.0) (2026-09-24)
|
||||
|
||||
### 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))
|
||||
|
||||
### 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))
|
||||
|
||||
|
||||
## [3.7.0](https://github.com/appium/appium/compare/appium@3.6.0...appium@3.7.0) (2026-08-24)
|
||||
|
||||
### Features
|
||||
|
||||
* **base-driver:** add httpServer.frontRouter for global extension middleware ([#22632](https://github.com/appium/appium/issues/22632)) ([f06226b](https://github.com/appium/appium/commit/f06226b7bb2fb7ee2f3a61833f4a1d7777d4ef21))
|
||||
* **storage-plugin:** Add route aliases ([#22558](https://github.com/appium/appium/issues/22558)) ([a551c38](https://github.com/appium/appium/commit/a551c3817156bbc7e06793227643a2d11c0c0259))
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **appium:** load @appium/docutils dynamically in docs build script ([#22584](https://github.com/appium/appium/issues/22584)) ([2c0f3fd](https://github.com/appium/appium/commit/2c0f3fd9e319c3bc774bdd2a65148da11094c87c))
|
||||
* **appium:** parse --webhook as a URI instead of host:port ([#22635](https://github.com/appium/appium/issues/22635)) ([c35a12a](https://github.com/appium/appium/commit/c35a12a51d30fe311ef96ebe386cd9c5540e3927))
|
||||
* **support:** do not treat a sibling folder as a subpath of the root ([#22586](https://github.com/appium/appium/issues/22586)) ([3a80498](https://github.com/appium/appium/commit/3a8049887dc673a6658c3821a2882e0145c3aa86))
|
||||
|
||||
|
||||
## [3.6.0](https://github.com/appium/appium/compare/appium@3.5.2...appium@3.6.0) (2026-07-25)
|
||||
|
||||
|
||||
|
||||
@@ -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](http://appium.io/docs/en/latest/cli/server/)
|
||||
where your client library expects it to listen. [Appium's command-line interface](https://appium.io/docs/en/latest/reference/cli/)
|
||||
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://github.com/appium/appium-inspector) can be used to visually inspect
|
||||
6. [Appium Inspector](https://appium.github.io/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
|
||||
|
||||
@@ -16,6 +16,8 @@ plugins:
|
||||
blog:
|
||||
enabled: true
|
||||
post_excerpt: required
|
||||
mike:
|
||||
canonical_version: 'latest'
|
||||
redirects:
|
||||
redirect_maps:
|
||||
'intro/requirements.md': 'quickstart/requirements.md'
|
||||
|
||||
@@ -17,3 +17,8 @@ authors:
|
||||
avatar: 'https://avatars.githubusercontent.com/u/4045041?v=4'
|
||||
slug: 'sai'
|
||||
url: 'https://saikrishna.tech'
|
||||
mykola:
|
||||
name: 'Mykola Mokhnach'
|
||||
description: 'Appium Core Maintainer'
|
||||
avatar: https://avatars.githubusercontent.com/u/7767781?v=4
|
||||
slug: 'mykola'
|
||||
|
||||
@@ -8,11 +8,13 @@ date: 2025-11-25
|
||||
# Announcing LambdaTest as Appium's Newest Development Partner
|
||||
|
||||
As part of our ongoing effort to recognize organizations that meaningfully support the Appium project through dedicated maintainer time, we are excited to welcome our newest Development Partner: LambdaTest!
|
||||
LambdaTest has long been an active participant in the automated testing ecosystem. Today, they are officially formalizing their commitment by investing people—dedicated engineers who will directly support Appium's development, maintenance, and ecosystem growth.
|
||||
This kind of hands-on contribution is crucial for ensuring Appium continues to evolve. We deeply value partners who empower their engineering teams to contribute code directly to open source rather than just sponsorship.
|
||||
|
||||
<!-- more -->
|
||||
|
||||
LambdaTest has long been an active participant in the automated testing ecosystem. Today, they are officially formalizing their commitment by investing people—dedicated engineers who will directly support Appium's development, maintenance, and ecosystem growth.
|
||||
|
||||
This kind of hands-on contribution is crucial for ensuring Appium continues to evolve. We deeply value partners who empower their engineering teams to contribute code directly to open source rather than just sponsorship.
|
||||
|
||||
<div style="text-align:center;width:100%">
|
||||
<a href="https://lambdatest.com/?utm_source=appium.io&utm_medium=organic&utm_campaign=june_25&utm_term=sk&utm_content=webpage">
|
||||
<img src="/docs/en/latest/assets/images/sponsor-logo-lambdatest-dark.png#only-dark" width="300" />
|
||||
@@ -22,15 +24,19 @@ This kind of hands-on contribution is crucial for ensuring Appium continues to e
|
||||
|
||||
|
||||
LambdaTest engineers are already contributing actively across several key Appium repositories. Their current focus includes:
|
||||
**appium-mcp** – Supporting Appium's implementation of the Model Context Protocol (MCP) to drive forward modern AI-assisted capabilities.
|
||||
**appium-remote-xpc** – Contributing to the native macOS/XPC-based remote execution layer, essential for iOS automation.
|
||||
**appium-tun-tap** – Assisting in the development and maintenance of network virtualization and tunneling components for advanced testing scenarios.
|
||||
|
||||
* [`appium-mcp`](https://github.com/appium/appium-mcp) – Supporting Appium's implementation of the Model Context Protocol (MCP) to drive forward modern AI-assisted capabilities.
|
||||
* [`appium-ios-remotexpc`](https://github.com/appium/appium-ios-remotexpc) – Contributing to the native macOS/XPC-based remote execution layer, essential for iOS automation.
|
||||
* [`appium-ios-tuntap`](https://github.com/appium/appium-ios-tuntap) – Assisting in the development and maintenance of network virtualization and tunneling components for advanced testing scenarios.
|
||||
|
||||
These contributions strengthen critical infrastructure within the Appium ecosystem and demonstrate LambdaTest's commitment to deep technical involvement in the project's evolution.
|
||||
About LambdaTest
|
||||
|
||||
**About LambdaTest**
|
||||
|
||||
LambdaTest’s platform already serves a massive community of Appium users. As a GenAI-powered Quality Engineering Platform, they provide a full-stack testing cloud with 10,000+ real mobile devices and 3,000+ browsers.
|
||||
|
||||
Beyond standard infrastructure, they are pushing the boundaries of test execution with AI-native test management and next-generation agents like KaneAI. By supporting Appium alongside Selenium, Playwright, and other major frameworks, LambdaTest helps teams orchestrate intelligent automation at cloud scale.
|
||||
|
||||
LambdaTest will continue contributing people, code, and development expertise to strengthen Appium's core functionality. Their commitment represents a significant investment into the future of the framework, and we're thrilled to have them collaborating with us at this deeper level.
|
||||
|
||||
The Appium project is proud to recognize LambdaTest as our newest official Development Partner. We can't wait to see what we'll build together!
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
authors:
|
||||
- mykola
|
||||
date: 2026-09-01
|
||||
---
|
||||
|
||||
# Announcing watchOS Simulator Support in the XCUITest Driver
|
||||
|
||||
We’re excited to announce that the XCUITest driver now supports automation of watchOS apps — a
|
||||
platform that’s been on Appium’s requested list for a long time.
|
||||
|
||||
<!-- more -->
|
||||
|
||||
In order to automate watchOS, you'll need the following:
|
||||
|
||||
* XCUITest driver version 12.6.0 or later (WebDriverAgent 16.5.0 or later)
|
||||
* Xcode 15.4 or later
|
||||
* watchOS 10 or later
|
||||
|
||||
Important to note: ^^the driver currently only works with simulators — real devices are not
|
||||
compatible.^^
|
||||
|
||||
The good news: automating a watchOS app looks just like automating any other iOS/iPadOS app. The
|
||||
standard use-cases of finding and clicking on elements, retrieving the page source, using the
|
||||
Appium Inspector — all work as usual. The one exception here is standard W3C gesture/touch actions
|
||||
(tap/swipe via the Actions API), which are not supported.
|
||||
|
||||
On top of that, a few watchOS-specific extensions are available:
|
||||
|
||||
- `mobile: pressButton` — press the Digital Crown or Action button
|
||||
- `mobile: rotateDigitalCrown` — rotate the Digital Crown (since driver version 12.7.0)
|
||||
- `mobile: performHandGesture` — perform double-tap or wrist flick hand gestures (since driver
|
||||
version 12.7.0)
|
||||
|
||||
For full setup instructions, capabilities, and limitations, check out the
|
||||
[watchOS guide](https://appium.github.io/appium-xcuitest-driver/latest/guides/watchos/).
|
||||
|
||||
Happy testing!
|
||||
@@ -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/api/runme?repository=https%3A%2F%2Fgithub.com%2Fappium%2Fappium.git&fileToOpen=packages%2Fappium%2Fdocs%2Fen%2Fcontributing%2Findex.md).
|
||||
If you are VS Code user, you can easily check out the project using [Runme](https://runme.dev/).
|
||||
|
||||
Install dependencies:
|
||||
```sh
|
||||
@@ -103,6 +103,27 @@ 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).
|
||||
|
||||
@@ -62,6 +62,33 @@ 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,8 +80,9 @@ 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. Known platform name strings include: `iOS`,
|
||||
`tvOS`, `macOS`, `Windows`, `Android`.
|
||||
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`.
|
||||
* `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).
|
||||
|
||||
@@ -222,17 +223,22 @@ So you'll probably end up overriding `createSession`. You can do so by defining
|
||||
driver:
|
||||
|
||||
```js
|
||||
async createSession(jwpCaps, reqCaps, w3cCaps, otherDriverData) {
|
||||
const [sessionId, caps] = super.createSession(w3cCaps);
|
||||
async createSession(w3cCaps) {
|
||||
const [sessionId, caps] = await super.createSession(w3cCaps);
|
||||
// do your own stuff here
|
||||
return [sessionId, caps];
|
||||
}
|
||||
```
|
||||
|
||||
For legacy reasons, your function will receive old-style JSON Wire Protocol desired and required
|
||||
caps as the first two arguments. Given that the old protocol isn't supported anymore and clients
|
||||
have all been updated, you can instead only rely on the `w3cCaps` parameter. (For a discussion
|
||||
about what `otherDriverData` is about, see the section below on concurrent drivers).
|
||||
!!! 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`
|
||||
@@ -276,8 +282,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.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
|
||||
[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
|
||||
receive for that command.
|
||||
|
||||
Let's take this block for example:
|
||||
@@ -318,7 +324,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.js](https://github.com/appium/appium/blob/master/packages/base-driver/lib/protocol/bidi-commands.js)
|
||||
[bidi-commands.ts](https://github.com/appium/appium/blob/master/packages/base-driver/lib/protocol/bidi-commands.ts)
|
||||
|
||||
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
|
||||
@@ -520,14 +526,13 @@ route, then the route will not be proxied and instead will be handled by your dr
|
||||
example, we are avoiding proxying all `POST` routes that have the `appium` prefix.
|
||||
|
||||
Next, we have to set up the proxying itself. The way to do this is to use a special class from
|
||||
Appium called `JWProxy`. (The name means "JSON Wire Proxy" and is related to a legacy
|
||||
implementation of the protocol). You'll want to create a `JWProxy` object using the details required to
|
||||
connect to the remote server:
|
||||
Appium called `WebDriverProxy`. You'll want to create a `WebDriverProxy` object using the details
|
||||
required to connect to the remote server:
|
||||
|
||||
```js
|
||||
// import {JWProxy} from 'appium/driver';
|
||||
// import {WebDriverProxy} from 'appium/driver';
|
||||
|
||||
const proxy = new JWProxy({
|
||||
const proxy = new WebDriverProxy({
|
||||
server: 'remote.server',
|
||||
port: 1234,
|
||||
base: '/',
|
||||
@@ -539,8 +544,8 @@ 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 `JWProxy` has a variety of other options which you can check out in the source code,
|
||||
as well. (TODO: publish options as API docs and link here).
|
||||
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)
|
||||
|
||||
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
|
||||
@@ -797,6 +802,12 @@ that multiple simultaneous sessions don't use the same resources:
|
||||
1. Have each driver express what resources it is using, then examine currently-used resources from
|
||||
other drivers when a new session begins.
|
||||
|
||||
!!! 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:
|
||||
|
||||
@@ -808,7 +819,7 @@ get driverData() {
|
||||
|
||||
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 `createSession` method:
|
||||
the deprecated, multi-argument form of the `createSession` method:
|
||||
|
||||
```js
|
||||
async createSession(jwpCaps, reqCaps, w3cCaps, driverData)
|
||||
|
||||
@@ -476,10 +476,10 @@ 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.js)
|
||||
in a variety of ways). But, for example, you could add new Express middleware 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:
|
||||
[configured](https://github.com/appium/appium/blob/master/packages/base-driver/lib/express/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:
|
||||
|
||||
* `expressApp`: the Express app object
|
||||
* `httpServer`: the Node HTTP server object
|
||||
@@ -492,6 +492,25 @@ results you'll need to test! Warning: this should be considered an advanced feat
|
||||
knowledge of Express, as well as the care not to do anything that could affect the operation of
|
||||
other parts of the Appium server!
|
||||
|
||||
`updateServer` runs *after* Appium's own routes are registered, so `expressApp.use(...)` here
|
||||
won't see requests to paths Appium already owns — Express matches middleware and routes in
|
||||
registration order. For middleware that must see requests to those routes too (e.g. logging or
|
||||
auth), use `httpServer.frontRouter` instead: Appium mounts this
|
||||
[Router](https://expressjs.com/en/5x/api/router/) before any route is registered, so anything
|
||||
attached to it — even from inside `updateServer` — still runs ahead of route matching. Note this
|
||||
is still *after* Appium's own baseline middleware (CORS, WebSocket upgrade handling, body
|
||||
parsing, etc.), so it won't see requests Appium itself has already rejected, e.g. a CORS
|
||||
preflight failure or a body that failed to parse:
|
||||
|
||||
```js
|
||||
static async updateServer(expressApp, httpServer, cliArgs) {
|
||||
httpServer.frontRouter.use((req, res, next) => {
|
||||
console.log(`Incoming request: ${req.method} ${req.url}`);
|
||||
next();
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Handle unexpected session shutdown
|
||||
|
||||
When developing a plugin you may want to add some cleanup logic for when a session ends. You would
|
||||
|
||||
@@ -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 is _not_ a JSON file, because a) JSON is painful to work with for humans, b) is
|
||||
This file 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://github.com/appium/appium-chromium-driver)
|
||||
### [Chromium](https://appium.github.io/appium-chromium-driver/)
|
||||
|
||||
* Target: Desktop and mobile Chromium browsers (Chrome, Microsoft Edge, etc.)
|
||||
* Target: Desktop Chromium-based browsers (Chrome, Microsoft Edge, etc.)
|
||||
* Mode: Web
|
||||
|
||||
```sh title="Install This Driver"
|
||||
appium driver install chromium
|
||||
```
|
||||
|
||||
### [Espresso](https://github.com/appium/appium-espresso-driver)
|
||||
### [Espresso](https://appium.github.io/appium-espresso-driver/)
|
||||
|
||||
* Target: Android applications
|
||||
* Mode: Native
|
||||
* Target: Android applications (mobile, TV, Wear, XR, Automotive)
|
||||
* Mode: Native, Hybrid, Web
|
||||
|
||||
```sh title="Install This Driver"
|
||||
appium driver install espresso
|
||||
```
|
||||
|
||||
### [Gecko](https://github.com/appium/appium-geckodriver)
|
||||
### [Gecko](https://appium.github.io/appium-geckodriver/)
|
||||
|
||||
* Target: Desktop and mobile Gecko browsers (Firefox)
|
||||
* Target: Desktop and mobile Gecko-based browsers (Firefox, etc.)
|
||||
* Mode: Web
|
||||
|
||||
```sh title="Install This Driver"
|
||||
appium driver install gecko
|
||||
```
|
||||
|
||||
### [Mac2](https://github.com/appium/appium-mac2-driver)
|
||||
### [Mac2](https://appium.github.io/appium-mac2-driver/)
|
||||
|
||||
* Target: macOS applications
|
||||
* Mode: Native
|
||||
@@ -51,7 +51,7 @@ appium driver install gecko
|
||||
appium driver install mac2
|
||||
```
|
||||
|
||||
### [Safari](https://github.com/appium/appium-safari-driver)
|
||||
### [Safari](https://appium.github.io/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://github.com/appium/appium-uiautomator2-driver)
|
||||
### [UiAutomator2](https://appium.github.io/appium-uiautomator2-driver/)
|
||||
|
||||
* Target: Android, Android TV, Android Wear applications
|
||||
* Target: Android applications (mobile, TV, Wear, XR, Automotive)
|
||||
* 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 applications
|
||||
* Target: iOS, iPadOS, tvOS, watchOS applications
|
||||
* Modes: Native, Hybrid, Web
|
||||
|
||||
```sh title="Install This Driver"
|
||||
@@ -126,7 +126,7 @@ appium driver install --source=npm appium-flutter-integration-driver
|
||||
appium driver install --source=npm appium-lg-webos-driver
|
||||
```
|
||||
|
||||
### [Linux](https://github.com/fantonglang/appium-linux-driver)
|
||||
### [Linux (@fantonglang)](https://github.com/fantonglang/appium-linux-driver)
|
||||
|
||||
!!! warning
|
||||
|
||||
@@ -143,6 +143,16 @@ yarn install
|
||||
node ./
|
||||
```
|
||||
|
||||
### [Linux (@Itsmeaj)](https://github.com/Itsmeaj/appium)
|
||||
|
||||
* Target: Linux desktop applications on X11 and Wayland
|
||||
* Mode: Native
|
||||
* Supported by: `@Itsmeaj`
|
||||
|
||||
```sh title="Install This Driver"
|
||||
appium driver install --source=npm @itsmeaj/appium-linux-driver
|
||||
```
|
||||
|
||||
### [NovaWindows](https://github.com/AutomateThePlanet/appium-novawindows-driver)
|
||||
|
||||
!!! info
|
||||
@@ -151,7 +161,7 @@ node ./
|
||||
[Windows driver](#windows)
|
||||
|
||||
* Target: Windows applications
|
||||
* Mode: Native
|
||||
* Mode: Native, Hybrid
|
||||
* 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 are currently maintained by the Appium team:
|
||||
These plugins are currently maintained by the Appium team:
|
||||
|
||||
### [Execute Driver](https://github.com/appium/appium/tree/master/packages/execute-driver-plugin)
|
||||
|
||||
|
||||
@@ -104,3 +104,44 @@ 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 <driver_name>`.
|
||||
`appium plugin uninstall <plugin_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 is size. This could become a serious
|
||||
Mobile application bundles could reach hundreds of megabytes in 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.js#L107) helper call.
|
||||
[`configureApp`](https://github.com/appium/appium/blob/master/packages/base-driver/lib/basedriver/helpers.ts#L99) 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 a colon (`:`). Appium's vendor
|
||||
the vendor introducing the capability), and the namespace must end in 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 use store the configuration inside an `appium`
|
||||
Further, _if your project uses Node.js,_ you can store the configuration inside an `appiumConfig`
|
||||
property in your `package.json` and it will be automatically discovered.
|
||||
|
||||
### Config File Search
|
||||
|
||||
@@ -6,18 +6,17 @@ title: Retrieving Event Timings
|
||||
---
|
||||
|
||||
Appium comes with the ability to retrieve timing information about startup
|
||||
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).
|
||||
information and command length. This is an advanced feature; the server records
|
||||
event timings for every session.
|
||||
|
||||
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:
|
||||
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:
|
||||
|
||||
```
|
||||
{
|
||||
"<event_type>": [<occurence_timestamp_1>, ...],
|
||||
"<event_type>": [<occurrence_timestamp_1>, ...],
|
||||
"commands": [
|
||||
{
|
||||
"cmd": "<command_name>",
|
||||
@@ -29,7 +28,7 @@ property:
|
||||
}
|
||||
```
|
||||
|
||||
In other words, the `events` property has 2 kinds of properties of its own:
|
||||
In other words, the event history object has 2 kinds of properties of its own:
|
||||
|
||||
* Properties which are the names of event types
|
||||
* The `commands` property
|
||||
@@ -63,7 +62,9 @@ generate various kinds of reports from event timings output:
|
||||
|
||||
!!! note
|
||||
|
||||
In the past, events were available as a part of `GET /session/:id` response
|
||||
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
|
||||
|
||||
## 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 implement new commands.
|
||||
decide how they wish to 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://github.com/appium/appium-xcuitest-driver) has implemented a command that lets a client
|
||||
Driver](https://appium.github.io/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_
|
||||
|
||||
@@ -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-adress\>**:**\<grid-port\>**/grid/console`
|
||||
`http://**\<grid-ip-address\>**:**\<grid-port\>**/grid/console`
|
||||
|
||||
### Example Grid Node Configuration JSON
|
||||
|
||||
|
||||
@@ -18,8 +18,11 @@ Each rule is an object with a set of predefined properties. The following rule p
|
||||
supported:
|
||||
|
||||
- `pattern`: A valid Javascript RegExp pattern to replace. Must be a valid non-empty pattern.
|
||||
- `text`: A simple non-empty exact text match to replace. Either this property or the above one must
|
||||
be provided. `pattern` has priority over `text` if both are provided.
|
||||
- `text`: A simple non-empty exact text to replace. Either this property or the above one must
|
||||
be provided. `pattern` has priority over `text` if both are provided. Note that the text is
|
||||
matched as a whole word: special characters are escaped and word boundaries (`\b`) are added on
|
||||
the sides where the value begins or ends with a word character. For example, a rule with text
|
||||
`pass` replaces `pass` in `my pass here`, but does not match inside `password`.
|
||||
- `flags`: Regular expression flags for the given pattern. Supported flags are the same as for the
|
||||
standard JavaScript [RegExp constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Advanced_searching_with_flags_2).
|
||||
Note that the `g` (global matching) flag is always enabled.
|
||||
|
||||
@@ -25,7 +25,7 @@ appium driver install xcuitest
|
||||
```
|
||||
|
||||
This command will install the latest version of the
|
||||
[XCUITest Driver](https://github.com/appium/appium-xcuitest-driver). The Extension CLI comes with a variety
|
||||
[XCUITest Driver](https://appium.github.io/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 ignore load
|
||||
1. If so, _unless you have specified `APPIUM_HOME` in your environment_, Appium will 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
|
||||
|
||||
@@ -106,10 +106,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/latest/)|
|
||||
|UiAutomator Driver|[UiAutomator2](https://github.com/appium/appium-uiautomator2-driver/)|
|
||||
|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://github.com/appium/appium-inspector)|
|
||||
|Appium Desktop|[Appium Inspector](https://appium.github.io/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://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-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-microsoft-windows:{ .lg } - [Windows driver](https://github.com/appium/appium-windows-driver)
|
||||
|
||||
</div>
|
||||
@@ -454,9 +454,6 @@ 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`
|
||||
|
||||
@@ -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://github.com/appium/appium-xcuitest-driver) because ultimately what it does is
|
||||
Driver](https://appium.github.io/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
|
||||
|
||||
@@ -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
|
||||
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).
|
||||
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.
|
||||
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 the WebDriver spec implementations for
|
||||
platform(s) that are semantically very similar to 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://github.com/appium/appium-safari-driver) code, for
|
||||
you look at the [Appium Safari driver](https://appium.github.io/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.
|
||||
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
# 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://github.com/appium/appium-uiautomator2-driver)
|
||||
- This guide provides instructions for the [UiAutomator2 driver](https://appium.github.io/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://github.com/appium/appium-inspector) is an
|
||||
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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
Tes code in `appium_lib` should be similar.
|
||||
Test 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://github.com/appium/appium-uiautomator2-driver). It's worth visiting that driver's
|
||||
Driver](https://appium.github.io/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://github.com/appium/appium-espresso-driver).
|
||||
(only if running macOS), and [Espresso](https://appium.github.io/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.ts)
|
||||
their origin (base Appium, driver-specific, or plugin-specific). Refer to [the type definition file](https://github.com/appium/appium/blob/master/packages/types/lib/command-maps.ts)
|
||||
for a detailed structure of this object.
|
||||
|
||||
### listExtensions
|
||||
@@ -103,9 +103,51 @@ Retrieves the [execute methods](../../guides/execute-methods.md) supported in th
|
||||
#### Response
|
||||
|
||||
`ListExtensionsResponse` - an object containing all supported execute methods, grouped by their
|
||||
origin (driver-specific or plugin-specific). Refer to [the type definition file](https://github.com/appium/appium/blob/master/packages/types/lib/command.ts)
|
||||
origin (driver-specific or plugin-specific). Refer to [the type definition file](https://github.com/appium/appium/blob/master/packages/types/lib/command-maps.ts)
|
||||
for a detailed structure of this object.
|
||||
|
||||
### getCurrentAppiumContext
|
||||
|
||||
```
|
||||
GET /session/:sessionId/appium/context
|
||||
```
|
||||
|
||||
Retrieves the active application context.
|
||||
|
||||
#### Response
|
||||
|
||||
`string` - the name of the active context
|
||||
|
||||
### setAppiumContext
|
||||
|
||||
```
|
||||
POST /session/:sessionId/appium/context
|
||||
```
|
||||
|
||||
Sets an application context as the active context.
|
||||
|
||||
#### Parameters
|
||||
|
||||
|Name|Description|Type|
|
||||
|--|--|--|
|
||||
|`name`|Name of the context to set as the active one|string|
|
||||
|
||||
#### Response
|
||||
|
||||
`null`
|
||||
|
||||
### getAppiumContexts
|
||||
|
||||
```
|
||||
GET /session/:sessionId/appium/contexts
|
||||
```
|
||||
|
||||
Retrieves all available application contexts.
|
||||
|
||||
#### Response
|
||||
|
||||
`string[]` - the names of available contexts
|
||||
|
||||
### getLogEvents
|
||||
|
||||
```
|
||||
@@ -392,3 +434,71 @@ Retrieves data from a directory on the device under test.
|
||||
#### Response
|
||||
|
||||
`string` - the Base64-encoded zip file of the directory contents
|
||||
|
||||
### getAppiumRotation
|
||||
|
||||
```
|
||||
GET /session/:sessionId/appium/device/rotation
|
||||
```
|
||||
|
||||
Retrieves the current spatial orientation of the device under test.
|
||||
|
||||
#### Response
|
||||
|
||||
`Rotation` - an object with the following properties:
|
||||
|
||||
|Name|Description|Type|
|
||||
|--|--|--|
|
||||
|`x`|Degrees by which the device is rotated on its X axis|number|
|
||||
|`y`|Degrees by which the device is rotated on its Y axis|number|
|
||||
|`z`|Degrees by which the device is rotated on its Z axis|number|
|
||||
|
||||
### setAppiumRotation
|
||||
|
||||
```
|
||||
POST /session/:sessionId/appium/device/rotation
|
||||
```
|
||||
|
||||
Sets the spatial orientation of the device under test.
|
||||
|
||||
#### Parameters
|
||||
|
||||
|Name|Description|Type|
|
||||
|--|--|--|
|
||||
|`x`|Degrees by which the device is rotated on its X axis|number|
|
||||
|`y`|Degrees by which the device is rotated on its Y axis|number|
|
||||
|`z`|Degrees by which the device is rotated on its Z axis|number|
|
||||
|
||||
#### Response
|
||||
|
||||
`null`
|
||||
|
||||
### getAppiumOrientation
|
||||
|
||||
```
|
||||
GET /session/:sessionId/appium/device/orientation
|
||||
```
|
||||
|
||||
Retrieves the current orientation of the device under test.
|
||||
|
||||
#### Response
|
||||
|
||||
`string` - either `PORTRAIT` or `LANDSCAPE`
|
||||
|
||||
### setAppiumOrientation
|
||||
|
||||
```
|
||||
POST /session/:sessionId/appium/device/orientation
|
||||
```
|
||||
|
||||
Sets the orientation of the device under test.
|
||||
|
||||
#### Parameters
|
||||
|
||||
|Name|Description|Type|
|
||||
|--|--|--|
|
||||
|`orientation`|New device orientation. Supported values are `PORTRAIT` or `LANDSCAPE`.|string|
|
||||
|
||||
#### Response
|
||||
|
||||
`null`
|
||||
|
||||
@@ -46,7 +46,7 @@ Subscribes to one or more BiDi events.
|
||||
|
||||
#### Response
|
||||
|
||||
`null`
|
||||
`{subscription: string}` — a unique subscription ID that can be passed to `session.unsubscribe`.
|
||||
|
||||
### bidiUnsubscribe
|
||||
|
||||
@@ -56,15 +56,20 @@ session.unsubscribe
|
||||
|
||||
> WebDriver BiDi documentation: [session.unsubscribe](https://w3c.github.io/webdriver-bidi/#command-session-unsubscribe)
|
||||
|
||||
Unsubscribes from one or more BiDi events.
|
||||
Unsubscribes using either previously returned subscription IDs or event names.
|
||||
Removing a subscription ID preserves any overlapping subscriptions.
|
||||
|
||||
#### Parameters
|
||||
|
||||
|Name|Description|Type|Default|
|
||||
|--|--|--|--|
|
||||
|`contexts?`|Contexts in which to unsubscribe from the specified events. By default, the global scope is applied.|string[]|`['']`|
|
||||
|`events`|Names of events to unsubscribe from|string[]||
|
||||
|`subscriptions?`|Non-empty list of subscription IDs returned by `session.subscribe`. Cannot be combined with `events` or `contexts`.|string[]||
|
||||
|`contexts?`|Non-standard, only together with `events`: contexts in which to unsubscribe from the specified events. By default, the global scope is applied.|string[]|`['']`|
|
||||
|`events?`|Non-empty list of event names to unsubscribe from. Required when `subscriptions` is omitted.|string[]||
|
||||
|
||||
All subscription IDs must be known to the current session. An unknown ID causes an `invalid argument`
|
||||
error without removing any subscriptions. Subscription IDs are cleared when the session is deleted.
|
||||
|
||||
#### Response
|
||||
|
||||
`null`
|
||||
`{}`
|
||||
|
||||
@@ -139,6 +139,10 @@ GET /session/:sessionId/orientation
|
||||
|
||||
Retrieves the current orientation of the device under test.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Please use [`getAppiumOrientation`](./appium.md#getappiumorientation) instead
|
||||
|
||||
#### Response
|
||||
|
||||
`string` - either `PORTRAIT` or `LANDSCAPE`
|
||||
@@ -153,6 +157,10 @@ POST /session/:sessionId/orientation
|
||||
|
||||
Sets the orientation of the device under test.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Please use [`setAppiumOrientation`](./appium.md#setappiumorientation) instead
|
||||
|
||||
#### Parameters
|
||||
|
||||
|Name|Description|Type|
|
||||
|
||||
@@ -20,6 +20,10 @@ GET /session/:sessionId/rotation
|
||||
|
||||
Retrieves the current spatial orientation of the device under test.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Please use [`getAppiumRotation`](./appium.md#getappiumrotation) instead
|
||||
|
||||
#### Response
|
||||
|
||||
`Rotation` - an object with the following properties:
|
||||
@@ -40,6 +44,10 @@ POST /session/:sessionId/rotation
|
||||
|
||||
Sets the spatial orientation of the device under test.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Please use [`setAppiumRotation`](./appium.md#setappiumrotation) instead
|
||||
|
||||
#### Parameters
|
||||
|
||||
|Name|Description|Type|
|
||||
@@ -62,6 +70,10 @@ GET /session/:sessionId/context
|
||||
|
||||
Retrieves the active application context.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Please use [`getCurrentAppiumContext`](./appium.md#getcurrentappiumcontext) instead
|
||||
|
||||
#### Response
|
||||
|
||||
`string` - the name of the active context
|
||||
@@ -76,6 +88,10 @@ POST /session/:sessionId/context
|
||||
|
||||
Sets an application context as the active context.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Please use [`setAppiumContext`](./appium.md#setappiumcontext) instead
|
||||
|
||||
#### Parameters
|
||||
|
||||
|Name|Description|Type|
|
||||
@@ -96,6 +112,10 @@ GET /session/:sessionId/contexts
|
||||
|
||||
Retrieves all available application contexts.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Please use [`getAppiumContexts`](./appium.md#getappiumcontexts) instead
|
||||
|
||||
#### Response
|
||||
|
||||
`string[]` - the names of available contexts
|
||||
|
||||
@@ -169,10 +169,17 @@ Modifies the [`createSession`](./webdriver.md#createsession) endpoint:
|
||||
All endpoints for this plugin can be invoked without creating a session, allowing you to prepare
|
||||
your test environment in advance.
|
||||
|
||||
!!! info
|
||||
|
||||
Prior to plugin version 1.2.0, all endpoints below were mounted under the `/storage` prefix
|
||||
(e.g. `/storage/add`) instead of `/appium/storage`. The `/storage`-prefixed routes are still
|
||||
available for backward compatibility, but are deprecated and will be removed in a future
|
||||
version of the plugin.
|
||||
|
||||
### addStorageItem
|
||||
|
||||
```
|
||||
POST /storage/add
|
||||
POST /appium/storage/add
|
||||
```
|
||||
|
||||
Adds a new file to the storage.
|
||||
@@ -198,8 +205,8 @@ Example:
|
||||
```json
|
||||
{
|
||||
"ws": {
|
||||
"stream": "/storage/add/ccc963411b2621335657963322890305ebe96186/stream",
|
||||
"events": "/storage/add/ccc963411b2621335657963322890305ebe96186/events"
|
||||
"stream": "/appium/storage/add/ccc963411b2621335657963322890305ebe96186/stream",
|
||||
"events": "/appium/storage/add/ccc963411b2621335657963322890305ebe96186/events"
|
||||
},
|
||||
"ttlMs": 300000
|
||||
}
|
||||
@@ -208,7 +215,7 @@ Example:
|
||||
### deleteStorageItem
|
||||
|
||||
```
|
||||
POST /storage/delete
|
||||
POST /appium/storage/delete
|
||||
```
|
||||
|
||||
Deletes a file in the storage.
|
||||
@@ -227,7 +234,7 @@ the storage, or if the delete request is invalid.
|
||||
### listStorageItems
|
||||
|
||||
```
|
||||
GET /storage/list
|
||||
GET /appium/storage/list
|
||||
```
|
||||
|
||||
List all files present in the storage.
|
||||
@@ -245,7 +252,7 @@ List all files present in the storage.
|
||||
### resetStorage
|
||||
|
||||
```
|
||||
POST /storage/reset
|
||||
POST /appium/storage/reset
|
||||
```
|
||||
|
||||
Deletes all uploaded files and stops any incomplete uploads.
|
||||
|
||||
@@ -13,6 +13,12 @@ Provides management options for a specific extension (driver or plugin). Both th
|
||||
The following sub-subcommands are supported: `doctor`, `install`, `list`, `run`, `update`,
|
||||
and `uninstall`.
|
||||
|
||||
For `doctor`, `run`, `update`, and `uninstall`, you can identify an installed extension by its
|
||||
short name or its exact npm package name. For example, `appium driver uninstall uiautomator2`
|
||||
and `appium driver uninstall appium-uiautomator2-driver` refer to the same installed driver.
|
||||
Short names take precedence if a name also matches another extension's package name. Package names
|
||||
can include a scope, such as `@appium/fake-driver`, but must not include a version or tag suffix.
|
||||
|
||||
## `doctor`
|
||||
|
||||
Runs doctor checks for an installed extension, which validate whether the extension has its prerequisites
|
||||
@@ -31,7 +37,7 @@ appium {driver|plugin} doctor <extension-name>
|
||||
|
||||
|Argument|Description|
|
||||
|--|--|
|
||||
|`extension-name`|The short name of the installed extension|
|
||||
|`extension-name`|The short name or exact npm package name of the installed extension|
|
||||
|
||||
#### Options
|
||||
|
||||
@@ -75,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 URL of the extension|
|
||||
|`github`|The GitHub repository slug of the extension, in the form `<org>/<repo>`|
|
||||
|`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)|
|
||||
|
||||
@@ -108,7 +114,7 @@ appium {driver|plugin} install <install-spec>
|
||||
- Install the XCUITest driver from GitHub:
|
||||
|
||||
```
|
||||
appium driver install https://github.com/appium/appium-xcuitest-driver --source=github --package=appium-xcuitest-driver
|
||||
appium driver install appium/appium-xcuitest-driver --source=github --package=appium-xcuitest-driver
|
||||
```
|
||||
|
||||
- Install the XCUITest driver using a Git URL:
|
||||
@@ -158,13 +164,13 @@ extensions include scripts.
|
||||
#### Usage
|
||||
|
||||
```
|
||||
appium {driver|plugin} run <extension-name> <script-name> [script-args]
|
||||
appium {driver|plugin} run <extension-name> [<script-name> [<script-args>]]
|
||||
```
|
||||
|
||||
|Argument|Description|
|
||||
|--|--|
|
||||
|`extension-name`|The short name of the installed extension|
|
||||
|`script-name`|The name of the script to be run|
|
||||
|`extension-name`|The short name or exact npm package name of the installed extension|
|
||||
|`script-name`|The name of the script to run. If not provided, a list of available scripts is returned.|
|
||||
|`script-args`|Any additional arguments passed to the script|
|
||||
|
||||
#### Options
|
||||
@@ -181,6 +187,12 @@ appium {driver|plugin} run <extension-name> <script-name> [script-args]
|
||||
appium driver run uiautomator2 reset
|
||||
```
|
||||
|
||||
- List all available scripts included in the XCUITest driver:
|
||||
|
||||
```
|
||||
appium driver run xcuitest
|
||||
```
|
||||
|
||||
## `update`
|
||||
|
||||
Updates one or more extensions. Only supported for extensions installed via `npm`. By default,
|
||||
@@ -194,7 +206,7 @@ appium {driver|plugin} update <extension-name>
|
||||
|
||||
|Argument|Description|
|
||||
|--|--|
|
||||
|`extension-name`|The short name of the installed extension, or `installed` to update all installed extensions|
|
||||
|`extension-name`|The short name or exact npm package name of the installed extension, or `installed` to update all installed extensions|
|
||||
|
||||
#### Options
|
||||
|
||||
@@ -229,7 +241,7 @@ appium {driver|plugin} uninstall <extension-name>
|
||||
|
||||
|Argument|Description|
|
||||
|--|--|
|
||||
|`extension-name`|The short name of the installed extension|
|
||||
|`extension-name`|The short name or exact npm package name of the installed extension|
|
||||
|
||||
#### Options
|
||||
|
||||
|
||||
@@ -26,12 +26,12 @@ appium
|
||||
|
||||
|<div style="width:15em">Argument</div>|Description|Type|<div style="width:7em">Default</div>|
|
||||
|--|--|--|--|
|
||||
|`--address`, `-a`|IPv4/IPv6 address to listen on|string|`0.0.0.0`|
|
||||
|`--address`, `-a`|IPv4/IPv6 address or a hostname to listen on|string|`0.0.0.0`|
|
||||
|`--allow-cors`|Allow web browser connections from any host|boolean|`false`|
|
||||
|`--allow-insecure`|List of [insecure features](../../guides/security.md) that should be allowed in this server's sessions. Individual features can be overridden by `--deny-insecure`. Has no effect in combination with `--relaxed-security`.|array<string>|`[]`|
|
||||
|`--allow-unknown-args`|Do not exit if unrecognized command-line arguments are passed to the server; ignore them instead. Useful when the Appium CLI is wrapped by external tooling that appends extra flags.|boolean|`false`|
|
||||
|`--base-path`, `-pa`|Base path to use as the prefix for all webdriver routes running on the server|string|`""`|
|
||||
|`--callback-address`, `-ca`|Callback IP address|string|`0.0.0.0`|
|
||||
|`--callback-address`, `-ca`|Callback IP address|string|same as `--address`|
|
||||
|`--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`|
|
||||
@@ -65,7 +65,7 @@ appium
|
||||
|`--tmp`|Absolute path to the directory used for temporary files|string|[`os.tmpdir()`](https://nodejs.org/api/os.html#ostmpdir)|
|
||||
|`--use-drivers`|List of drivers to activate. By default, all installed drivers are activated.|array<string>|`[]`|
|
||||
|`--use-plugins`|List of plugins to activate. By default, no plugins are activated. Set to `["all"]` to activate all installed plugins.|array<string>|`[]`|
|
||||
|`--webhook`, `-G`|URL for an HTTP listener where the server logs should be output. This does not affect output on the console.|string||
|
||||
|`--webhook`, `-G`|URL for an HTTP listener where the server logs should be output. This does not affect output on the console. A bare `host:port` is also accepted, which posts the logs to the root path over plain http; a value having neither a scheme nor a port falls back to `127.0.0.1:9003`.|string||
|
||||
|
||||
### Info Options
|
||||
|
||||
|
||||
@@ -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 the page source and its printing to the Appium log, whenever a request to find an element fails | `boolean` ||
|
||||
| `appium:printPageSourceOnFindFailure` | Toggle retrieval of the page source and its printing to the Appium log, whenever a request to find an element fails | `boolean` ||
|
||||
|
||||
### Validated Capabilities
|
||||
|
||||
|
||||
@@ -17,3 +17,8 @@ authors:
|
||||
avatar: 'https://avatars.githubusercontent.com/u/4045041?v=4'
|
||||
slug: 'sai'
|
||||
url: 'https://saikrishna.tech'
|
||||
mykola:
|
||||
name: 'Mykola Mokhnach'
|
||||
description: 'Appium Core Maintainer'
|
||||
avatar: https://avatars.githubusercontent.com/u/7767781?v=4
|
||||
slug: 'mykola'
|
||||
|
||||
@@ -8,11 +8,13 @@ date: 2025-11-25
|
||||
# Announcing LambdaTest as Appium's Newest Development Partner
|
||||
|
||||
As part of our ongoing effort to recognize organizations that meaningfully support the Appium project through dedicated maintainer time, we are excited to welcome our newest Development Partner: LambdaTest!
|
||||
LambdaTest has long been an active participant in the automated testing ecosystem. Today, they are officially formalizing their commitment by investing people—dedicated engineers who will directly support Appium's development, maintenance, and ecosystem growth.
|
||||
This kind of hands-on contribution is crucial for ensuring Appium continues to evolve. We deeply value partners who empower their engineering teams to contribute code directly to open source rather than just sponsorship.
|
||||
|
||||
<!-- more -->
|
||||
|
||||
LambdaTest has long been an active participant in the automated testing ecosystem. Today, they are officially formalizing their commitment by investing people—dedicated engineers who will directly support Appium's development, maintenance, and ecosystem growth.
|
||||
|
||||
This kind of hands-on contribution is crucial for ensuring Appium continues to evolve. We deeply value partners who empower their engineering teams to contribute code directly to open source rather than just sponsorship.
|
||||
|
||||
<div style="text-align:center;width:100%"><a href="https://lambdatest.com/?utm_source=appium.io&utm_medium=organic&utm_campaign=june_25&utm_term=sk&utm_content=webpage">
|
||||
<img src="/docs/en/latest/assets/images/sponsor-logo-lambdatest-dark.png#only-dark" width="300" />
|
||||
<img src="/docs/en/latest/assets/images/sponsor-logo-lambdatest-light.png#only-light" width="300" />
|
||||
@@ -20,15 +22,19 @@ This kind of hands-on contribution is crucial for ensuring Appium continues to e
|
||||
</div>
|
||||
|
||||
LambdaTest engineers are already contributing actively across several key Appium repositories. Their current focus includes:
|
||||
**appium-mcp** – Supporting Appium's implementation of the Model Context Protocol (MCP) to drive forward modern AI-assisted capabilities.
|
||||
**appium-remote-xpc** – Contributing to the native macOS/XPC-based remote execution layer, essential for iOS automation.
|
||||
**appium-tun-tap** – Assisting in the development and maintenance of network virtualization and tunneling components for advanced testing scenarios.
|
||||
|
||||
- [`appium-mcp`](https://github.com/appium/appium-mcp) – Supporting Appium's implementation of the Model Context Protocol (MCP) to drive forward modern AI-assisted capabilities.
|
||||
- [`appium-ios-remotexpc`](https://github.com/appium/appium-ios-remotexpc) – Contributing to the native macOS/XPC-based remote execution layer, essential for iOS automation.
|
||||
- [`appium-ios-tuntap`](https://github.com/appium/appium-ios-tuntap) – Assisting in the development and maintenance of network virtualization and tunneling components for advanced testing scenarios.
|
||||
|
||||
These contributions strengthen critical infrastructure within the Appium ecosystem and demonstrate LambdaTest's commitment to deep technical involvement in the project's evolution.
|
||||
About LambdaTest
|
||||
|
||||
**About LambdaTest**
|
||||
|
||||
LambdaTest’s platform already serves a massive community of Appium users. As a GenAI-powered Quality Engineering Platform, they provide a full-stack testing cloud with 10,000+ real mobile devices and 3,000+ browsers.
|
||||
|
||||
Beyond standard infrastructure, they are pushing the boundaries of test execution with AI-native test management and next-generation agents like KaneAI. By supporting Appium alongside Selenium, Playwright, and other major frameworks, LambdaTest helps teams orchestrate intelligent automation at cloud scale.
|
||||
|
||||
LambdaTest will continue contributing people, code, and development expertise to strengthen Appium's core functionality. Their commitment represents a significant investment into the future of the framework, and we're thrilled to have them collaborating with us at this deeper level.
|
||||
|
||||
The Appium project is proud to recognize LambdaTest as our newest official Development Partner. We can't wait to see what we'll build together!
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
authors:
|
||||
- mykola
|
||||
date: 2026-09-01
|
||||
---
|
||||
|
||||
# Announcing watchOS Simulator Support in the XCUITest Driver
|
||||
|
||||
We’re excited to announce that the XCUITest driver now supports automation of watchOS apps — a
|
||||
platform that’s been on Appium’s requested list for a long time.
|
||||
|
||||
<!-- more -->
|
||||
|
||||
In order to automate watchOS, you'll need the following:
|
||||
|
||||
- XCUITest driver version 12.6.0 or later (WebDriverAgent 16.5.0 or later)
|
||||
- Xcode 15.4 or later
|
||||
- watchOS 10 or later
|
||||
|
||||
Important to note: ^^the driver currently only works with simulators — real devices are not
|
||||
compatible.^^
|
||||
|
||||
The good news: automating a watchOS app looks just like automating any other iOS/iPadOS app. The
|
||||
standard use-cases of finding and clicking on elements, retrieving the page source, using the
|
||||
Appium Inspector — all work as usual. The one exception here is standard W3C gesture/touch actions
|
||||
(tap/swipe via the Actions API), which are not supported.
|
||||
|
||||
On top of that, a few watchOS-specific extensions are available:
|
||||
|
||||
- `mobile: pressButton` — press the Digital Crown or Action button
|
||||
- `mobile: rotateDigitalCrown` — rotate the Digital Crown (since driver version 12.7.0)
|
||||
- `mobile: performHandGesture` — perform double-tap or wrist flick hand gestures (since driver
|
||||
version 12.7.0)
|
||||
|
||||
For full setup instructions, capabilities, and limitations, check out the
|
||||
[watchOS guide](https://appium.github.io/appium-xcuitest-driver/latest/guides/watchos/).
|
||||
|
||||
Happy testing!
|
||||
@@ -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/api/runme?repository=https%3A%2F%2Fgithub.com%2Fappium%2Fappium.git&fileToOpen=packages%2Fappium%2Fdocs%2Fen%2Fcontributing%2Findex.md).
|
||||
If you are VS Code user, you can easily check out the project using [Runme](https://runme.dev/).
|
||||
|
||||
Install dependencies:
|
||||
|
||||
@@ -109,6 +109,27 @@ 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,6 +62,33 @@ 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,8 +80,9 @@ 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. Known platform name strings include: `iOS`,
|
||||
`tvOS`, `macOS`, `Windows`, `Android`.
|
||||
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`.
|
||||
- `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).
|
||||
|
||||
@@ -222,17 +223,24 @@ So you'll probably end up overriding `createSession`. You can do so by defining
|
||||
driver:
|
||||
|
||||
```js
|
||||
async createSession(jwpCaps, reqCaps, w3cCaps, otherDriverData) {
|
||||
const [sessionId, caps] = super.createSession(w3cCaps);
|
||||
async createSession(w3cCaps) {
|
||||
const [sessionId, caps] = await super.createSession(w3cCaps);
|
||||
// do your own stuff here
|
||||
return [sessionId, caps];
|
||||
}
|
||||
```
|
||||
|
||||
For legacy reasons, your function will receive old-style JSON Wire Protocol desired and required
|
||||
caps as the first two arguments. Given that the old protocol isn't supported anymore and clients
|
||||
have all been updated, you can instead only rely on the `w3cCaps` parameter. (For a discussion
|
||||
about what `otherDriverData` is about, see the section below on concurrent drivers).
|
||||
!!! 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`
|
||||
@@ -276,8 +284,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.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
|
||||
[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
|
||||
receive for that command.
|
||||
|
||||
Let's take this block for example:
|
||||
@@ -320,7 +328,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.js](https://github.com/appium/appium/blob/master/packages/base-driver/lib/protocol/bidi-commands.js)
|
||||
[bidi-commands.ts](https://github.com/appium/appium/blob/master/packages/base-driver/lib/protocol/bidi-commands.ts)
|
||||
|
||||
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
|
||||
@@ -522,14 +530,13 @@ route, then the route will not be proxied and instead will be handled by your dr
|
||||
example, we are avoiding proxying all `POST` routes that have the `appium` prefix.
|
||||
|
||||
Next, we have to set up the proxying itself. The way to do this is to use a special class from
|
||||
Appium called `JWProxy`. (The name means "JSON Wire Proxy" and is related to a legacy
|
||||
implementation of the protocol). You'll want to create a `JWProxy` object using the details required to
|
||||
connect to the remote server:
|
||||
Appium called `WebDriverProxy`. You'll want to create a `WebDriverProxy` object using the details
|
||||
required to connect to the remote server:
|
||||
|
||||
```js
|
||||
// import {JWProxy} from 'appium/driver';
|
||||
// import {WebDriverProxy} from 'appium/driver';
|
||||
|
||||
const proxy = new JWProxy({
|
||||
const proxy = new WebDriverProxy({
|
||||
server: 'remote.server',
|
||||
port: 1234,
|
||||
base: '/',
|
||||
@@ -541,8 +548,8 @@ 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 `JWProxy` has a variety of other options which you can check out in the source code,
|
||||
as well. (TODO: publish options as API docs and link here).
|
||||
this step! The `WebDriverProxy` has a variety of other options which you can check out in the
|
||||
source code as well.
|
||||
|
||||
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
|
||||
@@ -799,6 +806,14 @@ that multiple simultaneous sessions don't use the same resources:
|
||||
3. Have each driver express what resources it is using, then examine currently-used resources from
|
||||
other drivers when a new session begins.
|
||||
|
||||
!!! 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:
|
||||
|
||||
@@ -810,7 +825,7 @@ get driverData() {
|
||||
|
||||
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 `createSession` method:
|
||||
the deprecated, multi-argument form of the `createSession` method:
|
||||
|
||||
```js
|
||||
async createSession(jwpCaps, reqCaps, w3cCaps, driverData)
|
||||
|
||||
@@ -482,10 +482,10 @@ 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.js)
|
||||
in a variety of ways). But, for example, you could add new Express middleware 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:
|
||||
[configured](https://github.com/appium/appium/blob/master/packages/base-driver/lib/express/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:
|
||||
|
||||
- `expressApp`: the Express app object
|
||||
- `httpServer`: the Node HTTP server object
|
||||
@@ -498,6 +498,25 @@ results you'll need to test! Warning: this should be considered an advanced feat
|
||||
knowledge of Express, as well as the care not to do anything that could affect the operation of
|
||||
other parts of the Appium server!
|
||||
|
||||
`updateServer` runs _after_ Appium's own routes are registered, so `expressApp.use(...)` here
|
||||
won't see requests to paths Appium already owns — Express matches middleware and routes in
|
||||
registration order. For middleware that must see requests to those routes too (e.g. logging or
|
||||
auth), use `httpServer.frontRouter` instead: Appium mounts this
|
||||
[Router](https://expressjs.com/en/5x/api/router/) before any route is registered, so anything
|
||||
attached to it — even from inside `updateServer` — still runs ahead of route matching. Note this
|
||||
is still _after_ Appium's own baseline middleware (CORS, WebSocket upgrade handling, body
|
||||
parsing, etc.), so it won't see requests Appium itself has already rejected, e.g. a CORS
|
||||
preflight failure or a body that failed to parse:
|
||||
|
||||
```js
|
||||
static async updateServer(expressApp, httpServer, cliArgs) {
|
||||
httpServer.frontRouter.use((req, res, next) => {
|
||||
console.log(`Incoming request: ${req.method} ${req.url}`);
|
||||
next();
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Handle unexpected session shutdown
|
||||
|
||||
When developing a plugin you may want to add some cleanup logic for when a session ends. You would
|
||||
|
||||
@@ -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 is _not_ a JSON file, because a) JSON is painful to work with for humans, b) is
|
||||
This file 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://github.com/appium/appium-chromium-driver)
|
||||
### [Chromium](https://appium.github.io/appium-chromium-driver/)
|
||||
|
||||
- Target: Desktop and mobile Chromium browsers (Chrome, Microsoft Edge, etc.)
|
||||
- Target: Desktop Chromium-based browsers (Chrome, Microsoft Edge, etc.)
|
||||
- Mode: Web
|
||||
|
||||
```sh title="Install This Driver"
|
||||
appium driver install chromium
|
||||
```
|
||||
|
||||
### [Espresso](https://github.com/appium/appium-espresso-driver)
|
||||
### [Espresso](https://appium.github.io/appium-espresso-driver/)
|
||||
|
||||
- Target: Android applications
|
||||
- Mode: Native
|
||||
- Target: Android applications (mobile, TV, Wear, XR, Automotive)
|
||||
- Mode: Native, Hybrid, Web
|
||||
|
||||
```sh title="Install This Driver"
|
||||
appium driver install espresso
|
||||
```
|
||||
|
||||
### [Gecko](https://github.com/appium/appium-geckodriver)
|
||||
### [Gecko](https://appium.github.io/appium-geckodriver/)
|
||||
|
||||
- Target: Desktop and mobile Gecko browsers (Firefox)
|
||||
- Target: Desktop and mobile Gecko-based browsers (Firefox, etc.)
|
||||
- Mode: Web
|
||||
|
||||
```sh title="Install This Driver"
|
||||
appium driver install gecko
|
||||
```
|
||||
|
||||
### [Mac2](https://github.com/appium/appium-mac2-driver)
|
||||
### [Mac2](https://appium.github.io/appium-mac2-driver/)
|
||||
|
||||
- Target: macOS applications
|
||||
- Mode: Native
|
||||
@@ -53,7 +53,7 @@ appium driver install gecko
|
||||
appium driver install mac2
|
||||
```
|
||||
|
||||
### [Safari](https://github.com/appium/appium-safari-driver)
|
||||
### [Safari](https://appium.github.io/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://github.com/appium/appium-uiautomator2-driver)
|
||||
### [UiAutomator2](https://appium.github.io/appium-uiautomator2-driver/)
|
||||
|
||||
- Target: Android, Android TV, Android Wear applications
|
||||
- Target: Android applications (mobile, TV, Wear, XR, Automotive)
|
||||
- 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 applications
|
||||
- Target: iOS, iPadOS, tvOS, watchOS applications
|
||||
- Modes: Native, Hybrid, Web
|
||||
|
||||
```sh title="Install This Driver"
|
||||
@@ -130,7 +130,7 @@ appium driver install --source=npm appium-flutter-integration-driver
|
||||
appium driver install --source=npm appium-lg-webos-driver
|
||||
```
|
||||
|
||||
### [Linux](https://github.com/fantonglang/appium-linux-driver)
|
||||
### [Linux (@fantonglang)](https://github.com/fantonglang/appium-linux-driver)
|
||||
|
||||
!!! warning
|
||||
|
||||
@@ -149,6 +149,16 @@ yarn install
|
||||
node ./
|
||||
```
|
||||
|
||||
### [Linux (@Itsmeaj)](https://github.com/Itsmeaj/appium)
|
||||
|
||||
- Target: Linux desktop applications on X11 and Wayland
|
||||
- Mode: Native
|
||||
- Supported by: `@Itsmeaj`
|
||||
|
||||
```sh title="Install This Driver"
|
||||
appium driver install --source=npm @itsmeaj/appium-linux-driver
|
||||
```
|
||||
|
||||
### [NovaWindows](https://github.com/AutomateThePlanet/appium-novawindows-driver)
|
||||
|
||||
!!! info
|
||||
@@ -159,7 +169,7 @@ This driver is recommended as a drop-in replacement for the partially unmaintain
|
||||
```
|
||||
|
||||
- Target: Windows applications
|
||||
- Mode: Native
|
||||
- Mode: Native, Hybrid
|
||||
- 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 are currently maintained by the Appium team:
|
||||
These plugins are currently maintained by the Appium team:
|
||||
|
||||
### [Execute Driver](https://github.com/appium/appium/tree/master/packages/execute-driver-plugin)
|
||||
|
||||
|
||||
@@ -113,3 +113,44 @@ 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 <driver_name>`.
|
||||
`appium plugin uninstall <plugin_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 is size. This could become a serious
|
||||
Mobile application bundles could reach hundreds of megabytes in 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.js#L107) helper call.
|
||||
[`configureApp`](https://github.com/appium/appium/blob/master/packages/base-driver/lib/basedriver/helpers.ts#L99) 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 a colon (`:`). Appium's vendor
|
||||
the vendor introducing the capability), and the namespace must end in 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 use store the configuration inside an `appium`
|
||||
Further, _if your project uses Node.js,_ you can store the configuration inside an `appiumConfig`
|
||||
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,18 +6,17 @@ title: Retrieving Event Timings
|
||||
---
|
||||
|
||||
Appium comes with the ability to retrieve timing information about startup
|
||||
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).
|
||||
information and command length. This is an advanced feature; the server records
|
||||
event timings for every session.
|
||||
|
||||
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:
|
||||
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:
|
||||
|
||||
```
|
||||
{
|
||||
"<event_type>": [<occurence_timestamp_1>, ...],
|
||||
"<event_type>": [<occurrence_timestamp_1>, ...],
|
||||
"commands": [
|
||||
{
|
||||
"cmd": "<command_name>",
|
||||
@@ -29,7 +28,7 @@ property:
|
||||
}
|
||||
```
|
||||
|
||||
In other words, the `events` property has 2 kinds of properties of its own:
|
||||
In other words, the event history object has 2 kinds of properties of its own:
|
||||
|
||||
- Properties which are the names of event types
|
||||
- The `commands` property
|
||||
@@ -64,7 +63,9 @@ generate various kinds of reports from event timings output:
|
||||
!!! note
|
||||
|
||||
```
|
||||
In the past, events were available as a part of `GET /session/:id` response
|
||||
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
|
||||
```
|
||||
|
||||
## 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 implement new commands.
|
||||
decide how they wish to 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-adress\>**:**\<grid-port\>**/grid/console`
|
||||
`http://**\<grid-ip-address\>**:**\<grid-port\>**/grid/console`
|
||||
|
||||
### Example Grid Node Configuration JSON
|
||||
|
||||
|
||||
@@ -18,8 +18,11 @@ Each rule is an object with a set of predefined properties. The following rule p
|
||||
supported:
|
||||
|
||||
- `pattern`: A valid Javascript RegExp pattern to replace. Must be a valid non-empty pattern.
|
||||
- `text`: A simple non-empty exact text match to replace. Either this property or the above one must
|
||||
be provided. `pattern` has priority over `text` if both are provided.
|
||||
- `text`: A simple non-empty exact text to replace. Either this property or the above one must
|
||||
be provided. `pattern` has priority over `text` if both are provided. Note that the text is
|
||||
matched as a whole word: special characters are escaped and word boundaries (`\b`) are added on
|
||||
the sides where the value begins or ends with a word character. For example, a rule with text
|
||||
`pass` replaces `pass` in `my pass here`, but does not match inside `password`.
|
||||
- `flags`: Regular expression flags for the given pattern. Supported flags are the same as for the
|
||||
standard JavaScript [RegExp constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#Advanced_searching_with_flags_2).
|
||||
Note that the `g` (global matching) flag is always enabled.
|
||||
|
||||
@@ -27,7 +27,7 @@ appium driver install xcuitest
|
||||
```
|
||||
|
||||
This command will install the latest version of the
|
||||
[XCUITest Driver](https://github.com/appium/appium-xcuitest-driver). The Extension CLI comes with a variety
|
||||
[XCUITest Driver](https://appium.github.io/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 ignore load
|
||||
3. If so, _unless you have specified `APPIUM_HOME` in your environment_, Appium will 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/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) |
|
||||
| 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/) |
|
||||
|
||||
!!! info "Actions Needed"
|
||||
|
||||
|
||||
@@ -8,8 +8,7 @@ title: Appium 3 へ移行する
|
||||
}
|
||||
</style>
|
||||
|
||||
このドキュメントは既にAppium 2 を利用している人がAppium 3 に移行するための手引きです。
|
||||
破壊的変更と、それらを処理するためのヒントが含まれています。
|
||||
このドキュメントは既にAppium 2 を利用している人がAppium 3 に移行するための手引きです。破壊的変更と、それらを処理するためのヒントが含まれています。
|
||||
|
||||
Appium 2 はAppiumアーキテクチャ全体の大きな見直しをしました。 Appium 3 は限られた破壊的変更のみの比較的小さな更新であり、移行プロセスがはるかに簡易になります。
|
||||
|
||||
@@ -142,293 +141,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://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-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-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
|
||||
|
||||
@@ -437,22 +436,19 @@ 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`
|
||||
- `POST /session/:sessionId/timeouts`
|
||||
- :octicons-x-24: `type`, `ms`
|
||||
- :octicons-check-24: `script`, `pageLoad`, `implicit`
|
||||
- :octicons-x-24: `value`
|
||||
- :octicons-check-24: `text`
|
||||
- `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
|
||||
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).
|
||||
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.
|
||||
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 the WebDriver spec implementations for
|
||||
platform(s) that are semantically very similar to 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://github.com/appium/appium-safari-driver) code, for
|
||||
you look at the [Appium Safari driver](https://appium.github.io/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ドライバーとその依存関係をインストールする
|
||||
- このガイドでは、[UiAutomator2 driver](https://github.com/appium/appium-uiautomator2-driver) について説明します
|
||||
- This guide provides instructions for the [UiAutomator2 driver](https://appium.github.io/appium-uiautomator2-driver/)
|
||||
3. お好みの言語でAppiumクライアント・ライブラリをインストールする
|
||||
- このガイドでは、JavaScript、Python、Java、Ruby、.NETの例で説明します
|
||||
4. サンプルアプリケーションを使用した簡単なAppiumでの自動化スクリプトの作成と実行
|
||||
|
||||
### 必要条件
|
||||
|
||||
始める前に、お使いのシステムが[要件](../quickstart/requirements.md) を満たしていることを確認してください。 追加要件については、UiAutomator2 ドライバーのインストールと合わせて説明します。 また、このガイドでは基本的なコマンド実行や環境変数の設定と保持などができることを前提としています。
|
||||
始める前に、お使いのシステムが[要件](../quickstart/requirements.md) を満たしていることを確認してください。追加要件については、UiAutomator2 ドライバーのインストールと合わせて説明します。また、このガイドでは基本的なコマンド実行や環境変数の設定と保持などができることを前提としています。
|
||||
|
||||
さあ、これで準備は整いました! [Appiumのインストール](./install.md)に進んでください。
|
||||
|
||||
@@ -5,14 +5,16 @@ hide:
|
||||
title: 次のステップ
|
||||
---
|
||||
|
||||
Android自動化用のシステムの設定と簡単なテストの実行が完了したら、このドキュメントを引き続き参照してください。 特に初心者にとって、これらは優れたガイドと参考資料です:
|
||||
Android自動化用のシステムの設定と簡単なテストの実行が完了したら、このドキュメントを引き続き参照してください。特に初心者にとって、これらは優れたガイドと参考資料です:
|
||||
|
||||
- [エコシステム](../ecosystem/index.md) ページ: 利用可能なドライバー、クライアント、プラグイン、ツールを見る
|
||||
- [Appium ドライバーとプラグインの管理](../guides/managing-exts.md)
|
||||
- [Capabilities](../guides/caps.md)
|
||||
- [Settings](../guides/settings.md)
|
||||
|
||||
また、[Appium Inspector](https://github.com/appium/appium-inspector) は、アプリの視覚的な検査を可能にし、テストスクリプトで使用する要素ロケーターを見つけるのに役立つ、Appium テストの作成に不可欠なツールです。
|
||||
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 コースもご活用いただけます。
|
||||
|
||||
|
||||
@@ -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.
|
||||
Tes code in `appium_lib` should be similar.
|
||||
Test 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://github.com/appium/appium-espresso-driver).
|
||||
(only if running macOS), and [Espresso](https://appium.github.io/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.ts)
|
||||
their origin (base Appium, driver-specific, or plugin-specific). Refer to [the type definition file](https://github.com/appium/appium/blob/master/packages/types/lib/command-maps.ts)
|
||||
for a detailed structure of this object.
|
||||
|
||||
### listExtensions
|
||||
@@ -104,9 +104,51 @@ Retrieves the [execute methods](../../guides/execute-methods.md) supported in th
|
||||
#### Response
|
||||
|
||||
`ListExtensionsResponse` - an object containing all supported execute methods, grouped by their
|
||||
origin (driver-specific or plugin-specific). Refer to [the type definition file](https://github.com/appium/appium/blob/master/packages/types/lib/command.ts)
|
||||
origin (driver-specific or plugin-specific). Refer to [the type definition file](https://github.com/appium/appium/blob/master/packages/types/lib/command-maps.ts)
|
||||
for a detailed structure of this object.
|
||||
|
||||
### getCurrentAppiumContext
|
||||
|
||||
```
|
||||
GET /session/:sessionId/appium/context
|
||||
```
|
||||
|
||||
Retrieves the active application context.
|
||||
|
||||
#### Response
|
||||
|
||||
`string` - the name of the active context
|
||||
|
||||
### setAppiumContext
|
||||
|
||||
```
|
||||
POST /session/:sessionId/appium/context
|
||||
```
|
||||
|
||||
Sets an application context as the active context.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Description | Type |
|
||||
| ------ | -------------------------------------------- | ------ |
|
||||
| `name` | Name of the context to set as the active one | string |
|
||||
|
||||
#### Response
|
||||
|
||||
`null`
|
||||
|
||||
### getAppiumContexts
|
||||
|
||||
```
|
||||
GET /session/:sessionId/appium/contexts
|
||||
```
|
||||
|
||||
Retrieves all available application contexts.
|
||||
|
||||
#### Response
|
||||
|
||||
`string[]` - the names of available contexts
|
||||
|
||||
### getLogEvents
|
||||
|
||||
```
|
||||
@@ -393,3 +435,71 @@ Retrieves data from a directory on the device under test.
|
||||
#### Response
|
||||
|
||||
`string` - the Base64-encoded zip file of the directory contents
|
||||
|
||||
### getAppiumRotation
|
||||
|
||||
```
|
||||
GET /session/:sessionId/appium/device/rotation
|
||||
```
|
||||
|
||||
Retrieves the current spatial orientation of the device under test.
|
||||
|
||||
#### Response
|
||||
|
||||
`Rotation` - an object with the following properties:
|
||||
|
||||
| Name | Description | Type |
|
||||
| ---- | ---------------------------------------------------- | ------ |
|
||||
| `x` | Degrees by which the device is rotated on its X axis | number |
|
||||
| `y` | Degrees by which the device is rotated on its Y axis | number |
|
||||
| `z` | Degrees by which the device is rotated on its Z axis | number |
|
||||
|
||||
### setAppiumRotation
|
||||
|
||||
```
|
||||
POST /session/:sessionId/appium/device/rotation
|
||||
```
|
||||
|
||||
Sets the spatial orientation of the device under test.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Description | Type |
|
||||
| ---- | ---------------------------------------------------- | ------ |
|
||||
| `x` | Degrees by which the device is rotated on its X axis | number |
|
||||
| `y` | Degrees by which the device is rotated on its Y axis | number |
|
||||
| `z` | Degrees by which the device is rotated on its Z axis | number |
|
||||
|
||||
#### Response
|
||||
|
||||
`null`
|
||||
|
||||
### getAppiumOrientation
|
||||
|
||||
```
|
||||
GET /session/:sessionId/appium/device/orientation
|
||||
```
|
||||
|
||||
Retrieves the current orientation of the device under test.
|
||||
|
||||
#### Response
|
||||
|
||||
`string` - either `PORTRAIT` or `LANDSCAPE`
|
||||
|
||||
### setAppiumOrientation
|
||||
|
||||
```
|
||||
POST /session/:sessionId/appium/device/orientation
|
||||
```
|
||||
|
||||
Sets the orientation of the device under test.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Description | Type |
|
||||
| ------------- | ------------------------------------------------------------------------------------------------------- | ------ |
|
||||
| `orientation` | New device orientation. Supported values are `PORTRAIT` or `LANDSCAPE`. | string |
|
||||
|
||||
#### Response
|
||||
|
||||
`null`
|
||||
|
||||
@@ -47,7 +47,7 @@ Subscribes to one or more BiDi events.
|
||||
|
||||
#### Response
|
||||
|
||||
`null`
|
||||
`{subscription: string}` — a unique subscription ID that can be passed to `session.unsubscribe`.
|
||||
|
||||
### bidiUnsubscribe
|
||||
|
||||
@@ -57,15 +57,20 @@ session.unsubscribe
|
||||
|
||||
> WebDriver BiDi documentation: [session.unsubscribe](https://w3c.github.io/webdriver-bidi/#command-session-unsubscribe)
|
||||
|
||||
Unsubscribes from one or more BiDi events.
|
||||
Unsubscribes using either previously returned subscription IDs or event names.
|
||||
Removing a subscription ID preserves any overlapping subscriptions.
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Description | Type | Default |
|
||||
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------ | ------- |
|
||||
| `contexts?` | Contexts in which to unsubscribe from the specified events. By default, the global scope is applied. | string[] | `['']` |
|
||||
| `events` | Names of events to unsubscribe from | string[] | |
|
||||
| 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.
|
||||
|
||||
#### Response
|
||||
|
||||
`null`
|
||||
`{}`
|
||||
|
||||
@@ -140,6 +140,10 @@ GET /session/:sessionId/orientation
|
||||
|
||||
Retrieves the current orientation of the device under test.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Please use [`getAppiumOrientation`](./appium.md#getappiumorientation) instead
|
||||
|
||||
#### Response
|
||||
|
||||
`string` - either `PORTRAIT` or `LANDSCAPE`
|
||||
@@ -154,6 +158,10 @@ POST /session/:sessionId/orientation
|
||||
|
||||
Sets the orientation of the device under test.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Please use [`setAppiumOrientation`](./appium.md#setappiumorientation) instead
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Description | Type |
|
||||
|
||||
@@ -21,6 +21,10 @@ GET /session/:sessionId/rotation
|
||||
|
||||
Retrieves the current spatial orientation of the device under test.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Please use [`getAppiumRotation`](./appium.md#getappiumrotation) instead
|
||||
|
||||
#### Response
|
||||
|
||||
`Rotation` - an object with the following properties:
|
||||
@@ -41,6 +45,10 @@ POST /session/:sessionId/rotation
|
||||
|
||||
Sets the spatial orientation of the device under test.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Please use [`setAppiumRotation`](./appium.md#setappiumrotation) instead
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Description | Type |
|
||||
@@ -63,6 +71,10 @@ GET /session/:sessionId/context
|
||||
|
||||
Retrieves the active application context.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Please use [`getCurrentAppiumContext`](./appium.md#getcurrentappiumcontext) instead
|
||||
|
||||
#### Response
|
||||
|
||||
`string` - the name of the active context
|
||||
@@ -77,6 +89,10 @@ POST /session/:sessionId/context
|
||||
|
||||
Sets an application context as the active context.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Please use [`setAppiumContext`](./appium.md#setappiumcontext) instead
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Description | Type |
|
||||
@@ -97,6 +113,10 @@ GET /session/:sessionId/contexts
|
||||
|
||||
Retrieves all available application contexts.
|
||||
|
||||
!!! warning "Deprecated"
|
||||
|
||||
Please use [`getAppiumContexts`](./appium.md#getappiumcontexts) instead
|
||||
|
||||
#### Response
|
||||
|
||||
`string[]` - the names of available contexts
|
||||
|
||||
@@ -170,10 +170,17 @@ Modifies the [`createSession`](./webdriver.md#createsession) endpoint:
|
||||
All endpoints for this plugin can be invoked without creating a session, allowing you to prepare
|
||||
your test environment in advance.
|
||||
|
||||
!!! info
|
||||
|
||||
Prior to plugin version 1.2.0, all endpoints below were mounted under the `/storage` prefix
|
||||
(e.g. `/storage/add`) instead of `/appium/storage`. The `/storage`-prefixed routes are still
|
||||
available for backward compatibility, but are deprecated and will be removed in a future
|
||||
version of the plugin.
|
||||
|
||||
### addStorageItem
|
||||
|
||||
```
|
||||
POST /storage/add
|
||||
POST /appium/storage/add
|
||||
```
|
||||
|
||||
Adds a new file to the storage.
|
||||
@@ -200,8 +207,8 @@ Example:
|
||||
```json
|
||||
{
|
||||
"ws": {
|
||||
"stream": "/storage/add/ccc963411b2621335657963322890305ebe96186/stream",
|
||||
"events": "/storage/add/ccc963411b2621335657963322890305ebe96186/events"
|
||||
"stream": "/appium/storage/add/ccc963411b2621335657963322890305ebe96186/stream",
|
||||
"events": "/appium/storage/add/ccc963411b2621335657963322890305ebe96186/events"
|
||||
},
|
||||
"ttlMs": 300000
|
||||
}
|
||||
@@ -210,7 +217,7 @@ Example:
|
||||
### deleteStorageItem
|
||||
|
||||
```
|
||||
POST /storage/delete
|
||||
POST /appium/storage/delete
|
||||
```
|
||||
|
||||
Deletes a file in the storage.
|
||||
@@ -229,7 +236,7 @@ the storage, or if the delete request is invalid.
|
||||
### listStorageItems
|
||||
|
||||
```
|
||||
GET /storage/list
|
||||
GET /appium/storage/list
|
||||
```
|
||||
|
||||
List all files present in the storage.
|
||||
@@ -247,7 +254,7 @@ List all files present in the storage.
|
||||
### resetStorage
|
||||
|
||||
```
|
||||
POST /storage/reset
|
||||
POST /appium/storage/reset
|
||||
```
|
||||
|
||||
Deletes all uploaded files and stops any incomplete uploads.
|
||||
|
||||
@@ -14,6 +14,12 @@ Provides management options for a specific extension (driver or plugin). Both th
|
||||
The following sub-subcommands are supported: `doctor`, `install`, `list`, `run`, `update`,
|
||||
and `uninstall`.
|
||||
|
||||
For `doctor`, `run`, `update`, and `uninstall`, you can identify an installed extension by its
|
||||
short name or its exact npm package name. For example, `appium driver uninstall uiautomator2`
|
||||
and `appium driver uninstall appium-uiautomator2-driver` refer to the same installed driver.
|
||||
Short names take precedence if a name also matches another extension's package name. Package names
|
||||
can include a scope, such as `@appium/fake-driver`, but must not include a version or tag suffix.
|
||||
|
||||
## `doctor`
|
||||
|
||||
Runs doctor checks for an installed extension, which validate whether the extension has its prerequisites
|
||||
@@ -30,9 +36,9 @@ configured correctly. Note that not all extensions include doctor checks.
|
||||
appium {driver|plugin} doctor <extension-name>
|
||||
```
|
||||
|
||||
| Argument | Description |
|
||||
| ---------------- | ----------------------------------------- |
|
||||
| `extension-name` | The short name of the installed extension |
|
||||
| Argument | Description |
|
||||
| ---------------- | ------------------------------------------------------------------- |
|
||||
| `extension-name` | The short name or exact npm package name of the installed extension |
|
||||
|
||||
#### Options
|
||||
|
||||
@@ -76,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 URL of the extension |
|
||||
| `github` | The GitHub repository slug of the extension, in the form `<org>/<repo>` |
|
||||
| `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) |
|
||||
|
||||
@@ -109,7 +115,7 @@ appium {driver|plugin} install <install-spec>
|
||||
- Install the XCUITest driver from GitHub:
|
||||
|
||||
```
|
||||
appium driver install https://github.com/appium/appium-xcuitest-driver --source=github --package=appium-xcuitest-driver
|
||||
appium driver install appium/appium-xcuitest-driver --source=github --package=appium-xcuitest-driver
|
||||
```
|
||||
|
||||
- Install the XCUITest driver using a Git URL:
|
||||
@@ -159,14 +165,14 @@ extensions include scripts.
|
||||
#### Usage
|
||||
|
||||
```
|
||||
appium {driver|plugin} run <extension-name> <script-name> [script-args]
|
||||
appium {driver|plugin} run <extension-name> [<script-name> [<script-args>]]
|
||||
```
|
||||
|
||||
| Argument | Description |
|
||||
| ---------------- | --------------------------------------------- |
|
||||
| `extension-name` | The short name of the installed extension |
|
||||
| `script-name` | The name of the script to be run |
|
||||
| `script-args` | Any additional arguments passed to the script |
|
||||
| Argument | Description |
|
||||
| ---------------- | ------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `extension-name` | The short name or exact npm package name of the installed extension |
|
||||
| `script-name` | The name of the script to run. If not provided, a list of available scripts is returned. |
|
||||
| `script-args` | Any additional arguments passed to the script |
|
||||
|
||||
#### Options
|
||||
|
||||
@@ -182,6 +188,12 @@ appium {driver|plugin} run <extension-name> <script-name> [script-args]
|
||||
appium driver run uiautomator2 reset
|
||||
```
|
||||
|
||||
- List all available scripts included in the XCUITest driver:
|
||||
|
||||
```
|
||||
appium driver run xcuitest
|
||||
```
|
||||
|
||||
## `update`
|
||||
|
||||
Updates one or more extensions. Only supported for extensions installed via `npm`. By default,
|
||||
@@ -193,9 +205,9 @@ Appium will only update minor and patch versions, in order to prevent any breaki
|
||||
appium {driver|plugin} update <extension-name>
|
||||
```
|
||||
|
||||
| Argument | Description |
|
||||
| ---------------- | -------------------------------------------------------------------------------------------- |
|
||||
| `extension-name` | The short name of the installed extension, or `installed` to update all installed extensions |
|
||||
| Argument | Description |
|
||||
| ---------------- | ---------------------------------------------------------------------------------------------------------------------- |
|
||||
| `extension-name` | The short name or exact npm package name of the installed extension, or `installed` to update all installed extensions |
|
||||
|
||||
#### Options
|
||||
|
||||
@@ -228,9 +240,9 @@ Removes an installed extension.
|
||||
appium {driver|plugin} uninstall <extension-name>
|
||||
```
|
||||
|
||||
| Argument | Description |
|
||||
| ---------------- | ----------------------------------------- |
|
||||
| `extension-name` | The short name of the installed extension |
|
||||
| Argument | Description |
|
||||
| ---------------- | ------------------------------------------------------------------- |
|
||||
| `extension-name` | The short name or exact npm package name of the installed extension |
|
||||
|
||||
#### Options
|
||||
|
||||
|
||||
@@ -26,12 +26,12 @@ appium
|
||||
|
||||
| <div style="width:15em">Argument</div> | Description | Type | <div style="width:7em">Default</div> |
|
||||
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -------------------------------------------------------- |
|
||||
| `--address`, `-a` | IPv4/IPv6 address to listen on | string | `0.0.0.0` |
|
||||
| `--address`, `-a` | IPv4/IPv6 address or a hostname to listen on | string | `0.0.0.0` |
|
||||
| `--allow-cors` | Allow web browser connections from any host | boolean | `false` |
|
||||
| `--allow-insecure` | List of [insecure features](../../guides/security.md) that should be allowed in this server's sessions. Individual features can be overridden by `--deny-insecure`. Has no effect in combination with `--relaxed-security`. | array<string> | `[]` |
|
||||
| `--allow-unknown-args` | Do not exit if unrecognized command-line arguments are passed to the server; ignore them instead. Useful when the Appium CLI is wrapped by external tooling that appends extra flags. | boolean | `false` |
|
||||
| `--base-path`, `-pa` | Base path to use as the prefix for all webdriver routes running on the server | string | `""` |
|
||||
| `--callback-address`, `-ca` | Callback IP address | string | `0.0.0.0` |
|
||||
| `--callback-address`, `-ca` | Callback IP address | string | same as `--address` |
|
||||
| `--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` |
|
||||
@@ -65,7 +65,7 @@ appium
|
||||
| `--tmp` | Absolute path to the directory used for temporary files | string | [`os.tmpdir()`](https://nodejs.org/api/os.html#ostmpdir) |
|
||||
| `--use-drivers` | List of drivers to activate. By default, all installed drivers are activated. | array<string> | `[]` |
|
||||
| `--use-plugins` | List of plugins to activate. By default, no plugins are activated. Set to `["all"]` to activate all installed plugins. | array<string> | `[]` |
|
||||
| `--webhook`, `-G` | URL for an HTTP listener where the server logs should be output. This does not affect output on the console. | string | |
|
||||
| `--webhook`, `-G` | URL for an HTTP listener where the server logs should be output. This does not affect output on the console. A bare `host:port` is also accepted, which posts the logs to the root path over plain http; a value having neither a scheme nor a port falls back to `127.0.0.1:9003`. | string | |
|
||||
|
||||
### Info Options
|
||||
|
||||
|
||||
@@ -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 the page source and its printing to the Appium log, whenever a request to find an element fails | `boolean` | |
|
||||
| `appium:printPageSourceOnFindFailure` | Toggle retrieval of the page source and its printing to the Appium log, whenever a request to find an element fails | `boolean` | |
|
||||
|
||||
### Validated Capabilities
|
||||
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
/* eslint-disable promise/prefer-await-to-callbacks */
|
||||
/* eslint-disable promise/prefer-await-to-then */
|
||||
|
||||
const {deploy, buildSite} = require('@appium/docutils');
|
||||
const {
|
||||
log,
|
||||
LANGS,
|
||||
@@ -35,6 +34,9 @@ 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);
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
/**
|
||||
* 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;
|
||||
@@ -17,3 +17,8 @@ authors:
|
||||
avatar: 'https://avatars.githubusercontent.com/u/4045041?v=4'
|
||||
slug: 'sai'
|
||||
url: 'https://saikrishna.tech'
|
||||
mykola:
|
||||
name: 'Mykola Mokhnach'
|
||||
description: 'Appium Core Maintainer'
|
||||
avatar: https://avatars.githubusercontent.com/u/7767781?v=4
|
||||
slug: 'mykola'
|
||||
|
||||
@@ -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 的更令人兴奋的细节。
|
||||
|
||||
加入我们来塑造移动设备测试自动化的未来。 立即提交您的提案,成为这一激动人心的活动的一部分!
|
||||
加入我们来塑造移动设备测试自动化的未来。立即提交您的提案,成为这一激动人心的活动的一部分!
|
||||
@@ -8,11 +8,13 @@ date: 2025-11-25
|
||||
# Announcing LambdaTest as Appium's Newest Development Partner
|
||||
|
||||
As part of our ongoing effort to recognize organizations that meaningfully support the Appium project through dedicated maintainer time, we are excited to welcome our newest Development Partner: LambdaTest!
|
||||
LambdaTest has long been an active participant in the automated testing ecosystem. Today, they are officially formalizing their commitment by investing people—dedicated engineers who will directly support Appium's development, maintenance, and ecosystem growth.
|
||||
This kind of hands-on contribution is crucial for ensuring Appium continues to evolve. We deeply value partners who empower their engineering teams to contribute code directly to open source rather than just sponsorship.
|
||||
|
||||
<!-- more -->
|
||||
|
||||
LambdaTest has long been an active participant in the automated testing ecosystem. Today, they are officially formalizing their commitment by investing people—dedicated engineers who will directly support Appium's development, maintenance, and ecosystem growth.
|
||||
|
||||
This kind of hands-on contribution is crucial for ensuring Appium continues to evolve. We deeply value partners who empower their engineering teams to contribute code directly to open source rather than just sponsorship.
|
||||
|
||||
<div style="text-align:center;width:100%"><a href="https://lambdatest.com/?utm_source=appium.io&utm_medium=organic&utm_campaign=june_25&utm_term=sk&utm_content=webpage">
|
||||
<img src="/docs/en/latest/assets/images/sponsor-logo-lambdatest-dark.png#only-dark" width="300" />
|
||||
<img src="/docs/en/latest/assets/images/sponsor-logo-lambdatest-light.png#only-light" width="300" />
|
||||
@@ -20,15 +22,19 @@ This kind of hands-on contribution is crucial for ensuring Appium continues to e
|
||||
</div>
|
||||
|
||||
LambdaTest engineers are already contributing actively across several key Appium repositories. Their current focus includes:
|
||||
**appium-mcp** – Supporting Appium's implementation of the Model Context Protocol (MCP) to drive forward modern AI-assisted capabilities.
|
||||
**appium-remote-xpc** – Contributing to the native macOS/XPC-based remote execution layer, essential for iOS automation.
|
||||
**appium-tun-tap** – Assisting in the development and maintenance of network virtualization and tunneling components for advanced testing scenarios.
|
||||
|
||||
- [`appium-mcp`](https://github.com/appium/appium-mcp) – Supporting Appium's implementation of the Model Context Protocol (MCP) to drive forward modern AI-assisted capabilities.
|
||||
- [`appium-ios-remotexpc`](https://github.com/appium/appium-ios-remotexpc) – Contributing to the native macOS/XPC-based remote execution layer, essential for iOS automation.
|
||||
- [`appium-ios-tuntap`](https://github.com/appium/appium-ios-tuntap) – Assisting in the development and maintenance of network virtualization and tunneling components for advanced testing scenarios.
|
||||
|
||||
These contributions strengthen critical infrastructure within the Appium ecosystem and demonstrate LambdaTest's commitment to deep technical involvement in the project's evolution.
|
||||
About LambdaTest
|
||||
|
||||
**About LambdaTest**
|
||||
|
||||
LambdaTest’s platform already serves a massive community of Appium users. As a GenAI-powered Quality Engineering Platform, they provide a full-stack testing cloud with 10,000+ real mobile devices and 3,000+ browsers.
|
||||
|
||||
Beyond standard infrastructure, they are pushing the boundaries of test execution with AI-native test management and next-generation agents like KaneAI. By supporting Appium alongside Selenium, Playwright, and other major frameworks, LambdaTest helps teams orchestrate intelligent automation at cloud scale.
|
||||
|
||||
LambdaTest will continue contributing people, code, and development expertise to strengthen Appium's core functionality. Their commitment represents a significant investment into the future of the framework, and we're thrilled to have them collaborating with us at this deeper level.
|
||||
|
||||
The Appium project is proud to recognize LambdaTest as our newest official Development Partner. We can't wait to see what we'll build together!
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user