Compare commits

..
Author SHA1 Message Date
github-actions 8018f8b70e chore: publish
- appium@3.5.0
 - @appium/base-driver@10.6.0
 - @appium/base-plugin@3.3.0
 - @appium/docutils@2.4.3
 - @appium/driver-test-support@1.2.3
 - @appium/eslint-config-appium-ts@3.2.2
 - @appium/execute-driver-plugin@6.0.4
 - @appium/fake-driver@6.2.0
 - @appium/fake-plugin@4.3.0
 - @appium/images-plugin@4.2.5
 - @appium/logger@2.0.8
 - @appium/opencv@4.1.5
 - @appium/plugin-test-support@1.2.3
 - @appium/relaxed-caps-plugin@2.2.3
 - @appium/schema@1.2.0
 - @appium/storage-plugin@1.1.5
 - @appium/support@7.2.3
 - @appium/test-support@4.1.5
 - @appium/types@1.5.0
 - @appium/universal-xml-plugin@2.1.4
2026-05-31 02:29:56 +00:00
renovate[bot] ea38864e95 chore(execute-driver-plugin): update dependency webdriverio to v9.27.2 (#22326)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-30 09:32:17 +00:00
Mykola Mokhnach cf79b3283a feat(base-driver): Ditch lodash (#22324) 2026-05-30 08:13:10 +02:00
Mykola Mokhnach 7c60cee787 chore(driver-test-support): Ditch lodash (#22323) 2026-05-30 08:12:55 +02:00
Mykola Mokhnach bfac5ab9ec chore(fake-driver,fake-plugin): Ditch lodash (#22322) 2026-05-29 18:58:32 +02:00
Mykola Mokhnach d329ecd7f7 chore(support): Deprecate more unused helpers (#22321) 2026-05-29 18:58:19 +02:00
Mykola Mokhnach aa85993c01 chore(support): Simplify plist parsing (#22320) 2026-05-29 18:58:09 +02:00
Mykola Mokhnach 3c34ec1a04 chore(support): Deprecate sharp-related primitives (#22318) 2026-05-29 09:40:29 +02:00
renovate[bot] 2cd71fc45d chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.60.0 (#22319)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-29 09:15:24 +02:00
Mykola Mokhnach bab02cc7c1 chore(docutils): Ditch lodash (#22317) 2026-05-29 09:13:46 +02:00
Mykola Mokhnach 66b38e31ab chore(execute-driver-plugin): Ditch lodash (#22316) 2026-05-28 09:40:30 +02:00
Mykola Mokhnach 66eeaa2791 chore(images-plugin): Ditch lodash (#22312) 2026-05-28 07:41:42 +02:00
Mykola Mokhnach a1fc1c0e18 chore(logger): Ditch lodash (#22313) 2026-05-28 07:40:29 +02:00
Mykola Mokhnach ccbe297d3a chore(relaxed-caps-plugin): Ditch lodash (#22311) 2026-05-27 20:37:25 +02:00
renovate[bot] 101b31f35d chore(storage-plugin): update dependency ws to v8.21.0 (#22310)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-27 08:30:57 +00:00
Mykola Mokhnach b01bed2d2e chore(opencv): Ditch lodash (#22309) 2026-05-27 10:02:35 +02:00
Mykola Mokhnach 6b9ad08246 chore(storage-plugin): Ditch lodash (#22308) 2026-05-27 10:02:26 +02:00
dependabot[bot] 2694d789c4 chore(deps-dev): bump tmp in the npm_and_yarn group across 1 directory (#22307)
Bumps the npm_and_yarn group with 1 update in the / directory: [tmp](https://github.com/raszi/node-tmp).


Updates `tmp` from 0.2.5 to 0.2.6
- [Changelog](https://github.com/raszi/node-tmp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/raszi/node-tmp/compare/v0.2.5...v0.2.6)

---
updated-dependencies:
- dependency-name: tmp
  dependency-version: 0.2.6
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-27 06:44:58 +02:00
Mykola Mokhnach 58fad654c3 chore(test-support): Ditch lodash (#22306) 2026-05-27 06:22:52 +02:00
Mykola Mokhnach 0d1271f812 chore(universal-xml-plugin): Ditch lodash (#22305) 2026-05-27 06:22:40 +02:00
renovate[bot] c79225f8cf chore(support): update dependency shell-quote to v1.8.4 (#22304)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-26 19:25:32 +02:00
renovate[bot] 2afd0e651c chore(deps): update dependency npm-run-all2 to v9.0.1 (#22303)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-26 16:04:28 +00:00
renovate[bot] 075466243d chore(support): update dependency yauzl to v3.3.1 (#22302)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-25 08:26:07 +00:00
Mykola Mokhnach abb83bde62 feat(appium): Ditch bluebird (#22301) 2026-05-25 08:13:07 +02:00
Mykola Mokhnach eb139abf97 chore(test-support): Remove unused bluebird dependency (#22300) 2026-05-25 08:12:54 +02:00
renovate[bot] 377011bdb3 chore(eslint-config-appium-ts): update dependency eslint-plugin-jsdoc to v63 (#22295)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-25 07:50:17 +02:00
renovate[bot] 1fc8582327 chore(support): update dependency semver to v7.8.1 (#22299)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-25 07:42:10 +02:00
renovate[bot] f6a96d6647 chore(deps): update dependency mocha to v11.7.6 (#22298)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-25 07:41:57 +02:00
renovate[bot] 04b408aace chore(storage-plugin): update dependency lru-cache to v11.5.0 (#22294)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-25 07:33:05 +02:00
renovate[bot] f600982578 chore(deps): update dependency npm-run-all2 to v9 (#22291)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-25 07:31:57 +02:00
dependabot[bot] c8b9321667 chore(deps): bump qs in the npm_and_yarn group across 1 directory (#22292)
Bumps the npm_and_yarn group with 1 update in the / directory: [qs](https://github.com/ljharb/qs).


Updates `qs` from 6.14.2 to 6.15.2
- [Changelog](https://github.com/ljharb/qs/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ljharb/qs/compare/v6.14.2...v6.15.2)

---
updated-dependencies:
- dependency-name: qs
  dependency-version: 6.15.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-25 07:31:06 +02:00
Mykola Mokhnach c9b7eac365 feat(base-driver): Ditch bluebird (#22293) 2026-05-23 08:28:06 +02:00
renovate[bot] efbf7115cc chore(eslint-config-appium-ts): update dependency eslint-plugin-mocha to v11.3.0 (#22290)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-22 16:10:15 +00:00
renovate[bot] 679ec8864c chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.59.4 (#22289)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-22 09:35:52 +00:00
renovate[bot] 094daa24be chore(storage-plugin): update dependency lru-cache to v11.4.0 (#22288)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-21 14:00:29 +00:00
renovate[bot] 9c3aaa1056 chore(deps): update dependency eslint to v10.4.0 (#22286)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-19 10:55:46 +00:00
github-actions[bot]andmykola-mokhnach e58253033d docs(appium): Update documentation translations (#22285)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2026-05-18 23:46:57 -07:00
Mykola Mokhnach 25d922b7d3 feat: make assignIpc internal (#22278) 2026-05-18 07:35:51 +02:00
Mykola Mokhnach 0264775ecb feat: Limit the maximum count of topics per session and make it configurable (#22279) 2026-05-18 07:22:48 +02:00
Mykola Mokhnach f5b193ccf0 chore(base-driver): Simplify async generator logic in IpcSubscription (#22280) 2026-05-18 07:22:32 +02:00
renovate[bot] 6d88f54918 chore(support): update dependency axios to v1.16.1 (#22283)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-17 13:25:41 +00:00
renovate[bot] 95c4091b8b chore(support): update dependency archiver to v8 (#22267) 2026-05-16 15:25:52 +02:00
renovate[bot] ecf927395d chore(storage-plugin): update dependency ws to v8.20.1 (#22281)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-16 09:44:23 +00:00
renovate[bot] e1e228380f chore(universal-xml-plugin): update dependency fast-xml-parser to v5.8.0 (#22277)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-15 15:31:01 +00:00
renovate[bot] 74170ec575 chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.59.3 (#22275)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-15 12:43:00 +00:00
renovate[bot] 3f9a2ea18f chore(docutils): update dependency yaml to v2.9.0 (#22276)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-15 09:39:13 +00:00
renovate[bot] 2ef20b988b chore(deps): update dependency @types/node to v24.12.4 (#22274)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-15 07:51:31 +00:00
github-actions[bot]andmykola-mokhnach 1dffc4e833 docs(appium): Update documentation translations (#22273)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2026-05-14 22:45:04 -07:00
Jonathan Lipps 97c879cdd0 feat: add IPC channels per session for drivers and plugins to communicate (#22211)
* feat: add IPC channels per session for drivers and plugins to communicate (fix #22206)

* lint

* export AppiumIpc

* fix test issues

* import AppiumIpc directly from basedriver

* fakedriver is used directly outside of appium so can't rely on existence of IPC

* make ipc functions async with lock and better types

* fix assignIpc types

* deduplicate session object deletion

* ipcGuard -> withIpc

* address various review comments

* lint

* address copilot and other review comments

* store only last message. change model to use subscription object and async generator

* enforce max message size in bytes

* fix tests and call the message payload 'data' for clarity

* lint

* make assignIpc optional on drivers for backwards compatibility

* add error handling in startClock since it is usually not awaited

* add docs

* remove todo comment

* apply copilot and eglitise suggestions

* add typedoc

* add error handling to onIpcInit

* apply more suggestions

* fix schema unit test

* apply more suggestions

* add links to ipc examples

* make minimum ipc message size 1 instead of 0

* ensure publisher names are friendly to consumers

* fix ipc message time unit

* use already included sizeof for objs

* just pass error obj to log

* be more typescriptey about our ipc guard

* make max obj size part of opts for appiumipc

* let unsubscribe return whether it worked

* improve ipc types and shapes

* apply master package-lock.json

* update schema config

* use javascript naming conventions

* clarify distinction between message and payload (data)

* ensure async iterator loop ends when unsubscribe is called

* ensure the right things happen when you unsubscribe

* make require ipc more ergonomic

* remove unnecessary async locks and de-asyncify methods

* simplify interface and just use subscriber/plugin names

* fix docs

* fix lint

* document isActive

* add note about topic namespace

* use sleep instead of delay

* restrict the ipc payload data type to something that can be cloned

* clarify topic namespacing recommendation

* make sure listeners and promises are cleaned up in async iterator

* clean up ipc internal names

* readonly

* address review comments

* make ipcmessage readonly

* readonly cause why not
2026-05-14 16:56:02 -07:00
renovate[bot] 8300e115b2 chore(docutils): update dependency mkdocs-git-revision-date-localized-plugin to v1.5.2 (#22270)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-13 13:38:48 +00:00
renovate[bot] ea186eae17 chore(support): update dependency semver to v7.8.0 (#22266)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-12 14:46:17 +00:00
renovate[bot] 07466e02f7 chore(support): update dependency asyncbox to v6.3.0 (#22265)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-12 11:34:37 +00:00
renovate[bot] a91f4a718b chore(deps): update dependency @types/node to v24.12.3 (#22263)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-11 19:15:58 +02:00
renovate[bot] f53e443d64 chore(eslint-config-appium-ts): update dependency @eslint/compat to v2.1.0 (#22264)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-11 15:37:16 +00:00
renovate[bot] fc11de2bda chore(test-support): update dependency sinon to v22 (#22262)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-10 20:35:59 +02:00
renovate[bot] 82343effc4 chore(eslint-config-appium-ts): update dependency eslint-plugin-n to v18 (#22261)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-10 20:35:28 +02:00
renovate[bot] 59a460949a chore(universal-xml-plugin): update dependency fast-xml-parser to v5.7.3 (#22260)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-10 10:19:43 +02:00
renovate[bot] b4dd22512c chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.59.2 (#22258)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-10 08:48:04 +02:00
renovate[bot] a18700fed6 chore(storage-plugin): update dependency lru-cache to v11.3.6 (#22259)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-10 08:47:54 +02:00
dependabot[bot] 2f312722d7 chore(deps): bump the npm_and_yarn group across 1 directory with 2 updates (#22257)
Bumps the npm_and_yarn group with 2 updates in the / directory: [fast-uri](https://github.com/fastify/fast-uri) and [fast-xml-builder](https://github.com/NaturalIntelligence/fast-xml-builder).


Updates `fast-uri` from 3.0.1 to 3.1.2
- [Release notes](https://github.com/fastify/fast-uri/releases)
- [Commits](https://github.com/fastify/fast-uri/compare/v3.0.1...v3.1.2)

Updates `fast-xml-builder` from 1.1.5 to 1.2.0
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-builder/blob/main/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-builder/compare/v1.1.5...v1.2.0)

---
updated-dependencies:
- dependency-name: fast-uri
  dependency-version: 3.1.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: fast-xml-builder
  dependency-version: 1.2.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-08 22:43:31 +03:00
github-actions f5369c65a8 chore: publish
- appium@3.4.2
 - @appium/base-driver@10.5.2
 - @appium/base-plugin@3.2.4
 - @appium/docutils@2.4.2
 - @appium/fake-plugin@4.2.4
 - @appium/images-plugin@4.2.4
 - @appium/storage-plugin@1.1.4
 - @appium/support@7.2.2
 - @appium/test-support@4.1.4
2026-05-07 18:32:52 +00:00
Mykola Mokhnach 8c6c19982e fix(support): accept Uint8Array/ArrayBuffer in plist parse path (#22256) 2026-05-07 20:26:25 +02:00
Mykola Mokhnach e39017feac ci: Restore publish fallback script (#22255) 2026-05-07 20:25:25 +02:00
github-actions fd6dbe9eff chore: publish
- appium@3.4.1
 - @appium/base-driver@10.5.1
 - @appium/base-plugin@3.2.3
 - @appium/docutils@2.4.1
 - @appium/eslint-config-appium-ts@3.2.1
 - @appium/fake-plugin@4.2.3
 - @appium/images-plugin@4.2.3
 - @appium/storage-plugin@1.1.3
 - @appium/support@7.2.1
 - @appium/test-support@4.1.3
2026-05-06 20:38:58 +00:00
dependabot[bot] c18b535d42 chore(deps): bump basic-ftp in the npm_and_yarn group across 1 directory (#22253)
Bumps the npm_and_yarn group with 1 update in the / directory: [basic-ftp](https://github.com/patrickjuchli/basic-ftp).


Updates `basic-ftp` from 5.3.0 to 5.3.1
- [Release notes](https://github.com/patrickjuchli/basic-ftp/releases)
- [Changelog](https://github.com/patrickjuchli/basic-ftp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/patrickjuchli/basic-ftp/compare/v5.3.0...v5.3.1)

---
updated-dependencies:
- dependency-name: basic-ftp
  dependency-version: 5.3.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-06 23:24:12 +03:00
Edgars Eglītis 9045dfcefa ci: tune release workflows (#22252)
* ci: tune release workflows

* revert splitting workflows
2026-05-06 23:16:35 +03:00
Edgars Eglītis 98a1735913 fix(eslint-config-appium-ts): set new ESLint 10 rules to 'warn' (#22251) 2026-05-06 22:36:19 +03:00
Mykola Mokhnach 3229e74d3d fix(support): Avoid exceptions in unwrapElement (#22250) 2026-05-06 21:28:12 +02:00
github-actions 9c35776756 chore: publish
- appium@3.4.0
 - @appium/base-driver@10.5.0
 - @appium/base-plugin@3.2.2
 - @appium/docutils@2.4.0
 - @appium/driver-test-support@1.2.2
 - @appium/eslint-config-appium-ts@3.2.0
 - @appium/execute-driver-plugin@6.0.3
 - @appium/fake-driver@6.1.3
 - @appium/fake-plugin@4.2.2
 - @appium/images-plugin@4.2.2
 - @appium/opencv@4.1.4
 - @appium/plugin-test-support@1.2.2
 - @appium/relaxed-caps-plugin@2.2.2
 - @appium/schema@1.1.1
 - @appium/storage-plugin@1.1.2
 - @appium/support@7.2.0
 - @appium/test-support@4.1.2
 - @appium/types@1.4.0
 - @appium/universal-xml-plugin@2.1.3
2026-05-06 19:01:52 +00:00
Mykola Mokhnach 1b31db3be9 ci: Add a workflow for executing lerna version (#22249) 2026-05-06 20:59:36 +02:00
renovate[bot] 0a4b4f5a55 chore(support): update dependency glob to v13.0.6 (#22244)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-06 17:42:13 +02:00
Mykola Mokhnach a085d44616 ci: Apply scoped release recovery (#22248) 2026-05-06 17:41:59 +02:00
Mykola Mokhnach a10f558382 ci: tune recovery logic (#22247) 2026-05-06 17:19:23 +02:00
Mykola Mokhnach f61e7d57fa ci: Release recovery script (#22246) 2026-05-06 17:09:23 +02:00
renovate[bot] 705710adc5 chore(support): update dependency axios to v1.16.0 (#22240)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-06 14:50:17 +00:00
renovate[bot] 6a3d659c5a chore(support): update dependency teen_process to v4.1.3 (#22241)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-06 13:46:54 +00:00
dependabot[bot] c760f02e14 chore(deps): bump ip-address (#22243)
Bumps the npm_and_yarn group with 1 update in the / directory: [ip-address](https://github.com/beaugunderson/ip-address).


Updates `ip-address` from 9.0.5 to 10.2.0
- [Commits](https://github.com/beaugunderson/ip-address/commits)

---
updated-dependencies:
- dependency-name: ip-address
  dependency-version: 10.2.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-06 12:27:52 +03:00
renovate[bot] e1ab96fc4e chore(docutils): update dependency yaml to v2.8.4 (#22239)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-06 08:47:02 +00:00
github-actions[bot]andmykola-mokhnach e8d31c63c4 docs(appium): Update documentation translations (#22238)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2026-05-06 09:20:11 +03:00
Edgars Eglītis 787571d338 feat: add 3 WebDriver extension endpoints (#22237)
* feat: add 2 WebDriver extension endpoints

* docs: add missing reference for removeAuthCredential

* fix protocol hash
2026-05-05 20:30:59 +03:00
Edgars Eglītis 4849ad015d feat(eslint-config-appium-ts): support ESLint 10 (#22236) 2026-05-05 11:15:02 +03:00
renovate[bot] 0878f3c8ce chore(workflows): update fuxingloh/multi-labeler action to v5 (#22235)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-05 09:05:43 +03:00
renovate[bot] 3dd0ac715a chore(support): update dependency asyncbox to v6.2.0 (#22233)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-04 20:27:40 +00:00
Edgars Eglītis ce09eb2e7d chore: fix new linting errors in ESLint 10 (#22230)
* fix no-useless-assignment errors

* fix preserve-caught-error errors

* address comments

* address comments
2026-05-04 20:44:23 +03:00
renovate[bot] 9cc0377acf chore(execute-driver-plugin): update dependency webdriverio to v9.27.1 (#22232)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-04 15:15:08 +00:00
renovate[bot] 9b21b92418 chore(workflows): update slackapi/slack-github-action action to v3.0.3 (#22229)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-02 13:35:08 +00:00
renovate[bot] c758fcaf13 chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.59.1 (#22228)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-02 09:06:07 +00:00
Mykola Mokhnach 63218cdac6 feat(support): Replace lodash with native alternatives (#22225) 2026-05-01 23:17:40 +02:00
Edgars Eglītis 08493df3d1 feat(docutils): add mermaid diagram support (#22227) 2026-05-01 19:47:22 +03:00
Mykola Mokhnach bde5bd57f4 feat(eslint-config-appium-ts): Add rule to warn if a type is not imported properly (#22226) 2026-05-01 17:47:26 +02:00
renovate[bot] b5bdfdd4e4 chore(eslint-config-appium-ts): update dependency eslint-plugin-promise to v7.3.0 (#22222)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-30 14:43:29 +00:00
Edgars Eglītis cb4aa687a2 chore(deps): update plist to v4 (#22224) 2026-04-30 13:52:34 +03:00
renovate[bot] 180f2611c1 chore(support): update dependency plist to v3.1.1 (#22221)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-30 10:06:28 +00:00
Mykola Mokhnach 1f3119ec1f chore(support): Deprecate v1, v3 and v5 uuid generators (#22218) 2026-04-30 07:16:26 +02:00
Mykola Mokhnach 2c0fb7a2e4 feat(support): Add various helper utils (#22213) 2026-04-29 20:29:19 +02:00
Sai Asish Y fa1e87535b feat(base-driver): map W3C 'no such shadow root' to NoSuchShadowRootError (#22210)
Appium's base-driver had no dedicated ProtocolError subclass for
the W3C WebDriver 'no such shadow root' error. Every such response
from an underlying browser (the GetShadowRoot command against an
element whose shadow DOM is absent) fell through the
w3cErrorCodeMap lookup to UnknownError, making client-side error
handling (Selenium's NoSuchShadowRootException in particular)
unreachable.

Add NoSuchShadowRootError with error='no such shadow root' /
w3cStatus=404 / code=65, register it in the errors map so
errorFromW3CJsonCode returns it, and extend the existing
errors.spec table-tests to lock the new mapping.

Fixes #22209

Signed-off-by: SAY-5 <say.apm35@gmail.com>
2026-04-29 19:19:50 +02:00
renovate[bot] 79370cd307 chore(appium): update dependency ajv to v8.20.0 (#22216)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-28 20:05:03 +02:00
renovate[bot] 712832ae61 chore(support): update dependency axios to v1.15.2 (#22205)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-28 17:00:15 +00:00
renovate[bot] 6c9f7bbf6a chore(universal-xml-plugin): update dependency fast-xml-parser to v5.7.2 (#22215)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-28 11:44:36 +00:00
renovate[bot] 0f0f60effd chore(support): update dependency teen_process to v4.1.2 (#22212)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-25 13:43:11 +02:00
renovate[bot] be35e0b3d1 chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.59.0 (#22208)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-24 15:14:49 +00:00
github-actions 17f84265d1 chore: publish
- appium@3.3.1
 - @appium/base-driver@10.4.0
 - @appium/base-plugin@3.2.1
 - @appium/docutils@2.3.1
 - @appium/driver-test-support@1.2.1
 - @appium/eslint-config-appium-ts@3.1.0
 - @appium/execute-driver-plugin@6.0.2
 - @appium/fake-driver@6.1.2
 - @appium/fake-plugin@4.2.1
 - @appium/images-plugin@4.2.1
 - @appium/logger@2.0.7
 - @appium/opencv@4.1.3
 - @appium/plugin-test-support@1.2.1
 - @appium/relaxed-caps-plugin@2.2.1
 - @appium/storage-plugin@1.1.1
 - @appium/strongbox@1.1.1
 - @appium/support@7.1.1
 - @appium/test-support@4.1.1
 - @appium/types@1.3.1
 - @appium/universal-xml-plugin@2.1.2
2026-04-23 21:25:07 +00:00
renovate[bot] 7da5477e7a chore(workflows): update slackapi/slack-github-action action to v3.0.2 (#22207)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-23 15:06:39 +00:00
renovate[bot] 49f0dc7ab1 chore(support): update dependency uuid to v14 [security] (#22204)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-23 08:56:35 +03:00
Mykola Mokhnach 622f1999d7 fix(appium): plugins caching per session (#22203) 2026-04-22 23:09:58 +02:00
renovate[bot] 52b96394d6 chore(workflows): pin bahmutov/npm-install action to v1.12.1 (#22201)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-22 12:05:13 +03:00
renovate[bot] abba69f23a chore(universal-xml-plugin): update dependency @xmldom/xmldom to v0.9.10 (#22202)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-22 10:33:13 +03:00
Kazuaki Matsuo 83bfbce9cc docs: update governance.md (#22199)
* docs: update governance.md

* Update GOVERNANCE.md

* Update committers list in GOVERNANCE.md

* Update ownership details for Delta456 and navin772
2026-04-21 23:10:20 -07:00
Mykola Mokhnach 9670d93a12 fix(execute-driver-plugin): Protect VM-accessible instances from prototype pollution (#22195) 2026-04-21 23:23:28 +02:00
renovate[bot] c986fbe5ac chore(universal-xml-plugin): update dependency fast-xml-parser to v5.7.1 (#22181)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 22:12:18 +03:00
renovate[bot] 1c8735dfbe chore(eslint-config-appium-ts): update dependency eslint-plugin-perfectionist to v5.9.0 (#22200)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 16:44:17 +00:00
renovate[bot] 6d76b1ded6 chore(types): update dependency type-fest to v5.6.0 (#22198)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 09:39:32 +00:00
renovate[bot] 9c1c5ba06e chore(deps): update dependency typescript to v6.0.3 (#22196)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-20 14:34:31 +00:00
renovate[bot] bbb70d3c1e chore(workflows): update rinchsan/renovate-config-validator action to v0.2.1 (#22197)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-20 15:55:53 +03:00
Mykola Mokhnach 6476197bff fix(eslint-config-appium-ts): Suppress lint warnings (#22190) 2026-04-18 20:26:30 +02:00
Mykola Mokhnach 4c4e8d8911 feat(base-driver): Show known capability name matches for typos (#22193) 2026-04-18 19:17:00 +02:00
renovate[bot] c65e6d26f1 chore(workflows): update msimerson/node-lts-versions action to v2 (#22194)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-18 11:24:17 +02:00
renovate[bot] 97af269d68 chore(deps): update dependency prettier to v3.8.3 (#22191)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-18 10:01:53 +02:00
renovate[bot] a31b82cc7b chore(appium): update dependency @sidvind/better-ajv-errors to v5 (#22192)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-18 10:01:35 +02:00
Mykola Mokhnach efe167f59a fix: All the rest of linter warnings (#22183) 2026-04-17 19:24:57 +02:00
renovate[bot] 3efaac1e9a chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.58.2 (#22187)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-17 14:07:51 +00:00
renovate[bot] 3d3abbdc6f chore(docutils): update dependency diff to v9 (#22188)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-17 11:30:22 +03:00
Edgars Eglītis 862fbbb438 chore: bump basic-ftp to 5.3.0 (#22186) 2026-04-17 08:54:45 +03:00
Mykola Mokhnach 5484e9a4ff fix(logger): linter errors (#22182) 2026-04-16 20:05:28 +02:00
Mykola Mokhnach 943866bcf3 fix(base-driver): lint warnings (#22174) 2026-04-16 18:15:34 +02:00
Mykola Mokhnach 62c7132476 fix(fake-driver): linter warnings (#22177) 2026-04-16 18:13:52 +02:00
renovate[bot] dbcf4a133c chore(storage-plugin): update dependency lru-cache to v11.3.5 (#22180)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-16 11:17:27 +00:00
Mykola Mokhnach 4da7da0a14 fix(support): lint warnings (#22175) 2026-04-15 08:38:32 +02:00
Mykola Mokhnach 8e68b3e2c9 fix(appium): lint warnings (#22171) 2026-04-15 07:15:45 +02:00
renovate[bot] 2e465ef433 chore(test-support): update dependency sinon to v21.1.2 (#22166)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-15 04:57:00 +00:00
github-actions[bot]andmykola-mokhnach 021aed1fdf docs(appium): Update documentation translations (#22173)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2026-04-14 20:43:00 -07:00
Mykola Mokhnach a929cd6024 feat(eslint-config-appium-ts): Add new rules (#22164) 2026-04-14 20:54:40 +02:00
Mykola Mokhnach 6e0fdfd967 refactor(appium): reorganize bootstrap entities into a separate subfolder (#22165) 2026-04-14 20:54:18 +02:00
Edgars Eglītis 18138f939d chore(deps): bump follow-redirects to v1.16.0 (#22169) 2026-04-14 15:21:39 +03:00
renovate[bot] e43b9052d0 chore(docutils): update dependency mike to v2.2.0 (#22167)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-14 09:00:25 +00:00
Mykola Mokhnach 1a5d266c04 chore(appium): Migrate logger.js to typescript (#22163) 2026-04-13 20:29:28 +02:00
Mykola Mokhnach 97d26a5796 chore(appium): Migrate main.js to typescript (#22159) 2026-04-13 18:07:11 +02:00
renovate[bot] 20d410e108 chore(test-support): update dependency sinon to v21.1.0 (#22161)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-13 13:00:02 +00:00
renovate[bot] ad562353d9 chore(deps): update dependency prettier to v3.8.2 (#22160)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-13 10:05:35 +00:00
Mykola Mokhnach 96152aef42 chore(appium): Migrate umbrella driver to typescript (#22156) 2026-04-12 20:03:50 +02:00
renovate[bot] 71ca18c565 chore(universal-xml-plugin): update dependency fast-xml-parser to v5.5.11 (#22158)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-12 13:51:05 +00:00
renovate[bot] 4d45af1ef2 chore(eslint-config-appium-ts): update dependency @eslint/compat to v2.0.5 (#22157)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-11 13:13:38 +02:00
renovate[bot] 73a9891c24 chore(support): update dependency glob to v13.0.6 (#22155)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-11 13:13:26 +02:00
Mykola Mokhnach dfe8bde687 fix(base-driver): Make proxy timeout mutable again (#22154) 2026-04-11 09:30:37 +02:00
dependabot[bot] 9b0a5a4096 chore(deps): bump basic-ftp in the npm_and_yarn group across 1 directory (#22150)
Bumps the npm_and_yarn group with 1 update in the / directory: [basic-ftp](https://github.com/patrickjuchli/basic-ftp).


Updates `basic-ftp` from 5.2.1 to 5.2.2
- [Release notes](https://github.com/patrickjuchli/basic-ftp/releases)
- [Changelog](https://github.com/patrickjuchli/basic-ftp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/patrickjuchli/basic-ftp/compare/v5.2.1...v5.2.2)

---
updated-dependencies:
- dependency-name: basic-ftp
  dependency-version: 5.2.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-11 09:24:22 +02:00
renovate[bot] 73abe981de chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.58.1 (#22151)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-11 09:24:13 +02:00
renovate[bot] e34c0dd639 chore(support): update dependency teen_process to v4.1.1 (#22152)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-11 09:24:03 +02:00
renovate[bot] c8f0ed5deb chore(workflows): update peter-evans/create-pull-request action to v8.1.1 (#22153)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-11 09:23:51 +02:00
Mykola Mokhnach 62fb60a8b5 chore(appium): Migrate extension stuff to typescript (#22149) 2026-04-11 09:00:29 +02:00
renovate[bot] 4e9bf1944b chore(deps): update dependency typescript to v6 (#22104) 2026-04-10 10:42:49 +02:00
github-actions 7a8965f5c3 chore: publish
- appium@3.3.0
 - @appium/base-driver@10.3.0
 - @appium/base-plugin@3.2.0
 - @appium/docutils@2.3.0
 - @appium/driver-test-support@1.2.0
 - @appium/eslint-config-appium-ts@3.0.2
 - @appium/execute-driver-plugin@6.0.1
 - @appium/fake-driver@6.1.1
 - @appium/fake-plugin@4.2.0
 - @appium/images-plugin@4.2.0
 - @appium/logger@2.0.6
 - @appium/opencv@4.1.2
 - @appium/plugin-test-support@1.2.0
 - @appium/relaxed-caps-plugin@2.2.0
 - @appium/storage-plugin@1.1.0
 - @appium/strongbox@1.1.0
 - @appium/support@7.1.0
 - @appium/test-support@4.1.0
 - @appium/types@1.3.0
 - @appium/universal-xml-plugin@2.1.1
2026-04-09 18:57:40 +00:00
renovate[bot] daa99525eb chore(storage-plugin): update dependency lru-cache to v11.3.3 (#22148)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-09 21:36:41 +03:00
renovate[bot] 6234359ff2 chore(support): update dependency glob to v13.0.6 (#22142)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-09 21:36:30 +03:00
renovate[bot] 24d8344927 chore(support): update dependency axios to v1.15.0 (#22145)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-09 21:26:19 +03:00
renovate[bot] e00cd5e7eb chore(storage-plugin): update dependency lru-cache to v11.3.1 (#22144)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-09 21:23:46 +03:00
renovate[bot] 27d3c517d7 chore(storage-plugin): update dependency lru-cache to v11.3.0 (#22143)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-09 09:24:44 +00:00
dependabot[bot] 76e060cf75 chore(deps): bump basic-ftp in the npm_and_yarn group across 1 directory (#22141)
Bumps the npm_and_yarn group with 1 update in the / directory: [basic-ftp](https://github.com/patrickjuchli/basic-ftp).


Updates `basic-ftp` from 5.2.0 to 5.2.1
- [Release notes](https://github.com/patrickjuchli/basic-ftp/releases)
- [Changelog](https://github.com/patrickjuchli/basic-ftp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/patrickjuchli/basic-ftp/compare/v5.2.0...v5.2.1)

---
updated-dependencies:
- dependency-name: basic-ftp
  dependency-version: 5.2.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-09 00:34:48 +03:00
renovate[bot] 3b8c41e3d4 chore(eslint-config-appium-ts): update dependency @eslint/compat to v2.0.4 (#22140)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-07 09:16:27 +02:00
renovate[bot] 0e5db551b4 chore(deps): update definitelytyped (#22137)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-06 17:40:25 +00:00
renovate[bot] e79c521fa7 chore(universal-xml-plugin): update dependency fast-xml-parser to v5.5.10 (#22138)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-06 13:54:55 +00:00
renovate[bot] 1c4ce5d5ec chore(strongbox): update dependency slugify to v1.6.9 (#22136)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-05 16:34:53 +00:00
renovate[bot] a36736862f chore(base-driver): update dependency path-to-regexp to v8.4.2 (#22135)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-05 12:58:24 +00:00
renovate[bot] 22b60daf75 chore(support): update dependency yauzl to v3.3.0 (#22133)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-04 08:48:44 +00:00
renovate[bot] 7153d0adf8 chore(base-driver): update dependency path-to-regexp to v8.4.1 (#22126)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-03 05:13:13 +00:00
renovate[bot] ad13932e6e chore(universal-xml-plugin): update dependency lodash to v4.18.1 [security] (#22131)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-03 01:35:57 +00:00
renovate[bot] f044afd932 chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.58.0 (#22127)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-02 21:14:56 +00:00
Edgars Eglītis ac46d8ef5c chore: run npm audit fix (#22129) 2026-04-01 14:57:16 +03:00
Edgars Eglītis dc37b2766d fix: adjust Renovate config (#22128) 2026-04-01 10:17:38 +03:00
Edgars Eglītis fe8b8eb808 chore: update Renovate config (#22125)
* chore: update Renovate config

* update config
2026-03-31 21:30:27 +03:00
renovate[bot] aca8f72ee5 chore(universal-xml-plugin): update dependency @xmldom/xmldom to v0.9.9 (#22122)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-30 14:46:34 +03:00
dependabot[bot] f135acadd4 chore(deps-dev): bump brace-expansion (#22120)
Bumps the npm_and_yarn group with 1 update in the / directory: [brace-expansion](https://github.com/juliangruber/brace-expansion).


Updates `brace-expansion` from 1.1.12 to 1.1.13
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v1.1.12...v1.1.13)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 1.1.13
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-29 19:53:59 +03:00
Edgars Eglītis 4539f868fc chore: run npm audit fix (#22119) 2026-03-29 19:47:30 +03:00
Edgars Eglītis 5cd7076fd6 fix(docutils): do not silence errors when building without serve (#22118)
* fix(docutils): do not silence original errors when building without serve

* address comments
2026-03-29 19:33:41 +03:00
renovate[bot] 96254ef3b8 chore(docutils): update dependency mkdocs-redirects to v1.2.3 (#22116)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-29 09:17:15 +00:00
Mykola Mokhnach ed9d4aed09 chore(appium): Migrate cli foundation to typescript (#22110) 2026-03-29 09:16:00 +02:00
renovate[bot] a03b28a12c chore(eslint-config-appium-ts): update dependency eslint-plugin-unicorn to v64 (#22114)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-28 14:58:49 +02:00
renovate[bot] b649c64df5 chore(support): update dependency axios to v1.14.0 (#22113)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-28 09:39:44 +00:00
github-actions[bot]andmykola-mokhnach 22eed52c60 docs(appium): Update documentation translations (#22112)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2026-03-27 23:12:32 -07:00
Edgars Eglītis 5e2006ae23 docs: add AppClaw to Ecosystem tools document (#22111)
* docs: add AppClaw to Ecosystem tools document

* remove extra line
2026-03-27 15:45:24 +02:00
dependabot[bot] c45839f057 chore(deps-dev): bump handlebars (#22108)
Bumps the npm_and_yarn group with 1 update in the / directory: [handlebars](https://github.com/handlebars-lang/handlebars.js).


Updates `handlebars` from 4.7.8 to 4.7.9
- [Release notes](https://github.com/handlebars-lang/handlebars.js/releases)
- [Changelog](https://github.com/handlebars-lang/handlebars.js/blob/v4.7.9/release-notes.md)
- [Commits](https://github.com/handlebars-lang/handlebars.js/compare/v4.7.8...v4.7.9)

---
updated-dependencies:
- dependency-name: handlebars
  dependency-version: 4.7.9
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-27 10:42:34 +02:00
renovate[bot] b31574d0ed chore(base-driver): update dependency path-to-regexp to v8.4.0 (#22109)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-27 08:29:01 +00:00
Mykola Mokhnach c2b7070c53 chore(appium): Migrate the entire schema from JavaScript to TypeScript (#22107) 2026-03-27 08:19:05 +01:00
dependabot[bot] e907832667 chore(deps): bump the npm_and_yarn group across 1 directory with 1 update (#22106)
Bumps the npm_and_yarn group with 1 update in the / directory: [picomatch](https://github.com/micromatch/picomatch).


Updates `picomatch` from 4.0.3 to 4.0.4
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/4.0.3...4.0.4)

Updates `picomatch` from 2.3.1 to 2.3.2
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/4.0.3...4.0.4)

Updates `picomatch` from 4.0.2 to 4.0.4
- [Release notes](https://github.com/micromatch/picomatch/releases)
- [Changelog](https://github.com/micromatch/picomatch/blob/master/CHANGELOG.md)
- [Commits](https://github.com/micromatch/picomatch/compare/4.0.3...4.0.4)

---
updated-dependencies:
- dependency-name: picomatch
  dependency-version: 4.0.4
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: picomatch
  dependency-version: 2.3.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: picomatch
  dependency-version: 4.0.4
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-26 09:47:53 +02:00
Mykola Mokhnach 6e104d4ba1 chore(appium): Migrate doctor.js to typescript (#22105) 2026-03-25 20:34:28 +01:00
renovate[bot] 41f2304e16 chore(universal-xml-plugin): update dependency fast-xml-parser to v5.5.9 (#22102)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-24 21:45:51 +00:00
renovate[bot] 4ec08dbbf9 chore(execute-driver-plugin): update dependency webdriverio to v9.27.0 (#22103)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-24 17:21:19 +00:00
renovate[bot] a842430634 chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.57.2 (#22101)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-24 13:03:09 +00:00
renovate[bot] 4d3a5dc74a chore(docutils): update dependency diff to v8.0.4 (#22100)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-24 10:15:37 +00:00
Mykola Mokhnach e6fc983d9d chore(appium): Migrate config-related stuff to typescript (#22099) 2026-03-23 20:13:02 +01:00
renovate[bot] a2be0836da chore(storage-plugin): update dependency ws to v8.20.0 (#22098)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-23 16:36:01 +00:00
renovate[bot] 46f2160bf1 chore(plugin-test-support): update dependency get-port to v7.2.0 (#22097)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-23 12:36:41 +00:00
renovate[bot] 00e3d864f0 chore(docutils): update dependency yaml to v2.8.3 (#22096)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-23 09:15:43 +00:00
Mykola Mokhnach caee6b733b chore(appium): Migrate constants and grid-register to typescript (#22095) 2026-03-23 07:53:36 +01:00
renovate[bot] 4d94dffa80 chore(support): update dependency teen_process to v4.1.0 (#22094)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-21 16:37:33 +01:00
Mykola Mokhnach 86c8f23a67 feat: use exact version for dependencies in monorepo packages instead of ^ (#22090) 2026-03-21 16:37:22 +01:00
Mykola Mokhnach 73b7820df5 feat(strongbox): Add a possibility to list strongbox items (#22091) 2026-03-21 16:37:04 +01:00
renovate[bot] 26f8429509 chore(universal-xml-plugin): update dependency fast-xml-parser to v5.5.8 (#22093)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-21 14:06:08 +00:00
renovate[bot] ff96c9a6e1 chore(support): update dependency sanitize-filename to v1.6.4 (#22092)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-21 08:53:47 +00:00
renovate[bot] 87704de080 chore(types): update dependency type-fest to v5.5.0 (#22084) 2026-03-20 19:41:38 +01:00
renovate[bot] e20ee97139 chore(support): update dependency glob to v13.0.6 (#22089)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-20 19:18:51 +01:00
renovate[bot] 52a620818a chore(docutils): update dependency mkdocs-material to v9.7.6 (#22088)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-20 09:47:34 +00:00
dependabot[bot] 72b9efcb42 chore(deps): bump flatted in the npm_and_yarn group across 1 directory (#22087)
Bumps the npm_and_yarn group with 1 update in the / directory: [flatted](https://github.com/WebReflection/flatted).


Updates `flatted` from 3.4.1 to 3.4.2
- [Commits](https://github.com/WebReflection/flatted/compare/v3.4.1...v3.4.2)

---
updated-dependencies:
- dependency-name: flatted
  dependency-version: 3.4.2
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-20 08:48:23 +02:00
renovate[bot] 2f17a1a0ac chore(universal-xml-plugin): update dependency fast-xml-parser to v5.5.7 [security] (#22086)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-20 04:51:04 +00:00
github-actions[bot]andmykola-mokhnach 87b8603329 docs(appium): Update documentation translations (#22083)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2026-03-18 21:11:16 -07:00
Kazuaki Matsuo 7ab1df8e62 docs(appium): add skills in the tools (#22080)
* docs(appium): add skills in the tools

* Update AI Agent skills description for clarity
2026-03-18 08:02:45 -07:00
renovate[bot] 1412d58452 chore(universal-xml-plugin): update dependency fast-xml-parser to v5.5.6 (#22066)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-17 17:46:15 +00:00
renovate[bot] 63908458c0 chore(test-support): update dependency sinon to v21.0.3 (#22079)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-17 13:56:31 +00:00
renovate[bot] 2c12f647e5 chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.57.1 (#22078)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-17 10:01:34 +00:00
renovate[bot] 75682fa2e5 chore(support): update dependency glob to v13.0.6 (#22073)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-16 20:21:58 +01:00
Mykola Mokhnach af16eafbb2 chore(appium): Migrate utils to typescript (#22075) 2026-03-16 11:38:17 +01:00
renovate[bot] 6cffa01c8d chore(execute-driver-plugin): update dependency webdriverio to v9.26.1 (#22076)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-16 08:54:42 +00:00
renovate[bot] 7abbd51c28 chore(strongbox): update dependency slugify to v1.6.8 (#22074)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-15 08:46:07 +00:00
Mykola Mokhnach 2b859134a8 chore(appium): Migrate logsink to typescript (#22072) 2026-03-14 20:54:55 +01:00
renovate[bot] 06b5fe5019 chore(deps): update dependency lerna to v9.0.7 (#22070)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-14 17:41:41 +01:00
renovate[bot] d6a195a556 chore(storage-plugin): update dependency lru-cache to v11.2.7 (#22071)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-14 17:41:28 +01:00
renovate[bot] 69bd198a18 chore(workflows): update slackapi/slack-github-action action to v3 (#22067)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-14 12:50:02 +02:00
dependabot[bot] 3ca551ba2e chore(deps): bump the npm_and_yarn group across 1 directory with 2 updates (#22069)
Bumps the npm_and_yarn group with 2 updates in the / directory: [flatted](https://github.com/WebReflection/flatted) and [undici](https://github.com/nodejs/undici).


Updates `flatted` from 3.3.2 to 3.4.1
- [Commits](https://github.com/WebReflection/flatted/compare/v3.3.2...v3.4.1)

Updates `undici` from 6.23.0 to 6.24.0
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v6.23.0...v6.24.0)

---
updated-dependencies:
- dependency-name: flatted
  dependency-version: 3.4.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
- dependency-name: undici
  dependency-version: 6.24.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-14 12:46:31 +02:00
dependabot[bot] f897dbaacb chore(deps-dev): bump tar in the npm_and_yarn group across 1 directory (#22068)
Bumps the npm_and_yarn group with 1 update in the / directory: [tar](https://github.com/isaacs/node-tar).


Updates `tar` from 7.5.8 to 7.5.11
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v7.5.8...v7.5.11)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.11
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-14 00:05:53 +02:00
github-actions[bot]andmykola-mokhnach e83e513957 docs(appium): Update documentation translations (#22065)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2026-03-12 18:43:19 -07:00
Edgars Eglītis d3e8ddc35b docs: add reference pages for caps & insecure features (#22064)
* docs: add reference page for globally recognized caps

* docs: add index page

* docs: add reference for insecure features

* docs: update server security doc

* docs: update caps guide doc

* docs: address comments

* docs: address more comments
2026-03-12 20:58:35 +02:00
renovate[bot] d5092ffd30 chore(eslint-config-appium-ts): update dependency eslint-plugin-import-x to v4.16.2 (#22063)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-12 18:01:45 +00:00
renovate[bot] 91a9eb782a chore(deps): update dependency lerna to v9.0.6 (#22062)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-12 13:45:26 +00:00
renovate[bot] 3a452888fc chore(universal-xml-plugin): update dependency fast-xml-parser to v5.5.3 (#22061)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-12 09:40:41 +00:00
renovate[bot] 66ddff0a33 chore(execute-driver-plugin): update dependency webdriverio to v9.25.0 (#22060)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-11 13:29:44 +00:00
renovate[bot] d7c30108d6 chore(support): update dependency yauzl to v3.2.1 (#22059)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-11 08:40:56 +00:00
Kazuaki Matsuo f628d517fe ci: update publish docs workflow (#22057)
* ci: update publish docs workflow

* use docs:publish

* Add step to fetch gh-pages before publishing docs

* ci: run after 'Appium Server Release' completion
2026-03-11 00:20:54 -07:00
Mykola Mokhnach 190c30b418 chore(base-driver): Migrate proxy.js to typescript (#22054) 2026-03-11 07:07:54 +01:00
renovate[bot] fa7ba639d4 chore(docutils): update dependency mkdocs-material to v9.7.5 (#22058)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-11 05:04:19 +00:00
github-actions[bot]andmykola-mokhnach 1b1314cd6b docs(appium): Update documentation translations (#22056)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2026-03-10 19:45:48 -07:00
Mykola Mokhnach 36179e8795 docs: Enhance documentation on properties managed by the umbrella driver (#22055) 2026-03-10 22:23:48 +01:00
renovate[bot] 825431b14a chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.57.0 (#22053)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-10 08:56:24 +00:00
github-actions c745352c65 chore: publish
- appium@3.2.2
 - @appium/base-driver@10.2.2
 - @appium/base-plugin@3.1.1
 - @appium/fake-plugin@4.1.1
2026-03-09 18:42:00 +00:00
Mykola Mokhnach 1d89e2a5f8 fix(appium): Exclude package.json from tsconfig (#22052) 2026-03-09 19:33:14 +01:00
Mykola Mokhnach 2dfae495ff chore(base-driver): Migrate protocol converter to typescript (#22049) 2026-03-08 21:51:32 +01:00
github-actions 980a121804 chore: publish
- appium@3.2.1
 - @appium/base-driver@10.2.1
 - @appium/base-plugin@3.1.0
 - @appium/docutils@2.2.2
 - @appium/driver-test-support@1.1.0
 - @appium/eslint-config-appium-ts@3.0.1
 - @appium/execute-driver-plugin@6.0.0
 - @appium/fake-driver@6.1.0
 - @appium/fake-plugin@4.1.0
 - @appium/images-plugin@4.1.1
 - @appium/logger@2.0.5
 - @appium/opencv@4.1.1
 - @appium/plugin-test-support@1.1.0
 - @appium/relaxed-caps-plugin@2.1.0
 - @appium/schema@1.1.0
 - @appium/storage-plugin@1.0.6
 - @appium/strongbox@1.0.2
 - @appium/support@7.0.6
 - @appium/test-support@4.0.6
 - @appium/tsconfig@1.1.2
 - @appium/types@1.2.1
 - @appium/universal-xml-plugin@2.1.0
2026-03-08 20:32:27 +00:00
Kazuaki Matsuo 8fae5e69ea ci: add github token for a release task 2026-03-08 13:30:40 -07:00
Kazuaki Matsuo 2d149121e1 ci: print only versions in release task (#22050) 2026-03-08 12:43:38 -07:00
renovate[bot] 362a2a2d4d chore(docutils): update dependency mike to v2.1.4 (#22048)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-08 12:41:14 +00:00
Mykola Mokhnach 503f0c1f18 ci: Add manual release workflow (#22043) 2026-03-08 08:30:31 +01:00
Mykola Mokhnach a1095d2816 chore(base-driver): Migrate status.js to typescript (#22047) 2026-03-08 08:29:55 +01:00
Mykola Mokhnach e7e26e5f57 chore(base-driver): Migrate the rest of protocol modules to typescript (#22046) 2026-03-07 19:16:46 +01:00
renovate[bot] b4c1b7be78 chore(eslint-config-appium-ts): update eslint monorepo to v9.39.4 (#22045)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-07 16:22:14 +01:00
Edgars Eglītis eee4c05844 fix(support): add path traversal check in _extractEntryTo (#22042)
* fix(support): add path traversal check for `_extractEntryTo`

* simplify

* use isSubPath

* add test
2026-03-07 17:08:27 +02:00
renovate[bot] f2e4bc7fcd chore(eslint-config-appium-ts): update dependency @eslint/compat to v2.0.3 (#22044)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-07 14:00:43 +00:00
renovate[bot] 5187e63e33 chore(deps): update dependency @types/node to v24.12.0 (#22040)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-06 08:33:37 +01:00
renovate[bot] 43a096cf1f chore(eslint-config-appium-ts): update dependency @stylistic/eslint-plugin to v5.10.0 (#22041)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-06 08:33:25 +01:00
Mykola Mokhnach 27c39aed20 chore(base-driver): Migrate routes.js to typescript (#22039) 2026-03-06 08:33:05 +01:00
Mykola Mokhnach 176f19beff chore(base-driver): Migrate capability helpers to typescript (#22037) 2026-03-05 19:12:00 +01:00
renovate[bot] dd0be5ec6c chore(test-support): update dependency sinon to v21.0.2 (#22038)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-05 15:41:51 +00:00
Mykola Mokhnach a7006075f8 chore(base-driver): Migrate the rest of express modules to typescript (#22036) 2026-03-04 21:03:22 +01:00
Mykola Mokhnach 3b728c641a chore(base-driver): Migrate websocket and express logging helpers to typescript (#22034) 2026-03-04 18:28:24 +01:00
renovate[bot] 367ba33deb chore(docutils): update dependency mkdocs-material to v9.7.4 (#22033)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-04 09:30:04 +00:00
Mykola Mokhnach 5d260c78a2 chore(base-driver): Migrate middleware.js to typescript (#22032) 2026-03-04 07:21:28 +01:00
Mykola Mokhnach 7deb40a4a4 chore(base-driver): Migrate server.js to typescript (#22030) 2026-03-03 19:01:05 +01:00
renovate[bot] 2c8ff15c30 chore(universal-xml-plugin): update dependency fast-xml-parser to v5.4.2 (#22031)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-03-03 14:54:47 +00:00
Edgars Eglītis 405d8e9491 chore: run npm audit fix (#22029) 2026-03-01 21:29:55 +02:00
Edgars Eglītis 207761a2dc chore(support): drop non-breaking uses of bluebird (#22026)
* chore(support): drop bluebird

* remove extra newline

* fix timeout not being cleared

* simplify zipReadStream

* address comments

* drop custom error classes

* simplify promisified types

* add back bluebird where needed to avoid breaking changes

* tune cancellableDelay
2026-03-01 21:17:27 +02:00
Mykola Mokhnach c6d9e079c3 chore(base-driver): Migrate settings and logger to typescript (#22028) 2026-03-01 16:41:25 +01:00
Mykola Mokhnach 69482ee634 chore(base-driver): Migrate helpers.js to typescript (#22027) 2026-02-28 22:35:14 +01:00
Mykola Mokhnach 2f27425ea3 fix: Type imports (#22025) 2026-02-28 19:53:11 +01:00
renovate[bot] 61bba1e06f chore(support): update dependency glob to v13.0.6 (#22024)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-28 15:33:42 +02:00
renovate[bot] eda42cffff chore(deps): update dependency @types/node to v24.11.0 (#22021)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-28 13:10:21 +01:00
dependabot[bot] bfc57ea366 chore(deps): bump tar in the npm_and_yarn group across 1 directory (#22022)
Bumps the npm_and_yarn group with 1 update in the / directory: [tar](https://github.com/isaacs/node-tar).


Updates `tar` from 7.5.7 to 7.5.8
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v7.5.7...v7.5.8)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.8
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-28 13:10:08 +01:00
Mykola Mokhnach 0110437610 chore(types): Migrate index to lib (#22023) 2026-02-28 13:09:50 +01:00
renovate[bot] 0c966f2ce1 chore(support): update dependency axios to v1.13.6 (#22020)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-28 08:57:05 +00:00
Mykola Mokhnach 954ee5f621 chore(docutils): Migrate index to lib (#22019) 2026-02-28 09:22:09 +01:00
Mykola Mokhnach 9db2b7827d chore(support): Move index to lib (#22018) 2026-02-28 09:21:59 +01:00
Mykola Mokhnach b11cb78d11 chore(support): migrate zip.js to typescript (#22017) 2026-02-27 21:42:32 +01:00
renovate[bot] 9c7e2efaaf chore(deps): update dependency @types/node to v24.10.15 (#22015)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-27 10:14:51 +01:00
renovate[bot] 987996cc22 chore(support): update dependency glob to v13.0.6 (#22016)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-27 10:14:40 +01:00
Mykola Mokhnach 5c3289a8e9 chore(support): Migrate util.js to typescript (#22013) 2026-02-27 10:14:20 +01:00
Kazuaki Matsuo 98d2497b49 fix(support): fix missing throw for Error (#22014) 2026-02-26 23:05:27 -08:00
dependabot[bot] 579b6538f0 chore(deps): bump basic-ftp in the npm_and_yarn group across 1 directory (#22011)
Bumps the npm_and_yarn group with 1 update in the / directory: [basic-ftp](https://github.com/patrickjuchli/basic-ftp).


Updates `basic-ftp` from 5.0.5 to 5.2.0
- [Release notes](https://github.com/patrickjuchli/basic-ftp/releases)
- [Changelog](https://github.com/patrickjuchli/basic-ftp/blob/master/CHANGELOG.md)
- [Commits](https://github.com/patrickjuchli/basic-ftp/compare/v5.0.5...v5.2.0)

---
updated-dependencies:
- dependency-name: basic-ftp
  dependency-version: 5.2.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-26 18:04:39 +01:00
Mykola Mokhnach 5dac35b3cc chore(support): Migrate timing.js to typescript (#22010) 2026-02-26 18:04:24 +01:00
renovate[bot] 3c1f0fc99f chore(deps): update dependency @types/node to v24.10.14 (#22012)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-26 15:05:44 +00:00
renovate[bot] f94df7feb0 chore(universal-xml-plugin): update dependency fast-xml-parser to v5.4.1 (#22007)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-25 18:14:55 +01:00
Edgars Eglītis fb8b9297da chore(deps): run npm audit fix (#22009) 2026-02-25 16:51:42 +02:00
Mykola Mokhnach dcc6a00d10 fix(support): Make staticDir call lazy (#22008) 2026-02-25 09:42:34 +01:00
renovate[bot] 4838d301f6 chore(docutils): update dependency mkdocs-material to v9.7.3 (#22006)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-25 06:55:03 +00:00
Mykola Mokhnach 5f73989a17 chore(support): Migrate tempdir.js to typescript (#22005) 2026-02-24 22:54:13 +01:00
renovate[bot] 6db6e2a5d0 chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.56.1 (#22004)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-24 13:10:58 +00:00
Mykola Mokhnach 3708211153 chore(support): Migrate system.js to typescript (#22003) 2026-02-23 21:32:08 +01:00
Mykola Mokhnach 30f9ad5202 chore(support): Migrate process.js to typescript (#22002) 2026-02-23 18:44:20 +01:00
renovate[bot] 1cb5f91cce chore(deps): update dependency @types/lodash to v4.17.24 (#22001)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-23 09:49:42 +00:00
Mykola Mokhnach b885084dde chore(support): Migrate plist.js to typescript (#22000) 2026-02-22 21:18:40 +01:00
Mykola Mokhnach 90785783e6 chore(support): Migrate npm.js to typescript (#21999) 2026-02-22 17:24:43 +01:00
Mykola Mokhnach 358c6aaf4f chore(support): migrate node.js to typescript (#21998) 2026-02-21 20:06:36 +01:00
Edgars Eglītis 09f7e6c245 test(appium,base-driver,support): drop bluebird (#21996)
* test(appium,base-driver,support): drop bluebird

* copilot
2026-02-21 14:26:49 +02:00
renovate[bot] 0ebd0c3ccd chore(eslint-config-appium-ts): update eslint monorepo to v9.39.3 (#21997)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-21 12:24:38 +01:00
Mykola Mokhnach 4daaa14c29 fix(logger): Make sure we always have single logger instance per process (#21991) 2026-02-21 12:12:15 +01:00
Edgars Eglītis 8895ac79d7 feat(execute-driver-plugin)!: replace bluebird usage inside scripts with native promises (#21990)
BREAKING CHANGE: The `Promise` object in the script context now matches the global `Promise` object instead of `bluebird`. Methods specific to `bluebird` are no longer supported.
2026-02-20 22:11:01 +02:00
Edgars Eglītis 196c38f7af chore(deps-dev): remove unused yaml-js (#21995) 2026-02-20 19:22:30 +02:00
Edgars Eglītis edae4ac239 chore(fake-plugin): drop bluebird (#21992) 2026-02-20 14:36:30 +02:00
renovate[bot] fec645f64a chore(support): update dependency glob to v13.0.6 (#21993)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-20 13:28:35 +01:00
renovate[bot] df7efe4339 chore(universal-xml-plugin): update dependency fast-xml-parser to v5.3.7 (#21994)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-20 13:28:22 +01:00
Edgars Eglītis 7467221f64 chore(driver-test-support): drop bluebird (#21989) 2026-02-19 23:38:07 +02:00
Edgars Eglītis cad140783f chore(fake-driver): drop bluebird (#21988) 2026-02-19 21:53:57 +02:00
Edgars Eglītis 69e667b969 chore(deps): run npm audit fix (#21987) 2026-02-19 21:35:38 +02:00
Mykola Mokhnach f2dcd2d32f chore(support): Migrate mkdirp and net helpers to typescript (#21985) 2026-02-19 20:27:20 +01:00
Edgars Eglītis 77f9f14e48 chore(opencv): drop bluebird (#21986) 2026-02-19 21:25:28 +02:00
renovate[bot] 550f134f75 chore(eslint-config-appium-ts): update dependency @stylistic/eslint-plugin to v5.9.0 (#21984)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-19 17:45:50 +00:00
renovate[bot] 2cc5c59426 chore(docutils): update dependency mkdocs-material to v9.7.2 (#21982)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-19 09:50:56 +00:00
github-actions[bot]andmykola-mokhnach ee57552181 docs(appium): Update documentation translations (#21981)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2026-02-18 22:33:51 -08:00
Edgars Eglītis 7b908ec869 chore(storage-plugin): drop bluebird (#21980) 2026-02-18 23:53:16 +02:00
Mykola Mokhnach 8f13721110 chore(support): Migrate mjpeg.js to typescript (#21979) 2026-02-18 21:33:16 +01:00
renovate[bot] b6b340225c chore(support): update dependency glob to v13.0.5 (#21978)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-18 10:43:28 +00:00
Edgars Eglītis df60c91482 chore: remove obsolete root-level files (#21975)
* chore: remove obsolete root-level files

* chore: remove duplicated code of conduct

* chore: remove old ideas doc

* docs: update code of conduct link
2026-02-18 08:46:27 +02:00
Mykola Mokhnach 9b0dac0b61 chore(support): Migrate logging helpers to typescript (#21977) 2026-02-17 21:57:00 +01:00
renovate[bot] 5cd25c1d0c chore(support): update dependency glob to v13.0.4 (#21973)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-17 18:21:11 +01:00
renovate[bot] bfa5debfb8 chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.56.0 (#21974)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-17 18:20:55 +01:00
Mykola Mokhnach 6f78e06c34 chore(support): Migrate image-util.js to typescript (#21972) 2026-02-16 19:04:43 +01:00
renovate[bot] d59a7c9d49 chore(support): update dependency teen_process to v4.0.10 (#21971)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-16 17:30:45 +00:00
renovate[bot] bce5946755 chore(deps): update dependency rimraf to v6.1.3 (#21970)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-16 13:16:09 +00:00
Mykola Mokhnach 94e811d284 chore(support): Migrate fs.js to typescript (#21969) 2026-02-15 20:22:20 +01:00
Mykola Mokhnach 500ce8bc03 chore(support): Migrate env.js to typescript (#21968) 2026-02-15 18:57:41 +01:00
Kazuaki Matsuo d734b4c200 fix(base-driver): fix session id handling more (#21962)
* fix(appium): fix session id handling more

* modify the comment

* Refine comments in getSessionId and the log

Updated comments for clarity and corrected typos.
2026-02-15 09:12:34 -08:00
renovate[bot] 666c92cd72 chore(appium): update dependency ajv to v8.18.0 (#21966)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-15 14:14:20 +00:00
renovate[bot] 906ad62e8a chore(eslint-config-appium-ts): update dependency eslint-plugin-n to v17.24.0 (#21967)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-15 08:30:12 +00:00
Mykola Mokhnach 951e1c2a3b chore(support): Migrate doctor.js to typescript (#21965) 2026-02-15 08:42:54 +01:00
Mykola Mokhnach 9f5faf5bed fix: Avoid attaching plugins to a non-existing session (#21964) 2026-02-15 08:42:40 +01:00
Mykola Mokhnach 453a9e9e01 chore(support): Migrate console utils (#21961) 2026-02-14 19:52:41 +01:00
renovate[bot] 5bb75c0859 chore(universal-xml-plugin): update dependency fast-xml-parser to v5.3.6 (#21963)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-14 14:06:58 +00:00
Edgars Eglītis bcda0bec56 chore(support): replace moment with native Date (#21960)
* chore(support): replace moment with native Date

* avoid concatenation
2026-02-13 20:58:50 +02:00
Mykola Mokhnach 0caab1fa58 test(base-driver): Migrate e2e tests to typescript (#21956) 2026-02-13 19:21:05 +01:00
Edgars Eglītis f54961a655 chore(storage-plugin): replace rimraf with @appium/support equivalent (#21959) 2026-02-13 20:01:46 +02:00
Edgars Eglītis 8c9e66a70f chore(deps): run npm audit fix (#21958) 2026-02-13 15:58:21 +02:00
renovate[bot] 46fe54555c chore(support): update dependency glob to v13.0.3 (#21957)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-13 09:26:18 +00:00
Mykola Mokhnach 761bee667b test(base-driver): Migrate unit tests to typescript (#21955) 2026-02-12 20:04:10 +01:00
Kazuaki Matsuo 77eed7d4c0 chore(base-driver): update type of express-serve-static-core (#21942)
* chore(base-driver): update type of express-serve-static-core

* modify

* clean up a bit

* use debug

* remove error, address possible array case

* chore: remove a line

Check if the driver proxy is active before proceeding.
2026-02-11 22:17:39 -08:00
renovate[bot] 8ce7b05325 chore(support): update dependency which to v6.0.1 (#21953)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-11 18:08:22 +01:00
renovate[bot] 5ed44a0131 chore(support): update dependency glob to v13.0.2 (#21952)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-11 18:08:10 +01:00
renovate[bot] 55e61cc625 chore(storage-plugin): update dependency lru-cache to v11.2.6 (#21951)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-11 13:56:23 +00:00
renovate[bot] a1c5c03e8c chore(eslint-config-appium-ts): update dependency eslint-plugin-unicorn to v63 (#21954)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-11 12:54:07 +02:00
renovate[bot] 5259e27ee8 chore(deps): update dependency lerna to v9.0.4 (#21950)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-11 08:43:24 +00:00
renovate[bot] 2a49c53ce6 chore(deps): update dependency @types/node to v24.10.13 (#21949)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-11 07:16:49 +00:00
Mykola Mokhnach 6e8c19c83e test(logger): Migrate tests to typescript (#21948) 2026-02-11 07:11:59 +01:00
Mykola Mokhnach 2611459ac8 chore(appium): Split package installation and validation (#21947) 2026-02-11 07:11:05 +01:00
Mykola Mokhnach 1707cc1f85 feat(fake-driver): Migrate doctor scripts to typescript (#21946) 2026-02-10 22:33:18 +01:00
Mykola Mokhnach 9ea601c833 fix(appium): Fix CLI arguments normalization (#21945) 2026-02-10 17:43:20 +01:00
Mykola Mokhnach 0515ae5c49 feat(fake-driver): Migrate to typescript (#21935) 2026-02-10 16:32:47 +01:00
renovate[bot] d0df4fbd3b chore(execute-driver-plugin): update dependency webdriverio to v9.24.0 (#21944)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-10 14:11:53 +00:00
renovate[bot] 5da1e7dee3 chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.55.0 (#21943)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-10 10:14:26 +00:00
renovate[bot] f7e6da2bd4 chore(support): update dependency read-pkg to v10.1.0 (#21939)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-09 19:39:55 +00:00
renovate[bot] 12347b5323 chore(eslint-config-appium-ts): update dependency @stylistic/eslint-plugin to v5.8.0 (#21941)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-09 13:12:26 +00:00
renovate[bot] 2d97841834 chore(universal-xml-plugin): update dependency fast-xml-parser to v5.3.5 (#21938)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-09 10:54:36 +00:00
Mykola Mokhnach 51e9b06784 test(appium): Fix BiDi test (#21936) 2026-02-08 18:43:16 +01:00
renovate[bot] b7eec0a01d chore(types): update dependency type-fest to v5.4.4 (#21934)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-08 14:14:31 +01:00
renovate[bot] e9eed8de4c chore(support): update dependency axios to v1.13.5 (#21933)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-08 14:14:23 +01:00
renovate[bot] d1e07b55e2 chore(deps): update dependency @types/node to v24.10.12 (#21932)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-08 12:45:45 +00:00
Mykola Mokhnach ecaa49f00c test(fake-driver): Migrate to typescript (#21931) 2026-02-08 10:05:28 +01:00
Mykola Mokhnach a570aa4781 chore(appium): Remove unused scripts (#21930) 2026-02-07 19:27:58 +01:00
Mykola Mokhnach a938fa4e7b test(appium): Migrate tests to typescript (#21928) 2026-02-07 10:41:42 +01:00
Kazuaki Matsuo 18355bdf3a docs(execute-driver-plugin): add note about possible risk (#21924)
* docs(execute-driver-plugin): add note about possible risk

Update README to clarify plugin usage and security note.

* Update README.md
2026-02-06 22:56:10 -08:00
renovate[bot] df509693d1 chore(support): update dependency semver to v7.7.4 (#21927)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-06 17:50:41 +00:00
renovate[bot] 4048e1bfde chore(deps): update dependency @types/node to v24.10.11 (#21926)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-06 14:32:32 +00:00
Mykola Mokhnach 844e80c19c test(support): Migrate tests to typescript (#21925) 2026-02-05 23:32:12 +01:00
Mykola Mokhnach e33ad95851 feat(driver-test-support): Migrate to typescript (#21922) 2026-02-05 17:05:35 +01:00
renovate[bot] d308390db7 chore(deps): update dependency cpy-cli to v7 (#21923)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-05 12:19:05 +02:00
renovate[bot] 8b3c69f03c chore(tsconfig): update dependency @tsconfig/node20 to v20.1.9 (#21921)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-04 11:07:30 +00:00
dependabot[bot] 94e58f2ea6 chore(deps): bump @isaacs/brace-expansion (#21919)
Updates `@isaacs/brace-expansion` from 5.0.0 to 5.0.1

---
updated-dependencies:
- dependency-name: "@isaacs/brace-expansion"
  dependency-version: 5.0.1
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-04 09:29:03 +02:00
Mykola Mokhnach 2615935939 fix: Move @appium/types to dev dependencies for various packages (#21920) 2026-02-03 21:02:18 -08:00
Mykola Mokhnach 07b573df27 feat(base-plugin): Migrate to typescript (#21918) 2026-02-03 22:58:38 +01:00
renovate[bot] eb0aaa2e5f chore(deps): update dependency @types/node to v24.10.10 (#21917)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-03 14:07:04 +00:00
renovate[bot] f736bce4a5 chore(support): update dependency package-directory to v8.2.0 (#21916)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-02 17:09:51 +00:00
renovate[bot] 7343ec8cb5 chore(types): update dependency type-fest to v5.4.3 (#21915)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-02 12:50:28 +00:00
renovate[bot] 2cfc5d3956 chore(execute-driver-plugin): update dependency webdriverio to v9.23.3 (#21914)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-02-02 09:00:00 +00:00
Mykola Mokhnach 7b139d7e35 feat(fake-plugin): Migrate to typescript (#21913) 2026-02-02 09:48:44 +01:00
Mykola Mokhnach 27e7e5a4e2 feat(plugin-test-support): Migrate to typescript (#21911) 2026-02-01 21:23:38 +01:00
Mykola Mokhnach 36fd0af47e test(storage-plugin): Migrate to typescript (#21912) 2026-02-01 16:02:21 +01:00
Edgars Eglītis f4426a82dc chore: remove old WDIO version from lockfile (#21910) 2026-02-01 00:39:08 +02:00
Mykola Mokhnach 4f860502c4 test(appium): Update plugin resolution test (#21909) 2026-01-31 10:41:06 +01:00
Mykola Mokhnach 59ef8af269 feat(relaxed-caps-plugin): Migrate to typescript (#21908) 2026-01-31 10:31:39 +01:00
renovate[bot] 6461188ba8 chore(eslint-config-appium-ts): update dependency @eslint/compat to v2.0.2 (#21907)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-31 08:41:04 +00:00
Kazuaki Matsuo 971c584a17 chore(docs): update openjs foundation copyright format (#21906)
* chore(docs): update openjs foundation copyright format

* remove extra space
2026-01-30 23:10:14 -08:00
renovate[bot] 4d8dec1c91 chore(universal-xml-plugin): update dependency fast-xml-parser to v5.3.4 (#21904)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-30 12:26:18 +00:00
renovate[bot] eb344f0225 chore(base-driver): update dependency asyncbox to v6.1.0 (#21899)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-29 10:33:03 +00:00
github-actions[bot]andmykola-mokhnach 3cdacfcdbe docs(appium): Update documentation translations (#21901)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2026-01-29 08:47:27 +02:00
Mykola Mokhnach d43f749fc7 feat(schema): Migrate to typescript (#21900) 2026-01-28 21:32:02 +01:00
renovate[bot] 5a736fba08 chore(types): update dependency type-fest to v5.4.2 (#21898)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-28 18:54:09 +01:00
renovate[bot] 7c99e88fcf chore(support): update dependency teen_process to v4.0.9 (#21897)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-28 17:38:09 +00:00
Mykola Mokhnach 75ae6145c2 feat(universal-xml-plugin): Migrate to typescript (#21894) 2026-01-28 18:38:04 +01:00
renovate[bot] 31f4f298e1 chore(support): update dependency axios to v1.13.4 (#21896)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-28 13:10:56 +00:00
Navin Chandra b013a548f0 docs(appium): update lambdatest to TestMu AI (#21893)
* update lambdatest to TestMu AI

* revert ja/zh changes

* revert textual changes

* revert blogposts
2026-01-28 12:40:12 +02:00
github-actions[bot]andmykola-mokhnach c5053e2248 docs(appium): Update documentation translations (#21895)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2026-01-27 22:16:05 -08:00
Kazuaki Matsuo 0e84047ab3 docs(appium): add branch example (#21890)
* docs(appium): add branch example

Add instructions for installing a specific branch of the XCUITest driver.

* Update extensions.md
2026-01-27 12:48:22 -08:00
renovate[bot] e9255d8b8e chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.54.0 (#21892)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-27 17:04:05 +00:00
renovate[bot] 98214795fe chore(docutils): update dependency mkdocs-git-revision-date-localized-plugin to v1.5.1 (#21891)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-27 13:58:46 +00:00
Jonathan Lipps 3c70437da4 chore: publish 2026-01-27 08:08:28 +09:00
Jonathan Lipps f7b20335ea chore: publish
- appium@3.2.0
 - @appium/base-driver@10.2.0
 - @appium/base-plugin@3.0.6
 - @appium/docutils@2.2.1
 - @appium/driver-test-support@1.0.6
 - @appium/eslint-config-appium-ts@3.0.0
 - @appium/execute-driver-plugin@5.1.0
 - @appium/fake-driver@6.0.2
 - @appium/fake-plugin@4.0.6
 - @appium/images-plugin@4.1.0
 - @appium/logger@2.0.4
 - @appium/opencv@4.1.0
 - @appium/plugin-test-support@1.0.5
 - @appium/relaxed-caps-plugin@2.0.2
 - @appium/schema@1.0.1
 - @appium/storage-plugin@1.0.5
 - @appium/strongbox@1.0.1
 - @appium/support@7.0.5
 - @appium/test-support@4.0.5
 - @appium/types@1.2.0
 - @appium/universal-xml-plugin@2.0.4
2026-01-27 07:59:26 +09:00
renovate[bot] 8b9597b0e5 chore(support): update dependency axios to v1.13.3 (#21889)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-26 08:25:32 +01:00
renovate[bot] 556e90be7e chore(storage-plugin): update dependency lru-cache to v11.2.5 (#21888)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-26 08:25:23 +01:00
Mykola Mokhnach ab8ee41e79 feat(execute-driver-plugin): Migrate to typescript (#21887) 2026-01-25 22:52:21 +01:00
renovate[bot] 028a4274e1 chore(strongbox): update dependency env-paths to v4 (#21886)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-25 12:13:20 +02:00
renovate[bot] 9a4e5c77ac chore(eslint-config-appium-ts): update dependency @stylistic/eslint-plugin to v5.7.1 (#21885)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-24 13:48:44 +00:00
renovate[bot] cafb9bf089 chore(support): update dependency teen_process to v4.0.8 (#21884)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-23 14:45:37 +00:00
renovate[bot] cdfe8ddc48 chore(base-driver): update dependency asyncbox to v6.0.1 (#21879)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-23 09:11:19 +00:00
Mykola Mokhnach 5ff00a0a5c chore: Make sure tests are never included into published dist (#21883) 2026-01-23 08:13:36 +01:00
Mykola Mokhnach fec5f3a377 feat(opencv): Migrate to typescript (#21881) 2026-01-23 06:54:29 +01:00
Edgars Eglītis 5e5b76cf6b chore(deps): update asyncbox to v6 (#21880) 2026-01-22 20:17:20 +02:00
renovate[bot] efd13358cc chore(workflows): update peter-evans/create-pull-request action to v8.1.0 (#21878)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-22 09:40:28 +00:00
renovate[bot] 17eb3cac86 chore(deps): update dependency prettier to v3.8.1 (#21877)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-22 06:43:28 +00:00
dependabot[bot] 4419664ffd chore(deps): bump the npm_and_yarn group across 16 directories with 1 update (#21875)
Bumps the npm_and_yarn group with 1 update in the / directory: [lodash](https://github.com/lodash/lodash).
Bumps the npm_and_yarn group with 1 update in the /packages/appium directory: [lodash](https://github.com/lodash/lodash).
Bumps the npm_and_yarn group with 1 update in the /packages/base-driver directory: [lodash](https://github.com/lodash/lodash).
Bumps the npm_and_yarn group with 1 update in the /packages/docutils directory: [lodash](https://github.com/lodash/lodash).
Bumps the npm_and_yarn group with 1 update in the /packages/driver-test-support directory: [lodash](https://github.com/lodash/lodash).
Bumps the npm_and_yarn group with 1 update in the /packages/execute-driver-plugin directory: [lodash](https://github.com/lodash/lodash).
Bumps the npm_and_yarn group with 1 update in the /packages/fake-driver directory: [lodash](https://github.com/lodash/lodash).
Bumps the npm_and_yarn group with 1 update in the /packages/fake-plugin directory: [lodash](https://github.com/lodash/lodash).
Bumps the npm_and_yarn group with 1 update in the /packages/images-plugin directory: [lodash](https://github.com/lodash/lodash).
Bumps the npm_and_yarn group with 1 update in the /packages/logger directory: [lodash](https://github.com/lodash/lodash).
Bumps the npm_and_yarn group with 1 update in the /packages/opencv directory: [lodash](https://github.com/lodash/lodash).
Bumps the npm_and_yarn group with 1 update in the /packages/relaxed-caps-plugin directory: [lodash](https://github.com/lodash/lodash).
Bumps the npm_and_yarn group with 1 update in the /packages/storage-plugin directory: [lodash](https://github.com/lodash/lodash).
Bumps the npm_and_yarn group with 1 update in the /packages/support directory: [lodash](https://github.com/lodash/lodash).
Bumps the npm_and_yarn group with 1 update in the /packages/test-support directory: [lodash](https://github.com/lodash/lodash).
Bumps the npm_and_yarn group with 1 update in the /packages/universal-xml-plugin directory: [lodash](https://github.com/lodash/lodash).


Updates `lodash` from 4.17.21 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

Updates `lodash` from 4.17.21 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

Updates `lodash` from 4.17.21 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

Updates `lodash` from 4.17.21 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

Updates `lodash` from 4.17.21 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

Updates `lodash` from 4.17.21 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

Updates `lodash` from 4.17.21 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

Updates `lodash` from 4.17.21 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

Updates `lodash` from 4.17.21 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

Updates `lodash` from 4.17.21 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

Updates `lodash` from 4.17.21 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

Updates `lodash` from 4.17.21 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

Updates `lodash` from 4.17.21 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

Updates `lodash` from 4.17.21 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

Updates `lodash` from 4.17.21 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

Updates `lodash` from 4.17.21 to 4.17.23
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.21...4.17.23)

---
updated-dependencies:
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: direct:production
  dependency-group: npm_and_yarn
- dependency-name: lodash
  dependency-version: 4.17.23
  dependency-type: direct:production
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-22 08:36:09 +02:00
renovate[bot] 4be29e49b5 chore(fake-driver): update dependency asyncbox to v5 (#21874)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-21 11:34:31 +02:00
renovate[bot] f115ebed49 chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.53.1 (#21871)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-20 12:41:13 +00:00
Edgars Eglītis beb9da3320 chore: run npm audit fix (#21869) 2026-01-19 11:29:00 +02:00
Mykola Mokhnach 7c9d1363a9 test(images-plugin): Migrate tests to typescript (#21868) 2026-01-18 20:53:54 +01:00
Kazuaki Matsuo 5e28714442 fix: apply npm run lint:fix (#21867) 2026-01-18 09:04:01 -08:00
Mykola Mokhnach 14507371f7 feat(images-plugin): Migrate to typescript (#21865) 2026-01-18 16:10:48 +01:00
renovate[bot] 384afc77ff chore(execute-driver-plugin): update dependency webdriverio to v9.23.2 (#21866)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-18 12:59:27 +00:00
Kazuaki Matsuo 77c9b58989 feat(eslint-config-appium-ts): add unicorn/prefer-node-protocol with warn (#21864)
* feat(eslint-config-appium-ts): add unicorn/prefer-node-protocol with warn

* chore: remvoe unicorn from test files block
2026-01-18 01:28:25 -08:00
renovate[bot] 9500bd17e3 chore(deps): update dependency @types/node to v24.10.9 (#21862)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-16 08:49:10 +00:00
Edgars Eglītis 1f9e786df2 chore: update lockfile to v3 (#21861) 2026-01-16 09:12:21 +02:00
renovate[bot] a605032f2d chore(deps): update dependency prettier to v3.8.0 (#21860)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-15 08:43:22 +00:00
dependabot[bot] bfa33c6bf7 chore(deps): bump undici in the npm_and_yarn group across 1 directory (#21859)
Bumps the npm_and_yarn group with 1 update in the / directory: [undici](https://github.com/nodejs/undici).


Updates `undici` from 6.21.3 to 6.23.0
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v6.21.3...v6.23.0)

---
updated-dependencies:
- dependency-name: undici
  dependency-version: 6.23.0
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-15 08:43:10 +02:00
renovate[bot] 99d663c930 chore(types): update dependency type-fest to v5.4.1 (#21858)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-14 18:46:18 +00:00
renovate[bot] 70b383deaa chore(eslint-config-appium-ts): update dependency eslint-plugin-n to v17.23.2 (#21857)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-14 13:10:03 +00:00
renovate[bot] 43002e3286 chore(deps): update dependency @types/node to v24.10.8 (#21856)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-14 09:12:05 +00:00
renovate[bot] 2f949e581e chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.53.0 (#21855)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-13 21:13:39 +00:00
renovate[bot] 27419248e4 chore(docutils): update dependency diff to v8.0.3 (#21854)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-13 16:35:44 +00:00
renovate[bot] a5bee22a07 chore(deps): update dependency @types/node to v24.10.7 (#21852)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-12 08:24:04 +00:00
renovate[bot] cfaaf768a5 chore(deps): update definitelytyped (#21850)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-10 17:49:01 +00:00
renovate[bot] 0508626518 chore(eslint-config-appium-ts): update dependency @eslint/compat to v2.0.1 (#21851)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-10 12:54:41 +00:00
renovate[bot] 9dc0030fb9 chore(eslint-config-appium-ts): update dependency @stylistic/eslint-plugin to v5.7.0 (#21849)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-09 13:51:33 +00:00
renovate[bot] 002f8fce7f chore(base-driver): update dependency body-parser to v2.2.2 (#21847)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-08 08:29:58 +00:00
github-actions[bot]andmykola-mokhnach 57ae03f899 docs(appium): Update documentation translations (#21846)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2026-01-08 07:48:22 +01:00
Edgars Eglītis df5a7da467 chore(deps): update qs to 6.14.1 (#21845) 2026-01-07 08:58:05 +02:00
renovate[bot] 8de688f020 chore(storage-plugin): update dependency ws to v8.19.0 (#21843)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-06 16:50:47 +00:00
renovate[bot] d4fcd81aed chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.52.0 (#21842)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-06 13:03:36 +00:00
renovate[bot] aa90b9a840 chore(execute-driver-plugin): update dependency webdriverio to v9.23.0 (#21841)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-04 12:46:13 +00:00
Edgars Eglītis 1f6c82ce6d docs: add SeleniumConf & AppiumConf 2026 banner (#21840) 2026-01-01 16:57:16 +02:00
Kazuaki Matsuo 529aeb48f1 fix(appium): appium symlink behavior across drivers/plugins installations (#21837)
* fix(appium): appium symlink behavior with plugins

* add unit tests

* add invalid format case
2025-12-30 13:03:21 -08:00
renovate[bot] 04d9520f76 chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.51.0 (#21838)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-30 14:52:30 +00:00
renovate[bot] 6098bdeb92 chore(execute-driver-plugin): update dependency webdriverio to v9.22.0 (#21834)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-24 12:40:57 +00:00
Kazuaki Matsuo a6c4fad26b chore: bump teen-process (#21831)
* chore: bump teen-process

* remove renovate

* update tests

* update mock in e2e

* remove the custom rule in renovate

* remove unused tpMock

* remove Custom Rules completely
2025-12-23 09:30:32 -08:00
renovate[bot] 8e36bfe56d chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.50.1 (#21833)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-23 13:35:20 +00:00
renovate[bot] fdb95389b1 chore(driver-test-support): update dependency chai to v6.2.2 (#21832)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-23 12:01:34 +01:00
renovate[bot] 30adda0092 chore(test-support): update dependency sinon to v21.0.1 (#21828)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-20 17:06:05 +00:00
renovate[bot] 441c4e5572 chore(docutils): update dependency mkdocs-material to v9.7.1 (#21827)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-19 15:51:06 +00:00
renovate[bot] 7235392585 chore(fake-driver): update dependency asyncbox to v4 (#21826)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-18 08:33:31 +02:00
Mykola Mokhnach ce91686852 feat(appium): Add repository links to verbose extensions list (#21813) 2025-12-17 16:01:38 +01:00
renovate[bot] cbf7e4dfd6 chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.50.0 (#21825)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-17 10:56:05 +00:00
renovate[bot] a9a66d7cf5 chore(deps): update dependency serve-static to v2.2.1 (#21824)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-17 07:47:48 +00:00
Edgars Eglītis 2bd2bb7667 chore(renovate): remove custom Appium groups (#21821) 2025-12-16 17:40:50 +02:00
Edgars Eglītis 56a45a5244 chore(deps): update read-pkg to v10 (#21820) 2025-12-16 11:54:31 +02:00
Edgars Eglītis d9e4437c55 chore(deps): remove wrap-ansi (#21818)
* chore(deps): remove wrap-ansi

* remove unused lodash import
2025-12-15 20:28:10 +02:00
Edgars Eglītis e9a6e5425c fix(scripts): properly import log-symbols in scripts (#21819) 2025-12-15 17:17:24 +02:00
Edgars Eglītis 053a88bac1 chore(deps): update log-symbols to v7 (#21816) 2025-12-15 14:13:29 +02:00
github-actions[bot]andmykola-mokhnach cae84898d5 docs(appium): Update documentation translations (#21815)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2025-12-14 19:03:22 -08:00
Edgars Eglītis dcfaa88830 fix(docs): add missing verbose flag for CLI list command (#21814) 2025-12-15 00:02:39 +02:00
renovate[bot] 1143896b97 chore(deps): update dependency @types/node to v24.10.4 (#21812)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-14 12:51:52 +00:00
renovate[bot] a90797683c chore(universal-xml-plugin): update dependency fast-xml-parser to v5.3.3 (#21809)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-14 01:36:04 +00:00
renovate[bot] cc42206b4d chore(support): update dependency teen_process to v3.0.6 (#21808)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-13 20:26:48 +00:00
renovate[bot] e9ca1f5dd1 chore(eslint-config-appium-ts): update eslint-related packages to v9.39.2 (#21811)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-13 16:40:04 +00:00
Edgars Eglītis a5ba1c5efb chore: fix all lint issues (#21810)
* chore: fix all lint issues

* fix unit tests

* apply copilot suggestion
2025-12-13 15:24:16 +02:00
Edgars Eglītis b0b219aa01 feat(eslint-config-appium-ts)!: modernize ESLint config (#21781) 2025-12-12 09:07:14 +02:00
github-actions[bot]andmykola-mokhnach 204a07f5a4 docs(appium): Update documentation translations (#21807)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2025-12-11 21:22:03 -08:00
Srinivasan SekarandSaikrishna321 aeef6afb8b docs(appium): Add LambdaTest as Development partner (#21783)
Co-authored-by: Saikrishna321 <saikrishna321@yahoo.com>
2025-12-11 08:58:15 -08:00
Edgars Eglītis 8093c2658c chore(deps): update pkg-dir to v8 and rename it (#21806)
* chore(deps): update pkg-dir to v8 and rename it

* address copilot comments

* remove uuid cache keys since we always pass cwd
2025-12-11 17:28:10 +02:00
Edgars Eglītis 5b74a7653c chore(deps): update get-stream to v9 (#21805) 2025-12-11 16:16:07 +02:00
Edgars Eglītis 671c37a89c chore(deps): update get-port to v7 (#21804) 2025-12-11 15:59:00 +02:00
Edgars Eglītis cb2d6eef6c chore(deps): update env-paths to v3 (#21803) 2025-12-11 15:41:17 +02:00
Edgars Eglītis 183a2683b6 chore(deps): update supports-color to v10 (#21802) 2025-12-11 15:06:57 +02:00
Edgars Eglītis ee3d935899 chore(docutils): remove chalk (#21801) 2025-12-11 13:26:24 +02:00
Edgars Eglītis 591e678e6f chore(deps): remove source-map-support (#21800) 2025-12-11 12:50:26 +02:00
renovate[bot] 0cc3acf5e3 chore(support): update dependency teen_process to v3.0.5 (#21799)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-11 12:37:36 +02:00
Edgars Eglītis b20d36f979 chore(renovate): update config (#21797)
* chore: remove unused packages from Renovate blocklist

* chore: other Renovate config adjustments
2025-12-11 12:30:42 +02:00
renovate[bot] 146bc98876 chore(deps): update dependency @types/node to v24.10.3 (#21796)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-11 11:21:29 +01:00
renovate[bot] 477b837b1c chore(workflows): update peter-evans/create-pull-request action to v8 (#21795)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-10 13:09:12 +02:00
renovate[bot] ac78fedf43 chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.49.0 (#21794)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-09 18:31:24 +00:00
renovate[bot] b0e12852f0 chore(deps): update dependency @types/node to v24.10.2 (#21793)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-09 12:59:31 +00:00
Mykola Mokhnach 274b28cb29 chore(test-support): Mark the module as deprecated (#21791) 2025-12-08 18:34:04 +01:00
renovate[bot] cb9324cda4 chore(types): update dependency type-fest to v5.3.1 (#21792)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-08 14:48:55 +00:00
Karl BaumgartnerandKarl Baumgartner a4b47c02c6 feat(base-driver): add ability to supply custom headers for proxy (#21790)
Signed-off-by: Karl Baumgartner <178656887+karlbaumg@users.noreply.github.com>
Co-authored-by: Karl Baumgartner <178656887+karlbaumg@users.noreply.github.com>
2025-12-07 22:11:53 +01:00
renovate[bot] adf90ee746 chore(appium): update dependency winston to v3.19.0 (#21789)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-07 10:42:25 +01:00
renovate[bot] 653b95965a chore(workflows): update peter-evans/create-pull-request action to v7.0.11 (#21788)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-06 13:35:51 +00:00
github-actions[bot]andmykola-mokhnach 18864bfcac docs(appium): Update documentation translations (#21787)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2025-12-05 20:50:08 -08:00
Edgars Eglītis 6ae5930346 docs: move Appium MCP to official tools (#21786) 2025-12-05 23:16:18 +02:00
Jonathan Lipps 9004554879 chore: publish
- appium@3.1.2
 - @appium/base-driver@10.1.2
 - @appium/base-plugin@3.0.5
 - @appium/docutils@2.2.0
 - @appium/driver-test-support@1.0.5
 - @appium/eslint-config-appium-ts@2.0.5
 - @appium/execute-driver-plugin@5.0.3
 - @appium/fake-plugin@4.0.5
 - @appium/images-plugin@4.0.4
 - @appium/logger@2.0.3
 - @appium/plugin-test-support@1.0.4
 - @appium/storage-plugin@1.0.4
 - @appium/support@7.0.4
 - @appium/test-support@4.0.4
 - @appium/tsconfig@1.1.1
 - @appium/types@1.1.2
 - @appium/universal-xml-plugin@2.0.3
2025-12-04 14:58:53 -08:00
Edgars Eglītis 86d84b8c6a feat(docutils): add 3 Material for MkDocs features (#21784) 2025-12-04 16:38:40 +02:00
renovate[bot] 24b54f4e89 chore(support): update dependency teen_process to v3.0.4 (#21778)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-03 20:55:29 +00:00
renovate[bot] 65bacd51db chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.48.1 (#21777)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-03 19:10:07 +00:00
renovate[bot] 5c1b043ddd chore(types): update dependency type-fest to v5.3.0 (#21780)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-03 16:54:21 +01:00
renovate[bot] 2676dd64f0 chore(deps): update dependency prettier to v3.7.4 (#21776)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-03 12:32:36 +00:00
renovate[bot] a5c786fe84 chore(deps): update dependency finalhandler to v2.1.1 (#21775)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-03 11:01:49 +00:00
renovate[bot] e20ace541f chore(deps): update dependency @types/express to v5.0.6 (#21773)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-02 17:53:14 +00:00
renovate[bot] 9a0cb698bd chore(base-driver): update dependency express to v5.2.1 (#21772)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-02 13:33:26 +00:00
github-actions[bot]andmykola-mokhnach 7e8cc784c8 docs(appium): Update documentation translations (#21771)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2025-12-01 20:35:21 -08:00
renovate[bot] 69756995c2 chore(base-driver): update dependency express to v5.2.0 [security] (#21769)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-01 21:20:50 +00:00
renovate[bot] 49f8f8a073 chore(execute-driver-plugin): update dependency webdriverio to v9.21.0 (#21768)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-01 20:38:46 +00:00
Sai KrishnaandSrinivasanTarget 83e1cc4e1d docs(appium): Update blog with LT as development partner (#21752)
Co-authored-by: SrinivasanTarget <srinivasan.sekar1990@gmail.com>
2025-12-01 10:20:35 -08:00
renovate[bot] 65bd6faa4a chore(storage-plugin): update dependency lru-cache to v11.2.4 (#21767)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-01 14:56:10 +00:00
renovate[bot] 901e71049c chore(docutils): update dependency yaml to v2.8.2 (#21765)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-01 00:58:00 +00:00
Mykola Mokhnach ecbc7c4879 ci: Use shared workflows (#21766) 2025-11-30 23:13:29 +01:00
renovate[bot] d1eb6856ba chore(deps): update dependency prettier to v3.7.3 (#21764)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-30 13:49:57 +00:00
renovate[bot] d81e682243 chore(deps): update dependency prettier to v3.7.2 (#21763)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-29 14:02:15 +00:00
renovate[bot] 991b4baee2 chore(deps): update dependency lerna to v9.0.3 (#21762)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-28 09:14:10 +00:00
renovate[bot] 54e8ef7764 chore(deps): update dependency prettier to v3.7.1 (#21761)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-27 18:46:33 +00:00
github-actions[bot]andmykola-mokhnach af2701ac4d docs(appium): Update documentation translations (#21760)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2025-11-26 18:09:16 -08:00
renovate[bot] 2235689d93 chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.48.0 (#21751)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-26 19:30:01 +00:00
renovate[bot] c4c895cbdd chore(deps): update dependency @types/lodash to v4.17.21 (#21747)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-26 12:32:36 +00:00
renovate[bot] 18674037bc chore(appium): update dependency @sidvind/better-ajv-errors to v4.0.1 (#21746)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-26 08:50:46 +00:00
github-actions[bot]andmykola-mokhnach 8d0f9017c4 docs(appium): Update documentation translations (#21755)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2025-11-26 08:32:34 +02:00
renovate[bot] aa6a8531e6 chore(base-driver): update dependency body-parser to v2.2.1 [security] (#21754)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-26 04:45:35 +00:00
Dor Blayzer 65a17a1b59 docs: Refine security documentation for clarity (#21749)
* Refine security documentation for clarity

Corrected formatting and phrasing for clarity and consistency throughout the document. Adjusted security feature descriptions and command examples.

* Fix typos in security documentation

* Update security.md for multiple insecure features

Clarified section on enabling multiple insecure features for drivers.

* Update security.md to remove insecure feature examples

Removed examples of insecure feature commands.

* Remove section on multiple insecure features

Removed the section on enabling multiple insecure features for specific drivers.

* Fix formatting of appium command examples in security.md
2025-11-26 00:07:36 +02:00
renovate[bot] c23e45b09d chore(workflows): update peter-evans/create-pull-request action to v7.0.9 (#21748)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-23 14:02:53 +00:00
Mykola Mokhnach 82536ae9d5 ci: Do not presist credentials while doing checkout (#21745) 2025-11-22 08:08:28 +01:00
renovate[bot]andMykola Mokhnach 1034b02925 chore(support): update dependency glob to v13 (#21739)
* chore(support): update dependency glob to v13

* Update lockfile

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Mykola Mokhnach <mokhnach@gmail.com>
2025-11-21 22:35:43 +01:00
renovate[bot] 2fd9cfb6d5 chore(workflows): update actions/checkout action to v6 (#21743)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-21 09:36:23 +02:00
github-actions[bot]andmykola-mokhnach edceebe78d docs(appium): Update documentation translations (#21742)
Co-authored-by: mykola-mokhnach <7767781+mykola-mokhnach@users.noreply.github.com>
2025-11-20 20:10:28 -08:00
renovate[bot]andMykola Mokhnach 73cff7dd31 chore(storage-plugin): update dependency rimraf to v6.1.2 (#21738)
* chore(storage-plugin): update dependency rimraf to v6.1.2

* update lock

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Mykola Mokhnach <mokhnach@gmail.com>
2025-11-20 19:44:11 +01:00
Edgars Eglītis f12fc21dcb chore(deps): fix some npm audit issues (#21737) 2025-11-19 21:58:29 +02:00
renovate[bot] 4658cf60ce chore(execute-driver-plugin): update dependency webdriverio to v9.20.1 (#21735)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-19 12:50:01 +00:00
renovate[bot] 18089f70e4 chore(eslint-config-appium-ts): update dependency typescript-eslint to v8.47.0 (#21734)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-18 19:25:17 +01:00
renovate[bot] a7d19f481f chore(tsconfig): update dependency @tsconfig/node20 to v20.1.8 (#21733)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-18 15:04:39 +00:00
renovate[bot] 9decd8b00c chore(support): update dependency glob to v11.1.0 [security] (#21732)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-18 08:16:01 +00:00
renovate[bot] 968460c1a9 chore(deps): update dependency @types/sinon to v21 (#21730)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-17 12:47:16 +01:00
renovate[bot] 39cca27784 chore(support): update dependency form-data to v4.0.5 (#21729)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-17 12:47:02 +01:00
renovate[bot] 1c0a07c19f chore(support): update dependency teen_process to v3.0.3 (#21725)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-16 14:28:43 +00:00
renovate[bot] 2ceb39df06 chore(eslint-config-appium-ts): update dependency @eslint/compat to v2 (#21718)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-15 21:18:44 +02:00
Edgars Eglītis cabe2e53bc fix(eslint-config-appium-ts): update eslint-plugin-mocha to v11 (#21722) 2025-11-15 20:02:34 +02:00
Kazuaki Matsuo 9c43921ac9 ci: modify contribution post format (#21719)
* chore: modify contribution post format

* modify comment
2025-11-15 09:47:19 -08:00
Mykola Mokhnach 795181ffc2 test(docutils): Add e2e tests (#21721) 2025-11-15 18:23:54 +01:00
renovate[bot]andMykola Mokhnach f01b6fb054 chore(tsconfig): update dependency @tsconfig/node20 to v20.1.7 (#21713)
* chore(tsconfig): update dependency @tsconfig/node20 to v20.1.7

* fix: linter errors

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Mykola Mokhnach <mokhnach@gmail.com>
2025-11-15 13:36:18 +01:00
renovate[bot] a09c85e59e chore(support): update dependency which to v6 (#21720)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-15 12:49:37 +02:00
renovate[bot] 050bad8f12 chore(deps): update dependency @types/yargs to v17.0.35 (#21717)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-15 08:37:55 +00:00
renovate[bot] 38c918711a chore(universal-xml-plugin): update dependency fast-xml-parser to v5.3.2 (#21716)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-15 00:44:07 +00:00
renovate[bot] 982d33e318 chore(deps): update dependency lerna to v9.0.1 (#21715)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-14 18:30:00 +00:00
renovate[bot] 46bd0512d7 chore(deps): update dependency @types/sinon to v20 (#21714)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-14 08:42:26 +02:00
renovate[bot] 4d8189d68a chore(driver-test-support): update dependency chai to v6.2.1 (#21712)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-13 00:43:36 +00:00
renovate[bot] e357a55ebc chore(deps): update dependency @types/node to v24.10.1 (#21711)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-12 18:07:03 +00:00
renovate[bot] 1dff1300e6 chore(docutils): update dependency mkdocs-material to v9.7.0 (#21710)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-11-12 04:33:06 +00:00
654 changed files with 38577 additions and 52093 deletions
+10 -19
View File
@@ -15,10 +15,6 @@ inputs:
description: Whether to run npm run build
required: false
default: 'true'
clear-v8-cache:
description: Whether to clear V8 code cache (for Node.js 24+ compatibility)
required: false
default: 'true'
runs:
using: composite
@@ -28,23 +24,18 @@ runs:
with:
node-version: ${{ inputs.node-version }}
cache: npm
- name: Install dependencies
uses: bahmutov/npm-install@v1
- name: SocketDev Security Check
uses: SocketDev/action@v1
with:
useRollingCache: true
install-command: ${{ inputs.install-command }}
mode: firewall-free
- name: Install dependencies
shell: bash
run: |
# Replace npm with sfw npm in the install command
install_cmd="${{ inputs.install-command }}"
install_cmd="${install_cmd//npm /sfw npm }"
$install_cmd
- name: Build packages
if: ${{ inputs.run-build == 'true' }}
shell: bash
run: npm run build
- name: Clear V8 code cache
if: ${{ inputs.clear-v8-cache == 'true' }}
shell: bash
run: |
# Clear V8 code cache to avoid bytecode deserialization errors
if [[ -d "$HOME/.node" ]]; then
rm -rf "$HOME/.node"/* 2>/dev/null || true
fi
if [[ -d "$HOME/.cache/node" ]]; then
rm -rf "$HOME/.cache/node"/* 2>/dev/null || true
fi
+1 -1
View File
@@ -13,4 +13,4 @@ jobs:
name: Auto-Label PRs
runs-on: ubuntu-latest
steps:
- uses: fuxingloh/multi-labeler@v4
- uses: fuxingloh/multi-labeler@v5
+7 -18
View File
@@ -54,20 +54,14 @@ concurrency:
jobs:
prepare_matrix:
runs-on: ubuntu-latest
outputs:
versions: ${{ steps.generate-matrix.outputs.lts }}
steps:
- name: Select all current LTS versions of Node.js
id: generate-matrix
uses: msimerson/node-lts-versions@v1
uses: appium/appium-workflows/.github/workflows/node-lts-matrix.yml@main
prepare_e2e_packages:
runs-on: ubuntu-latest
outputs:
packages: ${{ steps.discover-packages.outputs.packages }}
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Discover packages with e2e tests
id: discover-packages
run: |
@@ -116,14 +110,13 @@ jobs:
node-version: ${{ fromJSON(needs.prepare_matrix.outputs.versions) }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Setup, install and build
uses: ./.github/actions/setup-build
with:
node-version: ${{ matrix.node-version }}
install-command: npm ci --foreground-scripts
run-build: 'true'
clear-v8-cache: 'true'
- name: Run smoke tests
run: npm run test:smoke
@@ -136,14 +129,13 @@ jobs:
node-version: ${{ fromJSON(needs.prepare_matrix.outputs.versions) }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Setup, install and build
uses: ./.github/actions/setup-build
with:
node-version: ${{ matrix.node-version }}
install-command: npm ci --foreground-scripts
run-build: 'true'
clear-v8-cache: 'true'
- name: Run unit tests
run: npm run test:unit
@@ -156,14 +148,13 @@ jobs:
node-version: ${{ fromJSON(needs.prepare_matrix.outputs.versions) }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Setup, install and build
uses: ./.github/actions/setup-build
with:
node-version: ${{ matrix.node-version }}
install-command: npm ci --foreground-scripts
run-build: 'true'
clear-v8-cache: 'true'
- name: Run type tests
run: npm run test:types
@@ -180,14 +171,13 @@ jobs:
package_dir: ${{ fromJSON(needs.prepare_e2e_packages.outputs.packages) }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Setup, install and build
uses: ./.github/actions/setup-build
with:
node-version: ${{ matrix.node-version }}
install-command: npm ci --foreground-scripts
run-build: 'true'
clear-v8-cache: 'true'
- name: Run E2E tests for ${{ matrix.package_dir }}
run: |
set -o pipefail
@@ -198,13 +188,12 @@ jobs:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Setup and install (no build)
uses: ./.github/actions/setup-build
with:
node-version: lts/*
install-command: npm ci
run-build: 'false'
clear-v8-cache: 'false'
- name: ESLint
run: npm run lint:ci
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: Cleanup
run: |
+2 -2
View File
@@ -21,7 +21,7 @@ jobs:
project_name: appium-inspector
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Use Node.js LTS
uses: actions/setup-node@v6
with:
@@ -36,7 +36,7 @@ jobs:
CROWDIN_PROJECT_ID: ${{ vars[matrix.project_id_var] }}
CROWDIN_TOKEN: ${{ secrets.CROWDIN_DOCS_TOKEN }}
- name: Post to Slack for ${{ matrix.project_name }}
uses: slackapi/slack-github-action@v2.1.1
uses: slackapi/slack-github-action@v3.0.3
with:
errors: true
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
@@ -12,7 +12,9 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
with:
persist-credentials: false
- name: Use Node.js LTS
uses: actions/setup-node@v6
with:
@@ -27,7 +29,7 @@ jobs:
CROWDIN_PROJECT_ID: ${{ vars.CROWDIN_DOCS_PROJECT_ID }}
CROWDIN_TOKEN: ${{ secrets.CROWDIN_DOCS_TOKEN }}
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7.0.8
uses: peter-evans/create-pull-request@v8.1.1
with:
token: ${{ github.token }}
commit-message: 'docs(appium): Update documentation translations'
@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Use Node.js LTS
uses: actions/setup-node@v6
with:
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
steps:
- name: Select all current LTS versions of Node.js
id: generate-matrix
uses: msimerson/node-lts-versions@v1
uses: msimerson/node-lts-versions@v2
check:
needs:
+2 -2
View File
@@ -37,9 +37,9 @@ jobs:
name: Docs
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Install dependencies (Node.js)
uses: bahmutov/npm-install@v1
uses: bahmutov/npm-install@v1.12.1
with:
useRollingCache: true
install-command: npm ci
+2 -2
View File
@@ -13,11 +13,11 @@ jobs:
env:
FOSSA_API_KEY: ${{secrets.FOSSA_API_KEY}}
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
with:
ref: master
- name: Install dependencies
uses: bahmutov/npm-install@v1
uses: bahmutov/npm-install@v1.12.1
- name: Install fossa-cli
run: |
curl -H 'Cache-Control: no-cache' https://raw.githubusercontent.com/fossas/fossa-cli/master/install-latest.sh | bash
+2 -2
View File
@@ -14,7 +14,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Use Node.js LTS
uses: actions/setup-node@v6
with:
@@ -29,7 +29,7 @@ jobs:
# GITHUB_TOKEN is optional - if not provided, uses unauthenticated requests (rate limited)
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Post to Slack
uses: slackapi/slack-github-action@v2.1.1
uses: slackapi/slack-github-action@v3.0.3
with:
errors: true
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
+137
View File
@@ -0,0 +1,137 @@
name: Appium Server Release
on:
workflow_dispatch:
inputs:
dry_run:
description: 'Dry run (no publishing or tagging)'
required: true
type: boolean
default: true
permissions:
contents: write
pull-requests: write
issues: write
id-token: write
jobs:
release:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master' && contains(fromJSON('["mykola-mokhnach", "jlipps", "eglitise", "KazuCocoa"]'), github.actor)
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Configure git user
run: |
git config user.name "github-actions"
git config user.email "github-actions@github.com"
- name: Setup Node and install deps (LTS)
uses: ./.github/actions/setup-build
with:
node-version: lts/*
install-command: npm ci
run-build: 'true'
- name: Run Lerna publish
env:
# for lerna createRelease
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
DRY_RUN: ${{ inputs.dry_run }}
run: |
set -euo pipefail
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
else
echo "Running lerna publish for real"
set +e
release_output="$(npm run release -- --yes 2>&1)"
release_exit_code=$?
set -e
printf '%s\n' "$release_output"
if [ $release_exit_code -eq 0 ]; then
exit 0
fi
if [[ "$release_output" == *"fatal: tag '"*"' already exists"* ]]; then
existing_tag="$(printf '%s\n' "$release_output" | sed -n "s/.*fatal: tag '\\([^']*\\)' already exists.*/\\1/p" | head -n 1)"
if [ -z "$existing_tag" ]; then
echo "Detected existing tag failure, but could not parse tag name"
exit $release_exit_code
fi
echo "Detected existing tag failure for ${existing_tag}; attempting scoped publish recovery from tagged commit"
git fetch --tags --force origin
tagged_commit="$(git rev-list -n 1 "$existing_tag")"
if [ -z "$tagged_commit" ]; then
echo "Tag ${existing_tag} was not found after fetching tags"
exit $release_exit_code
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
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[@]}"
exit $release_exit_code
fi
fi
echo "All publishable workspace package versions are present on npm; treating recovery as successful."
else
echo "Release failed and no known recovery condition matched"
exit $release_exit_code
fi
fi
+41
View File
@@ -0,0 +1,41 @@
# This job only publishes new releases on GitHub and updates the changelog, without publishing to NPM.
# It can be used if the standard release workflow failed and *only* published to NPM.
name: Appium Server Version (Without NPM Publish)
on:
workflow_dispatch:
permissions:
contents: write
pull-requests: write
issues: write
id-token: write
jobs:
version:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/master' && contains(fromJSON('["mykola-mokhnach", "jlipps", "eglitise", "KazuCocoa"]'), github.actor)
steps:
- name: Checkout repository
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Configure git user
run: |
git config user.name "github-actions"
git config user.email "github-actions@github.com"
- name: Setup Node and install deps (LTS)
uses: ./.github/actions/setup-build
with:
node-version: lts/*
install-command: npm ci
run-build: 'true'
- name: Run Lerna version
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx lerna version --exact --yes
+4 -9
View File
@@ -4,12 +4,7 @@ on:
types: [opened, edited, synchronize, reopened]
jobs:
conventional:
name: PR Title
runs-on: ubuntu-latest
steps:
- uses: beemojs/conventional-pr-action@v3
with:
config-preset: angular
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
lint:
uses: appium/appium-workflows/.github/workflows/pr-title.yml@main
with:
config-preset: angular
+22 -28
View File
@@ -1,38 +1,32 @@
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
name: Publish docs
on:
workflow_dispatch:
workflow_run:
workflows: ["Appium Server Release"]
types:
- completed
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v5
- run: |
git config user.name github-actions
git config user.email github-actions@github.com
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies (Node.js)
uses: bahmutov/npm-install@v1
with:
useRollingCache: true
install-command: npm ci
- name: Install dependencies (Python)
run: PIP_BREAK_SYSTEM_PACKAGES=1 pip install -r packages/docutils/requirements.txt
- name: Publish docs
run: |
cd packages/appium
npm run publish:docs
- uses: actions/checkout@v6
- run: |
git config user.name github-actions
git config user.email github-actions@github.com
- name: Setup Node and install deps (LTS)
uses: ./.github/actions/setup-build
with:
node-version: lts/*
install-command: npm ci
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
+2 -2
View File
@@ -23,8 +23,8 @@ jobs:
name: Check Renovate Configs
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@v6
- name: Validate Renovate Config
uses: rinchsan/renovate-config-validator@v0.2.0
uses: rinchsan/renovate-config-validator@v0.2.1
with:
pattern: '{.renovaterc.json,renovate/default.json}'
-10
View File
@@ -1,10 +0,0 @@
module.exports = {
'*.(js|ts)': ['eslint --fix', 'prettier --write'],
'appium-config-schema.js': () => [
'npm run --workspace=./packages/schema build',
'git add -A packages/schema/lib/appium-config.schema.json',
'npm run --workspace=./packages/types build',
'git add -A packages/types/lib/appium-config.ts',
],
'!(package|package-lock)*.json': ['prettier --write'],
};
-48
View File
@@ -1,48 +0,0 @@
## Code of Conduct
### What is this code of conduct for?
Appium is a piece of technology, but **the core of the Appium community is the people in it**. As such, we are committed to providing a friendly, safe and welcoming environment for all, regardless of gender, gender identity and expression, sexual orientation, ability, physical appearance, body size, race, age, socioeconomic status, religion (or lack thereof), or other marginalized aspect of community members. We expect all members of the Appium community to abide by this Code of Conduct whenever interacting in Appium venues (pull requests, GitHub issues, 1-1 or group chat, meetups, conferences, etc...)
### Examples of inappropriate behavior
Because we come from a variety of backgrounds, we don't want to assume that everyone has the same assumptions about what is and isn't appropriate. Here are some examples of inappropriate behavior that are incompatible with our community's ethos:
* Spamming, trolling, intentionally disrupting conversations, or irrelevant solicitation or advertisement
* Making demeaning or discriminatory comments
* Making negative assumptions about someone's background, abilities, or intentions
* Harassing or stalking individuals (online or in person)
* Giving someone unwelcome sexual attention or making unwelcome physical contact (in the case of an IRL event)
* Sharing sexual images or using sexually explicit language
In general: treat others how you would like to be treated, were you in their place. Don't be a jerk. _Do_ ask questions. _Do_ keep conflicts productively focused on technical issues. _Do_ think before you speak; remember that what is perceived as a funny witticism in your group of friends might be hurtful or reinforce hurtful stereotypes in the context of our diverse online community. _Do_ remember that we are all people, not robots, and all equally deserving of sensitivity and respect. (If and when robots join our community, let's treat them with respect too!)
### What will organizers do about inappropriate behavior?
If we notice you doing or saying something inappropriate, an organizer will explain why it's inappropriate and ask you to stop. We won't demonize or vilify you. But please do stop the inappropriate behavior so we can get back to writing and discussing code in a safe environment. If you have philosophical disagreements about what's actually inappropriate, please take them to a separate public or private conversation with an Appium maintainer so we don't turn pull requests into an ethics debate.
If you keep doing unacceptable things, we'll likely ban you, report you to GitHub, or take other appropriate action.
### What if I see or am subject to what feels like inappropriate behavior?
Let us know! Please notify a community organizer as soon as possible. Full contact information is listed in the [Contact Info](#contact-info) section of this document. All communications will be kept strictly confidential, unless otherwise required by law. No issue will be considered too inconsequential or unimportant for us to have a conversation about.
### Contact Info
If you need to report an incident, please contact any of the following organizers directly:
* Isaac Murchie [email](mailto:isaac@saucelabs.com) [twitter](https://twitter.com/imurchie)
* Jonathan Lipps [email](mailto:jlipps@saucelabs.com) [twitter](https://twitter.com/jlipps)
### Credit, License, and Attribution
This Code of Conduct is distributed under a [Creative Commons Attribution-ShareAlike license](http://creativecommons.org/licenses/by-sa/3.0/).
It's inspired among other things by:
* [Citizen Code of Conduct](http://citizencodeofconduct.org/)
* [npmjs](https://www.npmjs.com/policies/conduct)
* [Geek Feminism](http://geekfeminism.wikia.com/wiki/Conference_anti-harassment/Policy)
* [Ashe Dryden](http://www.ashedryden.com/blog/codes-of-conduct-101-faq)
* [Model View Culture](https://modelviewculture.com/issues/events)
* [Open Source & Feelings](http://osfeels.com/conduct).
+4
View File
@@ -50,18 +50,22 @@ The current committers are (along with their primary areas(s) of ownership or ma
* [@dan-maor](https://github.com/Dan-Maor) - XCUITest driver and iOS internals
* [@dor-bl](https://github.com/Dor-bl) - DotNet client
* [@Delta456](https://github.com/Delta456) - appium-mcp, iOS support libraries
* [@eglitise](https://github.com/eglitise) - Appium server, Inspector
* [@harsha509](https://github.com/harsha509) - appium-ios-tuntap
* [@jlipps](https://github.com/jlipps) - Appium server, Inspector
* [@kazucocoa](https://github.com/KazuCocoa) - all Appium projects
* [@laolubenson](https://github.com/laolubenson) - DotNet client
* [@mwakizaka](https://github.com/mwakizaka) - XCUITest driver
* [@mykola-mokhnach](https://github.com/mykola-mokhnach) - all Appium projects
* [@navin772](https://github.com/navin772) - appium-mcp, iOS support libraries
* [@rerorero](https://github.com/rerorero) - XCUITest/UIA2 driver
* [@saikrishna321](https://github.com/saikrishna321) - Java client
* [@srinivasantarget](https://github.com/SrinivasanTarget) - Java client
* [@tomriddly](https://github.com/tomriddly) - appium-ios-device
* [@valfirst](https://github.com/valfirst) - Java client
See [Emeritus Contributors](#emeritus-contributors) below for a list of people who formerly made
significant contributions to the project but are no longer actively committing.
-16
View File
@@ -1,16 +0,0 @@
Google Summer of Code Ideas
=====
Appium is excited to participate as a [Google Summer of Code](https://summerofcode.withgoogle.com/) sponsor project. Here's a fun list of ideas that a Summer of Code student participant can use as a foundation for thinking about what to contribute to Appium!
|Idea|Description|
|----|-----------|
|Apple tvOS Support|Our users have been asking for an Appium driver for Apple tvOS apps. Is this possible? We're not entirely sure! Why not be awesome and build it?|
|Test App revamp|Appium uses a number of poorly-designed mobile applications in its own testing. We have to use a variety of apps because we need to test that Appium can automate all the various controls and platform features that mobile vendors provide. Really what we need is one cross-platform app (or one app per platform) that exhibit all and only the features we need to test. This would be a fun project to build some mobile apps used for testing and also demoing Appium at events and in training videos, etc...|
|Tooling and Performance|We haven't instrumented Appium with very many performance metrics, and don't really know if we're missing some low-hanging fruit in terms of performance. Maybe you can help us do that?|
|Babel|We have a lot of repos, and they're all on a really old version of Babel. They all need to stay in sync. How can we make this situation better, and upgrade to the latest and greatest?|
|Unity3d Driver|Historically, Appium hasn't been great at automating games. We don't have any particular support for the frameworks used to create games. Unity is a popular one, for example. What if we could write an Appium driver that talked to an embedded process in a test version of a Unity game, that allowed us to find and interact with 3d elements? It would be amazing! You can also be amazing and lead Appium into this new world.|
|Testing the Internet of Things|Appium's architecture makes it dead simple to integrate drivers for automating new technologies. What about _really_ new technologies like IoT devices? Help to redefine the semantics of the WebDriver protocol for use with IoT, and build a driver for an IoT device to prove it out.|
|Driver for X|Have an idea of something else Appium could automate that it doesn't already? Build a driver for it! This would involve some awesome Node.js code, plus whatever else is needed to integrate with the platform you have in mind.|
Hopefully this gives you some ideas of fun projects that would be substantial and long-lasting contributions to the Appium community.
+4 -4
View File
@@ -199,11 +199,11 @@ contribution of project development and leadership!
</p>
<p align="center">
<a href="https://lambdatest.com/?utm_source=appium.io&utm_medium=organic&utm_campaign=june_25&utm_term=sk&utm_content=webpage">
<a href="https://www.testmuai.com">
<picture>
<source srcset="packages/appium/docs/overrides/assets/images/sponsor-logo-lambdatest-dark.png" media="(prefers-color-scheme: dark)"/>
<source srcset="packages/appium/docs/overrides/assets/images/sponsor-logo-lambdatest-light.png" media="(prefers-color-scheme: light)"/>
<img src="packages/appium/docs/overrides/assets/images/sponsor-logo-lambdatest-dark.png" width="300" alt="LambdaTest"/>
<source srcset="packages/appium/docs/overrides/assets/images/sponsor-logo-testmuai-dark.png" media="(prefers-color-scheme: dark)"/>
<source srcset="packages/appium/docs/overrides/assets/images/sponsor-logo-testmuai-light.png" media="(prefers-color-scheme: light)"/>
<img src="packages/appium/docs/overrides/assets/images/sponsor-logo-testmuai-dark.png" width="300" alt="TestMu AI (formerly LambdaTest)"/>
</picture>
</a>
</p>
+39 -21
View File
@@ -1,24 +1,42 @@
import tsConfig from '@appium/eslint-config-appium-ts';
import appiumConfig from '@appium/eslint-config-appium-ts';
import {defineConfig, globalIgnores} from 'eslint/config';
export default [
...tsConfig,
{
...tsConfig.find(({name}) => name === 'Test Files'),
name: 'Test Support',
files: [
'packages/test-support/lib/**',
'packages/driver-test-support/lib/**',
'packages/plugin-test-support/lib/**',
],
},
{
name: 'Ignores',
ignores: [
'**/build-fixtures/**',
'packages/appium/docs/**/assets/**',
'packages/appium/docs/**/js/**',
'packages/appium/sample-code/**',
],
},
// Create a modified config subset for test support files:
// Extract the test file related configs (Mocha plugin and custom rules),
// then override their 'files' property (match by name — resilient to new config entries).
const testFileConfigItems = appiumConfig.filter(
(item) => typeof item?.name === 'string' && item.name.startsWith('Test Files'),
);
const testSupportFiles = [
'packages/test-support/lib/**',
'packages/driver-test-support/lib/**',
'packages/plugin-test-support/lib/**',
];
const testSupportConfig = testFileConfigItems.map((item) => ({...item, files: testSupportFiles}));
export default defineConfig([
{
name: 'Base Config',
extends: [appiumConfig],
},
{
name: 'Test Support',
extends: [testSupportConfig],
},
{
name: 'Consistent type-only imports (all packages)',
files: ['**/*.{ts,tsx,mtsx}'],
rules: {
'@typescript-eslint/consistent-type-imports': [
'error',
{ fixStyle: 'separate-type-imports', prefer: 'type-imports' },
],
},
},
globalIgnores([
'**/build-fixtures/**',
'packages/appium/docs/**/assets/**',
'packages/appium/docs/**/js/**',
'packages/appium/sample-code/**',
]),
]);
+2 -1
View File
@@ -14,7 +14,8 @@
"version": {
"conventionalCommits": true,
"createRelease": "github",
"allowBranch": ["master", "appium3"]
"allowBranch": ["master", "appium3"],
"exact": true
}
},
"ignoreChanges": ["**/test/**", "**/*.md"],
+4731 -21753
View File
File diff suppressed because it is too large Load Diff
+35 -38
View File
@@ -57,7 +57,7 @@
"rebuild": "run-s clean build",
"reinstall": "run-s clean clean:deps ci",
"reinstall:angry": "npm run clean:dangerously && npm ci",
"release": "lerna publish",
"release": "lerna publish --exact",
"stage-synced-pkgs": "git add -A packages/appium/README.md \"packages/*/package.json\"",
"start": "appium",
"sync-pkgs": "run-p sync-pkgs:*",
@@ -85,76 +85,73 @@
},
"devDependencies": {
"@colors/colors": "1.6.0",
"@eslint/js": "9.39.1",
"@tsconfig/node20": "20.1.6",
"@eslint/js": "10.0.1",
"@stylistic/eslint-plugin": "5.10.0",
"@tsconfig/node20": "20.1.9",
"@types/argparse": "2.0.17",
"@types/archiver": "7.0.0",
"@types/async-lock": "1.4.2",
"@types/base64-stream": "1.0.5",
"@types/bluebird": "3.5.42",
"@types/chai": "5.2.3",
"@types/chai-as-promised": "8.0.2",
"@types/express": "5.0.5",
"@types/express": "5.0.6",
"@types/jsftp": "2.1.5",
"@types/json-schema": "7.0.15",
"@types/klaw": "3.0.7",
"@types/lockfile": "1.0.4",
"@types/lodash": "4.17.20",
"@types/lodash": "4.17.24",
"@types/method-override": "3.0.0",
"@types/mocha": "10.0.10",
"@types/mv": "2.1.4",
"@types/ncp": "2.0.8",
"@types/node": "24.10.0",
"@types/node": "24.12.4",
"@types/pluralize": "0.0.33",
"@types/semver": "7.7.1",
"@types/serve-favicon": "2.5.7",
"@types/shell-quote": "1.7.5",
"@types/sinon": "17.0.4",
"@types/sinon": "21.0.1",
"@types/sinon-chai": "4.0.0",
"@types/source-map-support": "0.5.10",
"@types/supports-color": "8.1.3",
"@types/teen_process": "2.0.4",
"@types/which": "3.0.4",
"@types/wrap-ansi": "3.0.0",
"@types/ws": "8.18.1",
"@types/xmldom": "0.1.34",
"@types/yargs": "17.0.34",
"asyncbox": "3.0.0",
"chai": "6.2.0",
"@types/yargs": "17.0.35",
"asyncbox": "6.3.0",
"chai": "6.2.2",
"chai-as-promised": "8.0.2",
"conventional-changelog-conventionalcommits": "7.0.2",
"cpy-cli": "6.0.0",
"cpy-cli": "7.0.0",
"cross-env": "10.1.0",
"eslint": "9.39.1",
"eslint": "10.4.0",
"eslint-config-prettier": "10.1.8",
"eslint-import-resolver-typescript": "4.4.4",
"eslint-plugin-import": "2.32.0",
"eslint-plugin-mocha": "10.5.0",
"eslint-plugin-promise": "7.2.1",
"finalhandler": "2.1.0",
"get-port": "5.1.1",
"eslint-plugin-import-x": "4.16.2",
"eslint-plugin-mocha": "11.3.0",
"eslint-plugin-n": "18.0.1",
"eslint-plugin-promise": "7.3.0",
"finalhandler": "2.1.1",
"get-port": "7.2.0",
"json-schema-to-typescript": "15.0.4",
"lerna": "9.0.0",
"log-symbols": "4.1.0",
"lerna": "9.0.7",
"log-symbols": "7.0.1",
"midnight-smoker": "8.0.0",
"mjpeg-consumer": "2.0.0",
"mjpeg-server": "0.3.1",
"mocha": "11.7.5",
"npm-run-all2": "8.0.4",
"prettier": "3.6.2",
"mocha": "11.7.6",
"npm-run-all2": "9.0.1",
"prettier": "3.8.3",
"rewiremock": "3.14.6",
"rimraf": "6.1.0",
"serve-static": "2.2.0",
"sinon": "21.0.0",
"rimraf": "6.1.3",
"serve-static": "2.2.1",
"sinon": "22.0.0",
"sinon-chai": "4.0.1",
"sync-monorepo-packages": "1.0.2",
"teen_process": "3.0.2",
"teen_process": "4.1.3",
"ts-node": "10.9.2",
"tsd": "0.33.0",
"typescript": "5.9.3",
"typescript-eslint": "8.46.4",
"webdriverio": "9.20.0",
"ws": "8.18.3",
"yaml-js": "0.3.1"
"typescript": "6.0.3",
"typescript-eslint": "8.60.0",
"webdriverio": "9.27.2",
"ws": "8.21.0"
},
"engines": {
"node": "^20.19.0 || ^22.12.0 || >=24.0.0",
@@ -165,10 +162,10 @@
},
"overrides": {
"@sidvind/better-ajv-errors": {
"ajv": "8.17.1"
"ajv": "8.20.0"
},
"ajv-formats": {
"ajv": "8.17.1"
"ajv": "8.20.0"
},
"http-cache-semantics": "4.2.0"
}
+101
View File
@@ -3,6 +3,107 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.5.0](https://github.com/appium/appium/compare/appium@3.4.2...appium@3.5.0) (2026-05-31)
### Features
* add IPC channels per session for drivers and plugins to communicate ([#22211](https://github.com/appium/appium/issues/22211)) ([97c879c](https://github.com/appium/appium/commit/97c879cdd02e6fcccaaea45a8d1a7088bed4ae66)), closes [#22206](https://github.com/appium/appium/issues/22206)
* **appium:** Ditch bluebird ([#22301](https://github.com/appium/appium/issues/22301)) ([abb83bd](https://github.com/appium/appium/commit/abb83bde62e8beefdd9483a276ef2aa888722245))
* Limit the maximum count of topics per session and make it configurable ([#22279](https://github.com/appium/appium/issues/22279)) ([0264775](https://github.com/appium/appium/commit/0264775ecb8ecaca9dac2eae47784da02a653255))
* make assignIpc internal ([#22278](https://github.com/appium/appium/issues/22278)) ([25d922b](https://github.com/appium/appium/commit/25d922b7d3062c306c1631d6f5c227600ddd226a))
## [3.4.2](https://github.com/appium/appium/compare/appium@3.4.1...appium@3.4.2) (2026-05-07)
**Note:** Version bump only for package appium
## [3.4.1](https://github.com/appium/appium/compare/appium@3.4.0...appium@3.4.1) (2026-05-06)
**Note:** Version bump only for package appium
## [3.4.0](https://github.com/appium/appium/compare/appium@3.3.1...appium@3.4.0) (2026-05-06)
### Features
* add 3 WebDriver extension endpoints ([#22237](https://github.com/appium/appium/issues/22237)) ([787571d](https://github.com/appium/appium/commit/787571d33836c06bb1332d7bc6cc2f9800bbdd82))
## [3.3.1](https://github.com/appium/appium/compare/appium@3.3.0...appium@3.3.1) (2026-04-23)
### Bug Fixes
* **appium:** lint warnings ([#22171](https://github.com/appium/appium/issues/22171)) ([8e68b3e](https://github.com/appium/appium/commit/8e68b3e2c9c7b6238e0ffc241adbd4d9991ead7a))
* **appium:** plugins caching per session ([#22203](https://github.com/appium/appium/issues/22203)) ([622f199](https://github.com/appium/appium/commit/622f1999d72d2f7ebc7cc279879ea0fcefe29a54))
## [3.3.0](https://github.com/appium/appium/compare/appium@3.2.2...appium@3.3.0) (2026-04-09)
### Features
* use exact version for dependencies in monorepo packages instead of ^ ([#22090](https://github.com/appium/appium/issues/22090)) ([86c8f23](https://github.com/appium/appium/commit/86c8f23a670d0bbc2d359a8235828606bd36e6aa))
## [3.2.2](https://github.com/appium/appium/compare/appium@3.2.1...appium@3.2.2) (2026-03-09)
### Bug Fixes
* **appium:** Exclude package.json from tsconfig ([#22052](https://github.com/appium/appium/issues/22052)) ([1d89e2a](https://github.com/appium/appium/commit/1d89e2a5f8e478f3331666d3c308427ab834471a))
## [3.2.1](https://github.com/appium/appium/compare/appium@3.2.0...appium@3.2.1) (2026-03-08)
### Bug Fixes
* **appium:** Fix CLI arguments normalization ([#21945](https://github.com/appium/appium/issues/21945)) ([9ea601c](https://github.com/appium/appium/commit/9ea601c8330d35f45f0712e41867544d925a0f6b))
* Avoid attaching plugins to a non-existing session ([#21964](https://github.com/appium/appium/issues/21964)) ([9f5faf5](https://github.com/appium/appium/commit/9f5faf5bedffe6196742c09c6793a6450af48ac9))
* **logger:** Make sure we always have single logger instance per process ([#21991](https://github.com/appium/appium/issues/21991)) ([4daaa14](https://github.com/appium/appium/commit/4daaa14c29bed129d329d0881a93ecdb9de77676))
* Type imports ([#22025](https://github.com/appium/appium/issues/22025)) ([2f27425](https://github.com/appium/appium/commit/2f27425ea300ca1af1c1da6e4be68d48e7a94346))
## [3.2.0](https://github.com/appium/appium/compare/appium@3.1.2...appium@3.2.0) (2026-01-26)
### Features
* **appium:** Add repository links to verbose extensions list ([#21813](https://github.com/appium/appium/issues/21813)) ([ce91686](https://github.com/appium/appium/commit/ce91686852b0baab5f46990f5d40db4747922924))
### Bug Fixes
* **appium:** appium symlink behavior across drivers/plugins installations ([#21837](https://github.com/appium/appium/issues/21837)) ([529aeb4](https://github.com/appium/appium/commit/529aeb48f10419e21555cec05835ff07bb0e2e51))
* apply npm run lint:fix ([#21867](https://github.com/appium/appium/issues/21867)) ([5e28714](https://github.com/appium/appium/commit/5e28714442cf59ee35b085e01e82c3f5483891fd))
* **docs:** add missing verbose flag for CLI list command ([#21814](https://github.com/appium/appium/issues/21814)) ([dcfaa88](https://github.com/appium/appium/commit/dcfaa88830f6a5c608c92f5ae72445e065261d38))
## [3.1.2](https://github.com/appium/appium/compare/appium@3.1.1...appium@3.1.2) (2025-12-04)
**Note:** Version bump only for package appium
## [3.1.1](https://github.com/appium/appium/compare/appium@3.1.0...appium@3.1.1) (2025-11-12)
+4 -4
View File
@@ -199,11 +199,11 @@ contribution of project development and leadership!
</p>
<p align="center">
<a href="https://lambdatest.com/?utm_source=appium.io&utm_medium=organic&utm_campaign=june_25&utm_term=sk&utm_content=webpage">
<a href="https://www.testmuai.com">
<picture>
<source srcset="packages/appium/docs/overrides/assets/images/sponsor-logo-lambdatest-dark.png" media="(prefers-color-scheme: dark)"/>
<source srcset="packages/appium/docs/overrides/assets/images/sponsor-logo-lambdatest-light.png" media="(prefers-color-scheme: light)"/>
<img src="packages/appium/docs/overrides/assets/images/sponsor-logo-lambdatest-dark.png" width="300" alt="LambdaTest"/>
<source srcset="packages/appium/docs/overrides/assets/images/sponsor-logo-testmuai-dark.png" media="(prefers-color-scheme: dark)"/>
<source srcset="packages/appium/docs/overrides/assets/images/sponsor-logo-testmuai-light.png" media="(prefers-color-scheme: light)"/>
<img src="packages/appium/docs/overrides/assets/images/sponsor-logo-testmuai-dark.png" width="300" alt="TestMu AI (formerly LambdaTest)"/>
</picture>
</a>
</p>
+3 -1
View File
@@ -3,7 +3,9 @@ site_name: Appium Documentation
repo_url: https://github.com/appium/appium
repo_name: appium/appium
edit_uri: edit/master/packages/appium/docs
copyright: Copyright &copy; 2012 OpenJS Foundation - <a href="#__consent">Change cookie settings</a>
copyright: |
<p>Copyright <a href="https://openjsf.org">OpenJS Foundation</a> and Appium contributors. All rights reserved. The <a href="https://openjsf.org">OpenJS Foundation</a> has registered trademarks and uses trademarks. For a list of trademarks of the <a href="https://openjsf.org">OpenJS Foundation</a>, please see our <a href="https://trademark-policy.openjsf.org">Trademark Policy</a> and <a href="https://trademark-list.openjsf.org">Trademark List</a>. Trademarks and logos not indicated on the <a href="https://trademark-list.openjsf.org">list of OpenJS Foundation trademarks</a> are trademarks&trade; or registered&reg; trademarks of their respective holders. Use of them does not imply any affiliation with or endorsement by them.</p>
<p><a href="https://openjsf.org">The OpenJS Foundation</a> | <a href="https://terms-of-use.openjsf.org">Terms of Use</a> | <a href="https://privacy-policy.openjsf.org">Privacy Policy</a> | <a href="https://bylaws.openjsf.org">Bylaws</a> | <a href="https://code-of-conduct.openjsf.org">Code of Conduct</a> | <a href="https://trademark-policy.openjsf.org">Trademark Policy</a> | <a href="https://trademark-list.openjsf.org">Trademark List</a> | <a href="https://www.linuxfoundation.org/cookies">Cookie Policy</a></p><a href="#__consent">Change cookie settings</a>
theme:
logo: assets/images/appium-logo-white.png
@@ -0,0 +1,36 @@
---
authors:
- sai
- srini
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 -->
<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" />
</a>
</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.
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
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!
@@ -10,7 +10,7 @@ maintenance, and support from companies and volunteers. As such, we welcome cont
There are a lot of different ways to help the project - see below for everything you can do and the
processes to follow for each contribution method. Note that no matter how you contribute, your
participation is governed by our [Code of Conduct](https://github.com/appium/appium/blob/master/CONDUCT.md).
participation is governed by our [Code of Conduct](https://github.com/appium/.github/blob/master/CODE_OF_CONDUCT.md).
## Join the Discussion Forum
@@ -568,6 +568,33 @@ capability), and then to set an internal field to that value, so that it can be
bidiProxyUrl`. Once all this is in place, Appium will proxy BiDi commands from the client straight
to the upstream connection.
### Understand server-assigned driver properties and security flags
When your driver is running under the main Appium server, Appium assigns a small set of
server-related properties on your driver instance when a session is created:
- `cliArgs`: Driver-specific configuration derived from the Appium server’s CLI flags and/or
configuration files (for example via the `server.driver.<your-driver-name>` section). These
options are **not** user capabilities and cannot be influenced directly by test code.
- `server`, `serverHost`, `serverPort`, `serverPath`: Information about the HTTP server that is
hosting your driver. These values reflect how the Appium server was started (for example the
`--address`, `--port`, and `--base-path` flags) and are useful when your driver needs to construct
URLs that point back to the Appium server itself (for example when setting up proxies, webhooks,
or other callbacks).
`BaseDriver` and `AppiumDriver` also cooperate to expose security-related flags on your driver
instance:
- `relaxedSecurityEnabled`: Indicates whether the server is running with relaxed security enabled
(for example via `--relaxed-security`).
- `allowInsecure`: A list of insecure features which are explicitly allowed for this driver (derived
from server-level options like `--allow-insecure`).
- `denyInsecure`: A list of insecure features which are explicitly disabled for this driver (derived
from server-level options like `--deny-insecure`).
See [Hide behaviour behind security flags](#hide-behaviour-behind-security-flags) for how to use
these flags in your driver (e.g. via `isFeatureEnabled` and `assertFeatureEnabled`).
### Extend the existing protocol with new commands
You may find that the existing commands don't cut it for your driver. If you want to expose
@@ -858,3 +885,118 @@ this.onUnexpectedShutdown(handler)
`handler` should be a function which receives an error object (representing the reason for the
unexpected shutdown).
### Send messages to plugins running on the same session
Appium's driver and plugin architecture means that a single driver and any number of plugins can be
running together for a current session. The driver and plugins don't really know anything about
each other though, which can make coordination potentially difficult. Without creating any kind of
tight coupling between drivers or plugins, it's possible for drivers and plugins to communicate
along a pub/sub style message bus. With Appium's IPC feature, "message" means a combination of
"data" (the data intended to be published or received), and metadata (timestamp, the name of the
publisher, etc...).
Drivers and plugins can implement an instance method called `async onIpcInit`, in which they will
know that the IPC channel for the session is now active. At this point, they have access to the
following methods:
#### `ipcSubscribe<T>(topic: string): IIpcSubscription`
This method allows a driver or plugin to subscribe to a topic on the IPC channel for the session.
Topics are simply strings. To coordinate effectively, drivers or plugins would use the same topic
string (so this would be something advertised in the driver/plugin documentation).
The result of this call is an `IpcSubscription` object that allows:
- Looping through messages on the topic via an async generator
- Hooking up an event handler for new messages
- Getting the last message sent on the topic
- Publishing a message to the topic
- Unsubscribing from the topic
#### `IpcSubscription` object
Here is an example of how subscribing and use of these subscription methods might work:
```ts
async onIpcInit() {
// we know at this point in our driver/plugin lifecycle that we can use IPC methods
type MyMessageData = {myData: string}; // let's say the message data for this channel has this shape
const subscription = this.ipcSubscribe<MyMessageData>('coolTopic');
// listen for new messages on topic
subscription.on('message', (message) => {
console.log(message.data); // {myData: 'something'}
});
// publish data to the topic; might throw if the data is larger than configured max size, or we
// are no longer subscribed
await subscription.publish({myData: 'hi'});
// get last message sent to topic
const {data} = subscription.getMessage() ?? {data: null};
// data = {myData: 'hi'}
// unsubscribe
subscription.unsubscribe(); // returns true if we unsubscribed and false if no subscription existed
}
```
With a subscription object, we can also iterate async over it to receive new messages:
```ts
for await (const message of subscription) {
// here we have a message and can unwrap its data
}
```
Note that the iteration will stop when the subscription ends (i.e., when `unsubscribe` is called).
You can also check whether the subscription is still active (if your subscribe and unsubscribe
logic is not locally connected):
```ts
if (subscription.isActive) {
// we know we have not yet unsubscribed
}
```
If the subscription is not active, attempts to call `subscription.publish` will throw an error.
#### `IpcMessage` object
When you get a message on a topic, it has the following shape:
```ts
export type IpcMessage<T> = {
publisher: string, // the id of the publishing object (typically of the form <ClassName>@<uniqueObjectId>)
timestampMs: number, // when the message was published, in ms since epoch
topic: string, // the topic the message was published on
data: T, // the arbitrary message data. Must be serializable and a valid argument to 'structuredClone()'
};
```
#### IPC Notes
There are some important things to keep in mind when using Appium's IPC feature:
- IPC is only available once `onIpcInit` has been called, at the end of the `createSession` flow.
It cannot be used statically or in `createSession` hooks
- In sum, IPC is only for use during a session (this is also to prevent drivers/plugins from
accessing or reading data sent on IPC channels in other sessions.)
- The default max size of an IPC message is 1MB. This can be configured by the server-admin by
using the `--max-ipc-data-size` arg (value is a number in bytes).
- If a message exceeds the configured size, any call to `publish` methods will throw, so be
sure to cover this case in your error handling.
- The default max number of IPC topics per session is 1000. This can be configured by the
server-admin using the `--max-ipc-topics` arg.
- If the topic limit is reached, calls to `subscribe` or `publish` on a new topic will throw, so
be sure to cover this case in your error handling.
- Topic names exist within a global namespace per session. So if you don't want to clash with other
drivers or plugins, make sure you prefix your topic names with something unique, akin to vendor
prefixes in the WebDriver standard (for example: `fake-driver:some-topic`). We recommend the
format `<namespace>:<topic>`.
To see examples of IPC in action, check out Appium's own
[FakeDriver](https://github.com/appium/appium/blob/master/packages/fake-driver/lib/driver.ts) and
[FakePlugin](https://github.com/appium/appium/blob/master/packages/fake-plugin/lib/plugin.ts)
extensions, which showcase several ways of using IPC messages.
@@ -512,3 +512,12 @@ async onUnexpectedShutdown(driver, cause) {
}
}
```
### Send messages to the driver or other plugins running on the same session
Even though drivers and plugins don't know anything about each other, it's possible for them to
send messages that other drivers or plugins can listen for, within the context of the same session,
using an IPC channel. Given that the developer instructions for this feature are the same for
drivers and plugins, please head over to the [IPC development docs for
drivers](./build-drivers.md#send-messages-to-plugins-running-on-the-same-session) at the driver
development guide.
@@ -30,7 +30,7 @@ In lieu of a separate file, configuration can be embedded in a project's `packag
```
When an Appium server is started via the `appium` executable, the `init` function in `lib/main.js`
will call into `lib/config-file.js` to load and/or search for a configuration file and in
will call into `lib/bootstrap/config-file.js` to load and/or search for a configuration file and in
`package.json`.
!!! note
@@ -69,7 +69,7 @@ It is more straightforward to explain how config files are validated, so we'll s
### Validating Config Files
When a config file is found (`lib/config-file.js`), it will call the `validate` function exported
When a config file is found (`lib/bootstrap/config-file.js`), it will call the `validate` function exported
from `lib/schema/schema.js` with the contents of the config file. In turn, this asks `ajv` to
validate the data against the schema that Appium has provided it.
+50 -27
View File
@@ -19,6 +19,43 @@ Appium has a graphical client which can be used to inspect application screensho
application hierarchy, search for elements, run Appium commands, record app interactions, and more.
It can be very useful for Appium test development.
=== "Install as an Appium Plugin"
```bash
appium plugin install inspector
```
=== "Install Standalone"
Download the app from the Appium Inspector repo's [GitHub Releases section](https://github.com/appium/appium-inspector/releases).
### [Appium MCP](https://github.com/appium/appium-mcp)
Appium MCP is a Model Context Protocol (MCP) server that provides mobile test development and
automation capabilities using Appium.
```json title="Install This Tool"
// Add the following to your MCP client configuration
{
"appium-mcp": {
"disabled": false,
"timeout": 100,
"type": "stdio",
"command": "npx",
"args": ["appium-mcp@latest"],
"env": {
"ANDROID_HOME": "/path/to/android/sdk"
}
}
}
```
### [Skills](https://github.com/appium/skills)
A set of AI Agent skills to support Appium automation, for example:
- Help preparing Appium test environment from scratch, including common driver setup
- Help preparing XCUITest driver and WebDriverAgent for real device automation
## Extension Tools
Appium driver or plugin developers can choose to include these tools in their driver/plugin:
@@ -33,7 +70,7 @@ details needed for the driver/plugin have been set up correctly. The tool can be
appium {driver|plugin} doctor <extension-name>
```
It shows no results if the driver/plugin author did not implement Doctor support.
It shows no results if the driver/plugin does not have such validation checks.
!!! note
@@ -44,6 +81,18 @@ It shows no results if the driver/plugin author did not implement Doctor support
These tools are not maintained by the Appium team:
### [AppClaw](https://github.com/AppiumTestDistribution/AppClaw)
AppClaw is a CLI-based agentic AI layer for mobile automation, powered by [Appium MCP](#appium-mcp).
Agent instructions can be passed directly via CLI, or defined as YAML flows in either structured
or natural language syntax.
Supported by: `@AppiumTestDistribution`
```sh title="Install This Tool"
npm install -g appclaw
```
### [Appium Installer](https://github.com/AppiumTestDistribution/appium-installer)
Appium Installer is a command-line tool for simplifying setups of new Appium test environments.
@@ -55,29 +104,3 @@ Supported by: `@AppiumTestDistribution`
```sh title="Install This Tool"
npm install -g appium-installer
```
### [Jarvis Appium](https://github.com/AppiumTestDistribution/mcp-appium)
Jarvis Appium is a Model Context Protocol (MCP) server that provides mobile test development and
automation capabilities using Appium.
Supported by: `@AppiumTestDistribution`
```json title="Install This Tool"
// Add the following to your MCP client configuration
{
"mcpServers": {
"jarvis-appium": {
"disabled": false,
"timeout": 100,
"type": "stdio",
"command": "npx",
"args": ["jarvis-appium"],
"env": {
"ANDROID_HOME": "/path/to/android/sdk",
"CAPABILITIES_CONFIG": "/path/to/your/capabilities.json"
}
}
}
}
```
+50 -54
View File
@@ -2,14 +2,14 @@
title: Session Capabilities
---
"Capabilities" is the name given to the set of parameters used to start an Appium session. The
information in the set describes what sort of "capabilities" you want your session to have, for
example, a certain mobile operating system or a certain version of a device. Capabilities are
represented as key-value pairs, with values allowed to be any valid JSON type, including
other objects.
Capabilities are the core parameters used to start an Appium session. They describe various
features that you want your session to have, for example, a certain mobile operating system or a
certain version of a device. Capabilities are represented as key-value pairs, with values allowed
to be any valid JSON type, including other objects. Most importantly, they cannot be changed
during the lifecycle of the session.
The W3C WebDriver spec's [section on Capabilities](https://w3c.github.io/webdriver/#capabilities)
identifies a small set of 10 standard capabilities, including the following:
The capabilities used in Appium follow [the W3C WebDriver specification of the same name](https://w3c.github.io/webdriver/#capabilities).
The WebDriver spec defines a small set of standard capabilities, including the following:
| Capability Name | Type | Description |
|------------------|----------|------------------------------------------------|
@@ -17,65 +17,62 @@ identifies a small set of 10 standard capabilities, including the following:
| `browserVersion` | `string` | The specific version of the browser |
| `platformName` | `string` | The type of platform hosting the browser |
While the above capabilities are commonly used by Appium drivers, they are not sufficient for
describing Appium-specific features, such as the name of the driver to use, or the name of the app
to launch. In order to achieve this, Appium defines its own [extension capabilities](https://w3c.github.io/webdriver/#dfn-extension-capability).
## Common Appium Capabilities
Appium understands these browser-focused capabilities, but introduces a number of additional
capabilities. According to the WebDriver spec, any
non-standard "extension capabilities" must include a namespace prefix (signifying the vendor
introducing the capability), ending in a `:`. Appium's vendor prefix is
`appium:`, and so any Appium-specific capabilities must include this prefix. Depending on which
client you are using, 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.
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
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.
Here is a list of all the globally-recognized Appium capabilities:
Here are a few commonly (but not universally!) used Appium-specific capabilities:
!!! info
| Capability Name | Type | Description |
|-------------------------|----------|-----------------------------------------------------------------|
| `appium:automationName` | `string` | The name of the Appium driver to use |
| `appium:udid` | `string` | The unique device identifier of a particular device to automate |
| `appium:app` | `string` | The path to an installable application |
Individual drivers and plugins can support other capabilities, so refer to their documentation
for lists of specific capability names. Some drivers may also not support all of these capabilities
All capabilities recognized by the Appium base driver (inherited by all drivers) can be found in the
[Capabilities Reference document](../reference/session/caps.md). While this common capability set
is fairly small, it can be greatly extended by Appium drivers and plugins, who can (and should)
define their own capabilities. Make sure to reference their documentation to learn more about the
capabilities they support. You can find a list of known drivers in the [Ecosystem Drivers](../ecosystem/drivers.md) document.
| <div style="width:12em">Capability</div> | Type | Required? | Description |
|--------------------------------------------|-----------|-----------|----------------------------|
| `platformName` | `string` | yes | The type of platform hosting the app or browser |
| `appium:automationName` | `string` | yes | The name of the Appium driver to use |
| `browserName` | `string` | no | The name of the browser to launch and automate, if the driver supports web browsers as a special case |
| `appium:app` | `string` | no | The path to an installable application |
| `appium:deviceName` | `string` | no | The name of a particular device to automate, e.g., `iPhone 14` (currently only actually useful for specifying iOS simulators, since in other situations it's typically recommended to use a specific device id via the `appium:udid` capability). |
| `appium:platformVersion` | `string` | no | The version of a platform, e.g., for iOS, `16.0` |
| `appium:newCommandTimeout` | `number` | no | The number of seconds the Appium server should wait for clients to send commands before deciding that the client has gone away and the session should shut down. `60` seconds by default. Setting it to zero disables the timer. |
| `appium:noReset` | `boolean` | no | If true, instruct an Appium driver to avoid its usual reset logic during session start and cleanup (default `false`) |
| `appium:fullReset` | `boolean` | no | If true, instruct an Appium driver to augment its usual reset logic with additional steps to ensure maximum environmental reproducibility (default `false`) |
| `appium:eventTimings` | `boolean` | no | If true, instruct an Appium driver to collect [Event Timings](./event-timing.md) (default `false`) |
| `appium:printPageSourceOnFindFailure` | `boolean` | no | If true, collect the page source and print it to the Appium log whenever a request to find an element fails (default `false`) |
Drivers are also able to place more complex constraints on capabilities as a group. For example,
the XCUITest driver recommends that at least one of `browserName`, `appium:app`, or `appium:bundleId`
is included in the capabilities, otherwise it will not be able to auto-install or auto-launch any
application. Each driver will document how it interprets these capabilities and any other
platform-specific requirements.
Some drivers place more complex constraints on capabilities as a group. For example, while the
`appium:app` and `browserName` capabilities are listed above as optional, if you want to launch
a session with a specific app, the XCUITest driver requires that at least one of `appium:app`,
`browserName`, or `appium:bundleId` are included in the capabilities (otherwise it will not know
what app to install and/or launch and will simply open a session on the home screen). Each driver
will document how it interprets these capabilities and any other platform-specific requirements.
The way to construct capabilities and start a session will likely differ depending on your Appium
client. For examples of doing this in each client library, head to the [Ecosystem Clients](../ecosystem/clients.md)
page and click through to the appropriate client documentation.
!!! note
Capabilities are like parameters used when starting a session. After the capabilities are sent
and the session is started, they cannot be changed. If a driver supports updating aspects of
its behaviour in the course of a session, it will provide a [Setting](./settings.md) for this
purpose instead of, or in addition to, a capability.
Each Appium client has its own way of constructing capabilities and starting a session. For
examples of doing this in each client library, head to the [Ecosystem](../ecosystem/index.md) page
and click through to the appropriate client documentation.
Once your capabilities are sent to the server and the session is started, they cannot be
changed. If a driver supports updating its behaviour during a session, it will use the
[Settings API](./settings.md) for this purpose.
## BiDi Protocol Support
Appium supports [WebDriver BiDi](https://w3c.github.io/webdriver-bidi/) protocol since base–driver 9.5.0.
The actual behavior depends on individual drivers while the Appium and the baseーdriver support the protocol.
Please make sure if a driver supports the protocol and what kind of commands/events it supports in the documentation.
In addition to the standard WebDriver protocol (now known as WebDriver Classic), Appium supports the
[WebDriver BiDi](https://w3c.github.io/webdriver-bidi/) protocol. Support for this protocol is
opt-in, and requires the use of the standard `webSocketUrl` capability.
| Capability Name | Type | Description |
|-----------------|-----------|-----------------------------------------|
| `webSocketUrl` | `boolean` | To enable BiDi protocol in the session. |
| Capability Name | Type | Description |
|-----------------|-----------|--------------------------------------------------|
| `webSocketUrl` | `boolean` | Whether BiDi protocol is enabled in the session |
All BiDi commands supported by the Appium base driver (inherited by all drivers) can be found in the
[BiDi Protocol API Reference document](../reference/api/bidi.md). Similarly to WebDriver Classic
commands, individual Appium drivers and plugins can define their own supported standard and custom
BiDi commands, so make sure to reference their documentation.
## Using `appium:options` to Group Capabilities
@@ -118,8 +115,7 @@ creates in response to a new session request. This is through the concept of "al
!!! note
Check out the [spec itself](https://w3c.github.io/webdriver/#processing-capabilities) or
a [summarized version](https://github.com/jlipps/simple-wd-spec#processing-capabilities) for
Check out the [spec itself](https://w3c.github.io/webdriver/#processing-capabilities) for
a more in-depth description of how capabilities are processed.
In practice, use of first-match capabilities is not necessary or recommended for use with Appium.
+33 -35
View File
@@ -3,27 +3,27 @@ title: Appium Server Security
---
The Appium team makes every effort to ensure the security of the Appium server. This is especially
important when Appium is run in a multitenant environment, or when multiple users are running
sessions on the same Appium server. In general, you can only safely enable all Appium's features if
all the following are true:
important when Appium is run in a multi-tenant environment, or when multiple users are running
sessions on the same Appium server. To ensure a safe environment for Appium's purposes, all of the
following should be true:
- You're running your own Appium server locally or within a protected internal network
- You're not sharing it with any untrusted parties
- You don't expose Appium's port(s) to the wider internet
But because many Appium users might not be able to guarantee such a safe environment, the Appium
team puts many features behind a security protection mechanism which forces system admins (the
people that are in charge of starting the Appium server) to _explicitly opt-in_ to these features.
(Third-party driver and plugin authors can also [hide behaviour behind security
flags](../developing/build-drivers.md).)
But because not all Appium hosts can guarantee such a safe environment, certain insecure Appium
features are disabled by default, and require explicit opt-in in order to enable them. Most
importantly, this can _only_ be done by the Appium server _host_, and Appium _client_ sessions are
not allowed to change this.
For security reasons, Appium client sessions can _not_ request feature enablement via capabilities;
this is the responsibility of the server admin who configures and launches the Appium server.
While it is possible for an Appium host to simply enable all insecure features at once, each
feature also has a unique name, which can be used for granular control over the server state.
## Security Server Args
The [Server CLI](../reference/cli/server.md) doc outlines three relevant arguments which may be passed to
Appium when starting it from the command line:
Enabling or disabling insecure features is done via [Appium server launch arguments](../reference/cli/server.md)
or [configuration file](./config.md). The former document outlines three relevant arguments for
achieving this:
|<div style="width:10em">Parameter</div>|Description|
|---------------------------------------|-----------|
@@ -31,36 +31,28 @@ Appium when starting it from the command line:
|`--allow-insecure`|Turns on _only_ specified features, except those blocked by `--deny-insecure`. Has no effect when used in combination with `--relaxed-security`|
|`--deny-insecure`|Explicitly turns _off_ specified features, overriding `--relaxed-security` and `--allow-insecure`|
All of the above arguments can also be specified in the [Appium Configuration file](./config.md).
Features passed to `--allow-insecure`/`--deny-insecure` must be specified as a comma-separated list,
and each feature in the list must additionally include a prefix, indicating the driver to which the
feature should apply. The prefix can be either the driver's `automationName`, or the wildcard (`*`)
symbol, if the feature should be applied to all drivers. The prefix and feature name are separated
using the colon character (`:`).
and each feature in the list must additionally include a prefix, indicating the driver to whose
sessions the feature should apply. The prefix can be either the driver's `automationName`, or the
wildcard (`*`) symbol, if the feature should be applied to all drivers. The prefix and feature name
are separated using the colon character (`:`).
For example, `first:foo` refers to the `foo` feature for the `first` driver, whereas `*:bar` refers
to the `bar` feature for all drivers.
## Insecure Features
Each Appium driver is responsible for its own security, and can create its own feature names. Thus
you should read through the documentation for a particular driver to know which feature names it
might use. Here is an incomplete list of examples from some of Appium's official drivers:
Almost all insecure features are defined on a per-driver or plugin basis, so make sure to read the
documentation for a particular driver/plugin to know which feature names it might use.
|<div style="width:12em">Feature Name</div>|Description|Supported Extension(s)|
|------------|-----------|-------|
|`get_server_logs`|Allows retrieving of Appium server logs via the Webdriver log interface|IOS, XCUITest, Android, UiAutomator2, Espresso|
|`adb_shell`|Allows execution of arbitrary shell commands via ADB, using the `mobile: shell` command|Android, UiAutomator2, Espresso|
|`record_audio`|Allow recording of host machine audio inputs|XCUITest|
|`execute_driver_script`| Allows to send a request which has multiple Appium commands.|Execute Driver Plugin|
Certain insecure features are also defined on the Appium server itself. For a list of these
features, as well as the features defined in official plugins, see
[the Insecure Features CLI Reference](../reference/cli/insecure-features.md) doc.
Some insecure features operate on the server level, and do not require a driver session. Enabling
these features requires using the wildcard prefix:
!!! note
|<div style="width:12em">Feature Name</div>|Description|
|------------|-----------|
|`session_discovery`|Allows retrieving the list of active server sessions via `GET /appium/sessions`|
If you are a driver or plugin author and want to implement insecure features of your own, check
out the [Building Drivers documentation](../developing/build-drivers.md#understand-server-assigned-driver-properties-and-security-flags).
## Examples
@@ -73,17 +65,23 @@ appium --allow-insecure=first:foo
Turn on the `foo` feature for all drivers:
```bash
appium --allow-insecure=*:foo
appium --allow-insecure='*:foo'
```
Turn on the `foo` feature for all drivers _except_ `first`:
```bash
appium --allow-insecure=*:foo --deny-insecure=first:foo
appium --allow-insecure='*:foo' --deny-insecure=first:foo
```
Turn on all features _except_ `foo` for all drivers:
```bash
appium --relaxed-security --deny-insecure=*:foo
appium --relaxed-security --deny-insecure='*:foo'
```
Turn on multiple insecure features for specific drivers:
```bash
appium --allow-insecure=uiautomator2:adb_shell,xcuitest:get_server_logs
```
+3 -3
View File
@@ -34,9 +34,9 @@ Android TV, Samsung), and more!
</a>
</div>
<div class="homepageSponsor">
<a href="https://lambdatest.com/?utm_source=appium.io&utm_medium=organic&utm_campaign=june_25&utm_term=sk&utm_content=webpage">
<img src="assets/images/sponsor-logo-lambdatest-dark.png#only-dark" style="width: 220px;" />
<img src="assets/images/sponsor-logo-lambdatest-light.png#only-light" style="width: 220px;" />
<a href="https://www.testmuai.com">
<img src="assets/images/sponsor-logo-testmuai-dark.png#only-dark" style="width: 220px;" />
<img src="assets/images/sponsor-logo-testmuai-light.png#only-light" style="width: 220px;" />
</a>
</div>
</div>
@@ -396,6 +396,45 @@ Deletes the virtual sensor with the type identified by `:sensorType`.
`null`
## Global Privacy Control Protocol
The [Global Privacy Control protocol](https://www.w3.org/TR/gpc) (GPC) is an extension of the W3C
WebDriver protocol.
### setGlobalPrivacyControl
```
POST /session/:sessionId/privacy
```
> GPC documentation: [Set Global Privacy Control](https://www.w3.org/TR/gpc/#set-global-privacy-control)
Sets the value of the do-not-sell-or-share preference for the current session.
#### Parameters
|Name|Description|Type|
|--|--|--|
|`gpc`|Whether the browser should perform do-not-sell-or-share interactions|boolean|
#### Response
`null`
### getGlobalPrivacyControl
```
GET /session/:sessionId/privacy
```
> GPC documentation: [Get Global Privacy Control](https://www.w3.org/TR/gpc/#get-global-privacy-control)
Retrieves the value of the do-not-sell-or-share preference for the current session.
#### Response
`boolean` - the preference value
## Permissions Protocol
The [Permissions protocol](https://www.w3.org/TR/permissions/) is an extension of the W3C WebDriver
@@ -523,6 +562,32 @@ Retrieves the available log types that can be used to call the [`getLog`](#getlo
`string[]` - an array of log types
## Storage Access Protocol
The [Storage Access protocol](https://privacycg.github.io/storage-access/) is an extension of the
W3C WebDriver protocol.
### setStorageAccess
```
POST /session/:sessionId/storageaccess
```
> Storage Access documentation: [Set Storage Access](https://privacycg.github.io/storage-access/#set-storage-access-command)
Sets the storage access policy of the current browsing context.
#### Parameters
|Name|Description|Type|
|--|--|--|
|`blocked`|Whether storage access should be blocked (`true`) or allowed (`false`)|boolean|
|`origin`|The origin to which the policy should be applied. Must be either a valid URL, or an asterisk (`*`) if the policy should apply to all origins.|string|
#### Response
`null`
## Web Authentication Protocol
The [Web Authentication protocol](https://w3c.github.io/webauthn/) (WebAuthn) is an extension of
@@ -117,6 +117,12 @@ appium {driver|plugin} install <install-spec>
appium driver install git://github.com/appium/appium-xcuitest-driver.git --source=git --package=appium-xcuitest-driver
```
- Install a branch of XCUITest driver repository using a Git URL:
```
appium driver install git://github.com/appium/appium-xcuitest-driver.git#specific-branch --source=git --package=appium-xcuitest-driver
```
## `list`
Lists all installed extensions, plus all official extensions that are not installed.
@@ -134,6 +140,7 @@ appium {driver|plugin} list
|`--installed`|Only list all installed extensions|boolean|
|`--json`|Return the result in JSON format|boolean|
|`--updates`|List all extensions along with information on whether newer versions are available. Only supported for extensions installed via `npm`.|boolean|
|`--verbose`|Show additional details for each extension|boolean|
#### Example
@@ -31,5 +31,6 @@ The executable has four main subcommands: `server`, `driver`, `plugin`, and `set
</div>
Appium also recognizes several [environment variables](./env-vars.md), which may be used for
advanced configuration.
The Appium server also recognizes several [environment variables](./env-vars.md) and
[insecure feature names](./insecure-features.md), though drivers and plugins can also define
variables and features of their own.
@@ -0,0 +1,24 @@
---
hide:
- toc
title: Insecure Features
---
The Appium server implements [a security protection mechanism](../../guides/security.md) that
allows the management of various insecure features.
The following features are defined on the server level and can be used even without drivers, but
they can only be enabled using the wildcard (`*`) prefix:
| Feature Name | Description |
|-------------------|-------------------------------------------------------------------------------|
|`session_discovery`|Allows retrieving the list of active server sessions via `GET /appium/sessions`|
Of course, Appium drivers and plugins are free to define additional insecure features of their own.
The following features are defined by official plugins:
| Feature Name | Plugin | Description |
|-----------------------|----------------|----------------------------------------------------------|
|`execute_driver_script`|`execute_driver`|Allows sending a request that has multiple Appium commands|
@@ -48,6 +48,8 @@ appium
|`--log-no-colors`|Disable colors in the server log|boolean|`false`|
|`--log-timestamp`|Show timestamps in the server log|boolean|`false`|
|`--long-stacktrace`|Add long stack traces to log entries. Recommended for debugging only.|boolean|`false`|
|`--max-ipc-data-size`|Maximum byte size of IPC message objects.|integer|`1048576` (1MB)|
|`--max-ipc-topics`|Maximum number of IPC topics per session.|integer|`1000`|
|`--no-perms-check`|Skip various permission checks on the server startup|boolean|`false`|
|`--nodeconfig`|JSON configuration for registering Appium as a node with Selenium Grid 3|object||
|`--plugin`|Plugin-specific configuration. Keys should correspond to plugin package names|object||
+9 -3
View File
@@ -5,8 +5,8 @@ hide:
title: Reference
---
This section of the Appium documentation provides a reference to the two main interfaces within the
Appium server: the command-line executable, and the supported API endpoints.
This section of the Appium documentation provides a reference to the core interfaces supported within the
Appium server:
<div class="grid cards" markdown>
@@ -16,10 +16,16 @@ Appium server: the command-line executable, and the supported API endpoints.
Learn how to use the Appium command-line executable
- :material-lan-connect: [__Session Properties__](./session/index.md)
---
See the values of global Appium session properties
- :material-cloud-braces: [__API Endpoints__](./api/index.md)
---
View endpoints supported by the Appium server
View endpoints supported by the core Appium server
</div>
@@ -0,0 +1,56 @@
---
hide:
- toc
title: Capabilities
---
The following [capabilities](../../guides/caps.md) are recognized by the Appium server/base driver,
and are therefore supported by all drivers as well. Some capabilities are directly handled by the
server/base driver, while others are only validated before being passed to the actual driver.
!!! note
Capabilities not listed here will _not_ be rejected by Appium: they will simply be forwarded
directly to the active driver/plugin.
### Required Capabilities
These capabilities are used in the Appium server/base driver, and are explicitly required in all
Appium sessions.
| Capability | Description | Type |
|-------------------------|---------------------------------------------|-----------|
| `platformName` | Type of platform hosting the app or browser | `string` |
| `appium:automationName` | Name of the Appium driver to use | `string` |
### Optional Capabilities
These capabilities are used in the Appium server/base driver, but are optional, and may have a
default value.
| <div style="width:19em">Capability</div> | Description | Type | Default |
|--|--|--|--|
| `webSocketUrl` | Toggle support of the WebDriver BiDi protocol | `boolean` ||
| `appium:eventTimings` (deprecated) | Toggle collection of [Event Timings](../../guides/event-timing.md). This capability is deprecated - please use the [`getLogEvents`](../api/appium.md#getlogevents) endpoint instead. | `boolean` ||
| `appium:newCommandTimeout` | Number of seconds the Appium server should wait for clients to send commands before stopping the session. A value of `0` disables the timeout. | `number` | `60` |
| `appium:printPageSourceOnFindFailure` | Toggle retrieval of the the page source and its printing to the Appium log, whenever a request to find an element fails | `boolean` ||
### Validated Capabilities
These capabilities are not directly used in the Appium server/base driver, but are still subject to
validation checks due to their relevance in other drivers. The actual handling of these
capabilities is optional and entirely driver-dependent.
| Capability | Validation |
|-----------------------------------|---------------------------------------------------------------|
| `platformVersion` | Must be `string` |
| `appium:app` | Must be `string`; empty values are ignored |
| `appium:autoLaunch` (deprecated) | Must be `boolean` |
| `appium:autoWebview` | Must be `boolean` |
| `appium:fullReset` | Must be `boolean`; mutually exclusive with `appium:noReset` |
| `appium:language` | Must be `string` |
| `appium:locale` | Must be `string` |
| `appium:orientation` | Must be either `LANDSCAPE` or `PORTRAIT` |
| `appium:noReset` | Must be `boolean`; mutually exclusive with `appium:fullReset` |
| `appium:udid` | Must be `string` |
@@ -0,0 +1,23 @@
---
hide:
- toc
title: Session Properties
---
An Appium session has several key properties, each with its own set of supported values:
capabilities, execute methods, settings, locator strategies, and others. The supported values for
each property are primarily defined by the active driver and plugins, but some properties also have
common values provided by the Appium server and its base driver:
<div class="grid cards" markdown>
- [__Capabilities__](./caps.md)
A small set of basic capabilities
- [__Command Endpoints__](../api/index.md)
The core set of API endpoints
</div>
+8 -3
View File
@@ -22,6 +22,11 @@ Hub](https://opencollective.com/appium).
We are very grateful for the support of our Development Partners, who donate Appium development and
maintenance as part of their employees' core job duties!
<a href="https://www.testmuai.com">
<img src="/docs/en/latest/assets/images/sponsor-logo-testmuai-dark.png#only-dark" width="250" alt="TestMu AI (formerly LambdaTest)" />
<img src="/docs/en/latest/assets/images/sponsor-logo-testmuai-light.png#only-light" width="250" alt="TestMu AI (formerly LambdaTest)" />
</a>
## Strategic Partners
We are very grateful for the financial and marketing support of our exclusive Strategic Partners,
@@ -33,9 +38,9 @@ contributors!
<img src="/docs/en/latest/assets/images/sponsor-logo-browserstack-light.png#only-light" width="250" alt="BrowserStack" />
</a>
<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="250" alt="LambdaTest" />
<img src="/docs/en/latest/assets/images/sponsor-logo-lambdatest-light.png#only-light" width="250" alt="LambdaTest" />
<a href="https://www.testmuai.com">
<img src="/docs/en/latest/assets/images/sponsor-logo-testmuai-dark.png#only-dark" width="250" alt="TestMu AI (formerly LambdaTest)" />
<img src="/docs/en/latest/assets/images/sponsor-logo-testmuai-light.png#only-light" width="250" alt="TestMu AI (formerly LambdaTest)" />
</a>
## Gold Sponsors
@@ -0,0 +1,34 @@
---
authors:
- sai
- srini
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 -->
<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" />
</a>
</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.
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
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!
@@ -10,7 +10,7 @@ maintenance, and support from companies and volunteers. As such, we welcome cont
There are a lot of different ways to help the project - see below for everything you can do and the
processes to follow for each contribution method. Note that no matter how you contribute, your
participation is governed by our [Code of Conduct](https://github.com/appium/appium/blob/master/CONDUCT.md).
participation is governed by our [Code of Conduct](https://github.com/appium/.github/blob/master/CODE_OF_CONDUCT.md).
## Join the Discussion Forum
@@ -570,6 +570,33 @@ capability), and then to set an internal field to that value, so that it can be
bidiProxyUrl`. Once all this is in place, Appium will proxy BiDi commands from the client straight
to the upstream connection.
### Understand server-assigned driver properties and security flags
When your driver is running under the main Appium server, Appium assigns a small set of
server-related properties on your driver instance when a session is created:
- `cliArgs`: Driver-specific configuration derived from the Appium server’s CLI flags and/or
configuration files (for example via the `server.driver.<your-driver-name>` section). These
options are **not** user capabilities and cannot be influenced directly by test code.
- `server`, `serverHost`, `serverPort`, `serverPath`: Information about the HTTP server that is
hosting your driver. These values reflect how the Appium server was started (for example the
`--address`, `--port`, and `--base-path` flags) and are useful when your driver needs to construct
URLs that point back to the Appium server itself (for example when setting up proxies, webhooks,
or other callbacks).
`BaseDriver` and `AppiumDriver` also cooperate to expose security-related flags on your driver
instance:
- `relaxedSecurityEnabled`: Indicates whether the server is running with relaxed security enabled
(for example via `--relaxed-security`).
- `allowInsecure`: A list of insecure features which are explicitly allowed for this driver (derived
from server-level options like `--allow-insecure`).
- `denyInsecure`: A list of insecure features which are explicitly disabled for this driver (derived
from server-level options like `--deny-insecure`).
See [Hide behaviour behind security flags](#hide-behaviour-behind-security-flags) for how to use
these flags in your driver (e.g. via `isFeatureEnabled` and `assertFeatureEnabled`).
### Extend the existing protocol with new commands
You may find that the existing commands don't cut it for your driver. If you want to expose
@@ -579,7 +606,7 @@ three ways:
1. Extending the classic WebDriver protocol and creating client-side plugins to access the extensions via the classic HTTP interface
2. Extending the WebDriver BiDi protocol with new modules and methods, accessed from a client via the BiDi interface
3. Overloading the Execute Script command by defining Execute
Methods
Methods
If you want to follow the first path, you can direct Appium to recognize new methods and add them
to its set of allowed HTTP routes and command names. You do this by assigning the `newMethodMap`
@@ -685,17 +712,17 @@ async execute(script, args) {
A couple notes about this system:
1. The arguments array sent via the call to Execute Script must contain only zero or one element(s). The
first item in the list is considered to be the parameters object for your method. These parameters
will be parsed, validated, and then applied to your overload method in the order specified in
`executeMethodMap` (the order specified in the `required` parameters list, followed by the
`optional` parameters list). I.e., this framework assumes only a single actual argument sent in via
Execute Script (and this argument should be an object with keys/values representing the
parameters your execute method expects).
first item in the list is considered to be the parameters object for your method. These parameters
will be parsed, validated, and then applied to your overload method in the order specified in
`executeMethodMap` (the order specified in the `required` parameters list, followed by the
`optional` parameters list). I.e., this framework assumes only a single actual argument sent in via
Execute Script (and this argument should be an object with keys/values representing the
parameters your execute method expects).
2. Appium does not automatically implement `execute` (the Execute Script handler) for you. You may
wish, for example, to only call the `executeMethod` helper function when you're not in proxy
mode!
wish, for example, to only call the `executeMethod` helper function when you're not in proxy
mode!
3. The `executeMethod` helper will reject with an error if a script name doesn't match one of the
script names defined as a command in `executeMethodMap`, or if there are missing parameters.
script names defined as a command in `executeMethodMap`, or if there are missing parameters.
One of the nice things about the Execute Method strategy is that methods implemented in this way
will be available via the classic or BiDi interfaces (since they will result in the same Appium
@@ -770,7 +797,7 @@ that multiple simultaneous sessions don't use the same resources:
1. Have your users specify resource IDs via capabilities (`appium:driverPort` etc)
2. Just always use free resources (find a new random port for each session)
3. Have each driver express what resources it is using, then examine currently-used resources from
other drivers when a new session begins.
other drivers when a new session begins.
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:
@@ -864,3 +891,120 @@ this.onUnexpectedShutdown(handler)
`handler` should be a function which receives an error object (representing the reason for the
unexpected shutdown).
### Send messages to plugins running on the same session
Appium's driver and plugin architecture means that a single driver and any number of plugins can be
running together for a current session. The driver and plugins don't really know anything about
each other though, which can make coordination potentially difficult. Without creating any kind of
tight coupling between drivers or plugins, it's possible for drivers and plugins to communicate
along a pub/sub style message bus. With Appium's IPC feature, "message" means a combination of
"data" (the data intended to be published or received), and metadata (timestamp, the name of the
publisher, etc...).
Drivers and plugins can implement an instance method called `async onIpcInit`, in which they will
know that the IPC channel for the session is now active. At this point, they have access to the
following methods:
#### `ipcSubscribe<T>(topic: string): IIpcSubscription`
This method allows a driver or plugin to subscribe to a topic on the IPC channel for the session.
Topics are simply strings. To coordinate effectively, drivers or plugins would use the same topic
string (so this would be something advertised in the driver/plugin documentation).
The result of this call is an `IpcSubscription` object that allows:
- Looping through messages on the topic via an async generator
- Hooking up an event handler for new messages
- Getting the last message sent on the topic
- Publishing a message to the topic
- Unsubscribing from the topic
#### `IpcSubscription` object
Here is an example of how subscribing and use of these subscription methods might work:
```ts
async onIpcInit() {
// we know at this point in our driver/plugin lifecycle that we can use IPC methods
type MyMessageData = {myData: string}; // let's say the message data for this channel has this shape
const subscription = this.ipcSubscribe<MyMessageData>('coolTopic');
// listen for new messages on topic
subscription.on('message', (message) => {
console.log(message.data); // {myData: 'something'}
});
// publish data to the topic; might throw if the data is larger than configured max size, or we
// are no longer subscribed
await subscription.publish({myData: 'hi'});
// get last message sent to topic
const {data} = subscription.getMessage() ?? {data: null};
// data = {myData: 'hi'}
// unsubscribe
subscription.unsubscribe(); // returns true if we unsubscribed and false if no subscription existed
}
```
With a subscription object, we can also iterate async over it to receive new messages:
```ts
for await (const message of subscription) {
// here we have a message and can unwrap its data
}
```
Note that the iteration will stop when the subscription ends (i.e., when `unsubscribe` is called).
You can also check whether the subscription is still active (if your subscribe and unsubscribe
logic is not locally connected):
```ts
if (subscription.isActive) {
// we know we have not yet unsubscribed
}
```
If the subscription is not active, attempts to call `subscription.publish` will throw an error.
#### `IpcMessage` object
When you get a message on a topic, it has the following shape:
```ts
export type IpcMessage<T> = {
publisher: string, // the id of the publishing object (typically of the form <ClassName>@<uniqueObjectId>)
timestampMs: number, // when the message was published, in ms since epoch
topic: string, // the topic the message was published on
data: T, // the arbitrary message data. Must be serializable and a valid argument to 'structuredClone()'
};
```
#### IPC Notes
There are some important things to keep in mind when using Appium's IPC feature:
- IPC is only available once `onIpcInit` has been called, at the end of the `createSession` flow.
It cannot be used statically or in `createSession` hooks
- In sum, IPC is only for use during a session (this is also to prevent drivers/plugins from
accessing or reading data sent on IPC channels in other sessions.)
- The default max size of an IPC message is 1MB. This can be configured by the server-admin by
using the `--max-ipc-data-size` arg (value is a number in bytes).
- If a message exceeds the configured size, any call to `publish` methods will throw, so be
sure to cover this case in your error handling.
- The default max number of IPC topics per session is 1000. This can be configured by the
server-admin using the `--max-ipc-topics` arg.
- If the topic limit is reached, calls to `subscribe` or `publish` on a new topic will throw, so
be sure to cover this case in your error handling.
- Topic names exist within a global namespace per session. So if you don't want to clash with other
drivers or plugins, make sure you prefix your topic names with something unique, akin to vendor
prefixes in the WebDriver standard (for example: `fake-driver:some-topic`). We recommend the
format `<namespace>:<topic>`.
To see examples of IPC in action, check out Appium's own
[FakeDriver](https://github.com/appium/appium/blob/master/packages/fake-driver/lib/driver.ts) and
[FakePlugin](https://github.com/appium/appium/blob/master/packages/fake-plugin/lib/plugin.ts)
extensions, which showcase several ways of using IPC messages.
@@ -236,13 +236,13 @@ upstream server. In this case, we might run into a problem, because the plugin n
handle that command! The way Appium handles this is as follows:
1. When a command comes in, before deciding whether to proxy the command, the main protocol handler
checks to see whether a plugin would handle the command.
checks to see whether a plugin would handle the command.
2. If a plugin would _not_ handle the command--all proceeds as normal, and the request is either
proxied or not, based on the driver's proxy mode.
proxied or not, based on the driver's proxy mode.
3. If a plugin _would_ handle the command, then the proxy behavior is skipped for the time being,
and wrapped up as the `next` function sent to the plugin. So if you have a command handler in
your plugin, and you want to be sure that the default driver proxying _does_ take place, then
simply `await next()` instead of (or in addition to) whatever your plugin handler is doing.
and wrapped up as the `next` function sent to the plugin. So if you have a command handler in
your plugin, and you want to be sure that the default driver proxying _does_ take place, then
simply `await next()` instead of (or in addition to) whatever your plugin handler is doing.
### Throw WebDriver-specific errors
@@ -331,7 +331,7 @@ drivers, you can create new commands in one of two ways, just as is possible for
1. Extending the WebDriver protocol and creating client-side plugins to access the extensions
2. Extending the WebDriver BiDi protocol with new modules and methods, accessed from a client via the BiDi interface
3. Overloading the Execute Script command by defining Execute
Methods
Methods
#### Extending the HTTP Protocol
@@ -458,10 +458,10 @@ inside the plugin class:
1. The `executeMethodMap`, defined in just the same way as for drivers
2. The implementation of the command method as defined in `executeMethodMap` (in this case,
`plugMeIn`)
`plugMeIn`)
3. The overriding/handling of the `execute` command. Just like any plugin command handlers, the
first two arguments are `next` and `driver`, followed by the script name and args. `BasePlugin`
implements a helper method which we can simply call with all of these arguments.
first two arguments are `next` and `driver`, followed by the script name and args. `BasePlugin`
implements a helper method which we can simply call with all of these arguments.
Overriding Execute Methods from drivers works as you'd expect: if your plugin defines an Execute
Method with the same name as that of a driver, your command (in this case `plugMeIn`) will be
@@ -518,3 +518,12 @@ async onUnexpectedShutdown(driver, cause) {
}
}
```
### Send messages to the driver or other plugins running on the same session
Even though drivers and plugins don't know anything about each other, it's possible for them to
send messages that other drivers or plugins can listen for, within the context of the same session,
using an IPC channel. Given that the developer instructions for this feature are the same for
drivers and plugins, please head over to the IPC development docs for
drivers at the driver
development guide.
@@ -29,7 +29,7 @@ In lieu of a separate file, configuration can be embedded in a project's `packag
```
When an Appium server is started via the `appium` executable, the `init` function in `lib/main.js`
will call into `lib/config-file.js` to load and/or search for a configuration file and in
will call into `lib/bootstrap/config-file.js` to load and/or search for a configuration file and in
`package.json`.
!!! note
@@ -72,7 +72,7 @@ It is more straightforward to explain how config files are validated, so we'll s
### Validating Config Files
When a config file is found (`lib/config-file.js`), it will call the `validate` function exported
When a config file is found (`lib/bootstrap/config-file.js`), it will call the `validate` function exported
from `lib/schema/schema.js` with the contents of the config file. In turn, this asks `ajv` to
validate the data against the schema that Appium has provided it.
+55 -27
View File
@@ -21,6 +21,48 @@ Appium has a graphical client which can be used to inspect application screensho
application hierarchy, search for elements, run Appium commands, record app interactions, and more.
It can be very useful for Appium test development.
\=== "Install as an Appium Plugin"
````
```bash
appium plugin install inspector
```
````
\=== "Install Standalone"
```
Download the app from the Appium Inspector repo's [GitHub Releases section](https://github.com/appium/appium-inspector/releases).
```
### [Appium MCP](https://github.com/appium/appium-mcp)
Appium MCP is a Model Context Protocol (MCP) server that provides mobile test development and
automation capabilities using Appium.
```json title="Install This Tool"
// Add the following to your MCP client configuration
{
"appium-mcp": {
"disabled": false,
"timeout": 100,
"type": "stdio",
"command": "npx",
"args": ["appium-mcp@latest"],
"env": {
"ANDROID_HOME": "/path/to/android/sdk"
}
}
}
```
### [Skills](https://github.com/appium/skills)
A set of AI Agent skills to support Appium automation, for example:
- Help preparing Appium test environment from scratch, including common driver setup
- Help preparing XCUITest driver and WebDriverAgent for real device automation
## Extension Tools
Appium driver or plugin developers can choose to include these tools in their driver/plugin:
@@ -35,7 +77,7 @@ details needed for the driver/plugin have been set up correctly. The tool can be
appium {driver|plugin} doctor <extension-name>
```
It shows no results if the driver/plugin author did not implement Doctor support.
It shows no results if the driver/plugin does not have such validation checks.
!!! note
@@ -48,6 +90,18 @@ out the documentation on [Building Doctor Checks](../developing/build-doctor-che
These tools are not maintained by the Appium team:
### [AppClaw](https://github.com/AppiumTestDistribution/AppClaw)
AppClaw is a CLI-based agentic AI layer for mobile automation, powered by [Appium MCP](#appium-mcp).
Agent instructions can be passed directly via CLI, or defined as YAML flows in either structured
or natural language syntax.
Supported by: `@AppiumTestDistribution`
```sh title="Install This Tool"
npm install -g appclaw
```
### [Appium Installer](https://github.com/AppiumTestDistribution/appium-installer)
Appium Installer is a command-line tool for simplifying setups of new Appium test environments.
@@ -59,29 +113,3 @@ Supported by: `@AppiumTestDistribution`
```sh title="Install This Tool"
npm install -g appium-installer
```
### [Jarvis Appium](https://github.com/AppiumTestDistribution/mcp-appium)
Jarvis Appium is a Model Context Protocol (MCP) server that provides mobile test development and
automation capabilities using Appium.
Supported by: `@AppiumTestDistribution`
```json title="Install This Tool"
// Add the following to your MCP client configuration
{
"mcpServers": {
"jarvis-appium": {
"disabled": false,
"timeout": 100,
"type": "stdio",
"command": "npx",
"args": ["jarvis-appium"],
"env": {
"ANDROID_HOME": "/path/to/android/sdk",
"CAPABILITIES_CONFIG": "/path/to/your/capabilities.json"
}
}
}
}
```
+50 -33
View File
@@ -2,9 +2,14 @@
title: Session Capabilities
---
「Capabilities」は、Appiumセッションを開始するために使用されるパラメータセットに付けられた名前です。 セット内の情報は、セッションにどのような「Capabilities」を持たせたいかを表します。たとえば、特定のモバイルオペレーティングシステムや特定のデバイスバージョンなどです。 Capabilities はキーと値のペアとして表され、値には他のオブジェクトを含む任意の有効な JSON 型を使用できます。
Capabilities are the core parameters used to start an Appium session. They describe various
features that you want your session to have, for example, a certain mobile operating system or a
certain version of a device. Capabilities are represented as key-value pairs, with values allowed
to be any valid JSON type, including other objects. Most importantly, they cannot be changed
during the lifecycle of the session.
W3C WebDriver 仕様の [Capabilities に関するセクション](https://w3c.github.io/webdriver/#capabilities) では、以下の機能を含む 10 個の標準機能のセットが定義されています:
The capabilities used in Appium follow [the W3C WebDriver specification of the same name](https://w3c.github.io/webdriver/#capabilities).
The WebDriver spec defines a small set of standard capabilities, including the following:
| Capability 名 | 型 | 説明 |
| ---------------- | -------- | --------------------- |
@@ -12,51 +17,64 @@ W3C WebDriver 仕様の [Capabilities に関するセクション](https://w3c.g
| `browserVersion` | `string` | ブラウザのバージョン |
| `platformName` | `string` | ブラウザをホストするプラットフォームの種類 |
While the above capabilities are commonly used by Appium drivers, they are not sufficient for
describing Appium-specific features, such as the name of the driver to use, or the name of the app
to launch. In order to achieve this, Appium defines its own [extension capabilities](https://w3c.github.io/webdriver/#dfn-extension-capability).
## 一般的なAppiumのCapabilities
Appium はこれらのブラウザに焦点を当てた capabilities を理解しますが、いくつかの capabilities も追加導入しています。 WebDriver 仕様によれば、非標準の「拡張 capabilities」には、capabilities を導入したベンダーを示す名前空間となる接頭辞(末尾に「:」)を含める必要があります。 Appium の接頭辞は「appium:」であるため、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
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.
以下は様々なドライバーで認識される Appium の capabilities の一覧です:
Here are a few commonly (but not universally!) used Appium-specific capabilities:
!!! info
| Capability 名 | 型 | Description |
| ----------------------- | -------- | --------------------------------------------------------------- |
| `appium:automationName` | `string` | 使用するAppiumドライバの名前 |
| `appium:udid` | `string` | The unique device identifier of a particular device to automate |
| `appium:app` | `string` | インストール可能なアプリケーションへのパス |
```
個々のドライバやプラグインは独自の capabilities をサポートしている場合があるため、具体的な capability 名のリストについては、それぞれのドキュメントを参照してください。また、一部のドライバはこれらの capabilities をすべてサポートしていない場合があります
```
All capabilities recognized by the Appium base driver (inherited by all drivers) can be found in the
[Capabilities Reference document](../reference/session/caps.md). While this common capability set
is fairly small, it can be greatly extended by Appium drivers and plugins, who can (and should)
define their own capabilities. Make sure to reference their documentation to learn more about the
capabilities they support. You can find a list of known drivers in the [Ecosystem Drivers](../ecosystem/drivers.md) document.
| <div style="width:12em">Capability 名</div> | 型 | 必須か | 説明 |
| ------------------------------------------ | --------- | --- | ------------------------------------------------------------------------------------------------------------------------- |
| `platformName` | `string` | はい | アプリまたはブラウザをホストするプラットフォームの種類 |
| `appium:automationName` | `string` | はい | 使用するAppiumドライバの名前 |
| `browserName` | `string` | いいえ | ドライバーが特別なケースとしてWebブラウザーをサポートしている場合、起動して自動化するブラウザーの名前 |
| `appium:app` | `string` | いいえ | インストール可能なアプリケーションへのパス |
| `appium:deviceName` | `string` | いいえ | 自動化する特定のデバイスの名前、例:`iPhone 14`(現在のところ、iOS シミュレーターを指定する場合にのみ役立ちます。他の状況では通常、`appium:udid` 機能を使用して特定のデバイス Id を使用することをお勧めします)。 |
| `appium:platformVersion` | `string` | いいえ | プラットフォームのバージョン(例:iOS の場合は `16.0`) |
| `appium:newCommandTimeout` | `number` | いいえ | クライアントがこれ以上コマンドを送信してこないと判断しセッションを終了する前に、Appium サーバーがクライアントからのコマンド送信を待機する秒数。 デフォルトは `60` 秒。 ゼロに設定するとタイマーが無効になります。 |
| `appium:noReset` | `boolean` | いいえ | true の場合、セッションの開始とクリーンアップ中に通常のリセット処理を回避するように Appium ドライバーに指示します (デフォルトは `false`) |
| `appium:fullReset` | `boolean` | いいえ | true の場合、Appium ドライバーに通常のリセット処理に追加の手順を追加して、環境の再現性を最大限に高めるように指示します (デフォルトは `false`) |
| `appium:eventTimings` | `boolean` | いいえ | true の場合、Appium ドライバーに [Event Timings](./event-timing.md) を収集するように指示します (デフォルトは `false`) |
| `appium:printPageSourceOnFindFailure` | `boolean` | いいえ | true の場合、要素の検索リクエストが失敗するたびにページソースを収集し、Appium ログに出力します (デフォルトは `false`) |
Drivers are also able to place more complex constraints on capabilities as a group. For example,
the XCUITest driver recommends that at least one of `browserName`, `appium:app`, or `appium:bundleId`
is included in the capabilities, otherwise it will not be able to auto-install or auto-launch any
application. Each driver will document how it interprets these capabilities and any other
platform-specific requirements.
ドライバーの中には、capabilitiesのより複雑な制約をグループとして設定しているものもあります。 たとえば、`appium:app` および `browserName` capabilities は上記では必須ではないと記載していますが、特定のアプリでセッションを開始する場合、XCUITest ドライバーは、`appium:app`、`browserName`、または `appium:bundleId` の少なくとも1 つが capabilities に含まれていることが必要です (含まれていない場合、どのアプリをインストールまたは起動すればよいか判断できないため、ホーム画面からセッションが開かれます)。 各ドライバーは、これらの capabilities やその他のプラットフォーム固有の要件をどのように解釈するかを記述しています。
The way to construct capabilities and start a session will likely differ depending on your Appium
client. For examples of doing this in each client library, head to the [Ecosystem Clients](../ecosystem/clients.md)
page and click through to the appropriate client documentation.
!!! note
```
Capabilitiesは、セッション開始時に使用されるパラメータのようなものです。Capabilitiesが送信され、セッションが開始された後変更できません。ドライバーがセッション中に動作の一部を更新する場合、capabilitiesの代わりに、またはcapabilitiesに加えて、[Settings](./settings.md)も利用可能です。
Once your capabilities are sent to the server and the session is started, they cannot be
changed. If a driver supports updating its behaviour during a session, it will use the
[Settings API](./settings.md) for this purpose.
```
各 Appium クライアントには、capabilities を構築し、セッションを開始する独自の方法があります。 各クライアントライブラリでこれを行う例については、[エコシステム](../ecosystem/index.md) ページにアクセスし、適切なクライアントドキュメントをクリックしてください。
## BiDi プロトコルのサポート
Appiumは、base-driver 9.5.0以降で[WebDriver BiDi](https://w3c.github.io/webdriver-bidi/)プロトコルをサポートしています。
実際の動作は個々のドライバーによって異なりますが、Appium と base-driver はプロトコルをサポートしています。
ドライバーが BiDi プロトコルをサポートしているかどうか、また、どのようなコマンド/イベントをサポートしているかはドキュメントで確認してください。
In addition to the standard WebDriver protocol (now known as WebDriver Classic), Appium supports the
[WebDriver BiDi](https://w3c.github.io/webdriver-bidi/) protocol. Support for this protocol is
opt-in, and requires the use of the standard `webSocketUrl` capability.
| Capability 名 | 型 | 説明 |
| -------------- | --------- | ------------------------- |
| `webSocketUrl` | `boolean` | セッションで BiDi プロトコルを有効にします。 |
| Capability Name | 型 | 説明 |
| --------------- | --------- | ----------------------------------------------- |
| `webSocketUrl` | `boolean` | Whether BiDi protocol is enabled in the session |
All BiDi commands supported by the Appium base driver (inherited by all drivers) can be found in the
[BiDi Protocol API Reference document](../reference/api/bidi.md). Similarly to WebDriver Classic
commands, individual Appium drivers and plugins can define their own supported standard and custom
BiDi commands, so make sure to reference their documentation.
## `appium:options` を使用して機能をグループ化する
@@ -99,8 +117,7 @@ creates in response to a new session request. This is through the concept of "al
!!! note
```
Check out the [spec itself](https://w3c.github.io/webdriver/#processing-capabilities) or
a [summarized version](https://github.com/jlipps/simple-wd-spec#processing-capabilities) for
Check out the [spec itself](https://w3c.github.io/webdriver/#processing-capabilities) for
a more in-depth description of how capabilities are processed.
```
+35 -35
View File
@@ -3,27 +3,27 @@ title: Appium Server Security
---
The Appium team makes every effort to ensure the security of the Appium server. This is especially
important when Appium is run in a multitenant environment, or when multiple users are running
sessions on the same Appium server. In general, you can only safely enable all Appium's features if
all the following are true:
important when Appium is run in a multi-tenant environment, or when multiple users are running
sessions on the same Appium server. To ensure a safe environment for Appium's purposes, all of the
following should be true:
- You're running your own Appium server locally or within a protected internal network
- You're not sharing it with any untrusted parties
- You don't expose Appium's port(s) to the wider internet
But because many Appium users might not be able to guarantee such a safe environment, the Appium
team puts many features behind a security protection mechanism which forces system admins (the
people that are in charge of starting the Appium server) to _explicitly opt-in_ to these features.
(Third-party driver and plugin authors can also hide behaviour behind security
flags.)
But because not all Appium hosts can guarantee such a safe environment, certain insecure Appium
features are disabled by default, and require explicit opt-in in order to enable them. Most
importantly, this can _only_ be done by the Appium server _host_, and Appium _client_ sessions are
not allowed to change this.
For security reasons, Appium client sessions can _not_ request feature enablement via capabilities;
this is the responsibility of the server admin who configures and launches the Appium server.
While it is possible for an Appium host to simply enable all insecure features at once, each
feature also has a unique name, which can be used for granular control over the server state.
## Security Server Args
The [Server CLI](../reference/cli/server.md) doc outlines three relevant arguments which may be passed to
Appium when starting it from the command line:
Enabling or disabling insecure features is done via [Appium server launch arguments](../reference/cli/server.md)
or [configuration file](./config.md). The former document outlines three relevant arguments for
achieving this:
| <div style="width:10em">Parameter</div> | Description |
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -31,36 +31,30 @@ Appium when starting it from the command line:
| `--allow-insecure` | Turns on _only_ specified features, except those blocked by `--deny-insecure`. Has no effect when used in combination with `--relaxed-security` |
| `--deny-insecure` | Explicitly turns _off_ specified features, overriding `--relaxed-security` and `--allow-insecure` |
All of the above arguments can also be specified in the [Appium Configuration file](./config.md).
Features passed to `--allow-insecure`/`--deny-insecure` must be specified as a comma-separated list,
and each feature in the list must additionally include a prefix, indicating the driver to which the
feature should apply. The prefix can be either the driver's `automationName`, or the wildcard (`*`)
symbol, if the feature should be applied to all drivers. The prefix and feature name are separated
using the colon character (`:`).
and each feature in the list must additionally include a prefix, indicating the driver to whose
sessions the feature should apply. The prefix can be either the driver's `automationName`, or the
wildcard (`*`) symbol, if the feature should be applied to all drivers. The prefix and feature name
are separated using the colon character (`:`).
For example, `first:foo` refers to the `foo` feature for the `first` driver, whereas `*:bar` refers
to the `bar` feature for all drivers.
## Insecure Features
Each Appium driver is responsible for its own security, and can create its own feature names. Thus
you should read through the documentation for a particular driver to know which feature names it
might use. Here is an incomplete list of examples from some of Appium's official drivers:
Almost all insecure features are defined on a per-driver or plugin basis, so make sure to read the
documentation for a particular driver/plugin to know which feature names it might use.
| <div style="width:12em">Feature Name</div> | Description | Supported Extension(s) |
| ------------------------------------------ | --------------------------------------------------------------------------------------- | ---------------------------------------------- |
| `get_server_logs` | Allows retrieving of Appium server logs via the Webdriver log interface | IOS, XCUITest, Android, UiAutomator2, Espresso |
| `adb_shell` | Allows execution of arbitrary shell commands via ADB, using the `mobile: shell` command | Android, UiAutomator2, Espresso |
| `record_audio` | Allow recording of host machine audio inputs | XCUITest |
| `execute_driver_script` | Allows to send a request which has multiple Appium commands. | Execute Driver Plugin |
Certain insecure features are also defined on the Appium server itself. For a list of these
features, as well as the features defined in official plugins, see
[the Insecure Features CLI Reference](../reference/cli/insecure-features.md) doc.
Some insecure features operate on the server level, and do not require a driver session. Enabling
these features requires using the wildcard prefix:
!!! note
| <div style="width:12em">Feature Name</div> | Description |
| ------------------------------------------ | ------------------------------------------------------------------------------- |
| `session_discovery` | Allows retrieving the list of active server sessions via `GET /appium/sessions` |
```
If you are a driver or plugin author and want to implement insecure features of your own, check
out the [Building Drivers documentation](../developing/build-drivers.md#understand-server-assigned-driver-properties-and-security-flags).
```
## Examples
@@ -73,17 +67,23 @@ appium --allow-insecure=first:foo
Turn on the `foo` feature for all drivers:
```bash
appium --allow-insecure=*:foo
appium --allow-insecure='*:foo'
```
Turn on the `foo` feature for all drivers _except_ `first`:
```bash
appium --allow-insecure=*:foo --deny-insecure=first:foo
appium --allow-insecure='*:foo' --deny-insecure=first:foo
```
Turn on all features _except_ `foo` for all drivers:
```bash
appium --relaxed-security --deny-insecure=*:foo
appium --relaxed-security --deny-insecure='*:foo'
```
Turn on multiple insecure features for specific drivers:
```bash
appium --allow-insecure=uiautomator2:adb_shell,xcuitest:get_server_logs
```
+3 -3
View File
@@ -30,9 +30,9 @@ Appiumのドキュメントにようこそ! Appiumはオープンソースプ
</a>
</div>
<div class="homepageSponsor">
<a href="https://lambdatest.com/?utm_source=appium.io&utm_medium=organic&utm_campaign=june_25&utm_term=sk&utm_content=webpage">
<img src="assets/images/sponsor-logo-lambdatest-dark.png#only-dark" style="width: 220px;" />
<img src="assets/images/sponsor-logo-lambdatest-light.png#only-light" style="width: 220px;" />
<a href="https://www.testmuai.com">
<img src="assets/images/sponsor-logo-testmuai-dark.png#only-dark" style="width: 220px;" />
<img src="assets/images/sponsor-logo-testmuai-light.png#only-light" style="width: 220px;" />
</a>
</div>
</div>
@@ -397,6 +397,45 @@ Deletes the virtual sensor with the type identified by `:sensorType`.
`null`
## Global Privacy Control Protocol
The [Global Privacy Control protocol](https://www.w3.org/TR/gpc) (GPC) is an extension of the W3C
WebDriver protocol.
### setGlobalPrivacyControl
```
POST /session/:sessionId/privacy
```
> GPC documentation: [Set Global Privacy Control](https://www.w3.org/TR/gpc/#set-global-privacy-control)
Sets the value of the do-not-sell-or-share preference for the current session.
#### Parameters
| Name | Description | Type |
| ----- | -------------------------------------------------------------------- | ------- |
| `gpc` | Whether the browser should perform do-not-sell-or-share interactions | boolean |
#### Response
`null`
### getGlobalPrivacyControl
```
GET /session/:sessionId/privacy
```
> GPC documentation: [Get Global Privacy Control](https://www.w3.org/TR/gpc/#get-global-privacy-control)
Retrieves the value of the do-not-sell-or-share preference for the current session.
#### Response
`boolean` - the preference value
## Permissions Protocol
The [Permissions protocol](https://www.w3.org/TR/permissions/) is an extension of the W3C WebDriver
@@ -524,6 +563,32 @@ Retrieves the available log types that can be used to call the [`getLog`](#getlo
`string[]` - an array of log types
## Storage Access Protocol
The [Storage Access protocol](https://privacycg.github.io/storage-access/) is an extension of the
W3C WebDriver protocol.
### setStorageAccess
```
POST /session/:sessionId/storageaccess
```
> Storage Access documentation: [Set Storage Access](https://privacycg.github.io/storage-access/#set-storage-access-command)
Sets the storage access policy of the current browsing context.
#### Parameters
| Name | Description | Type |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- |
| `blocked` | Whether storage access should be blocked (`true`) or allowed (`false`) | boolean |
| `origin` | The origin to which the policy should be applied. Must be either a valid URL, or an asterisk (`*`) if the policy should apply to all origins. | string |
#### Response
`null`
## Web Authentication Protocol
The [Web Authentication protocol](https://w3c.github.io/webauthn/) (WebAuthn) is an extension of
@@ -118,6 +118,12 @@ appium {driver|plugin} install <install-spec>
appium driver install git://github.com/appium/appium-xcuitest-driver.git --source=git --package=appium-xcuitest-driver
```
- Install a branch of XCUITest driver repository using a Git URL:
```
appium driver install git://github.com/appium/appium-xcuitest-driver.git#specific-branch --source=git --package=appium-xcuitest-driver
```
## `list`
Lists all installed extensions, plus all official extensions that are not installed.
@@ -135,6 +141,7 @@ appium {driver|plugin} list
| `--installed` | Only list all installed extensions | boolean |
| `--json` | Return the result in JSON format | boolean |
| `--updates` | List all extensions along with information on whether newer versions are available. Only supported for extensions installed via `npm`. | boolean |
| `--verbose` | Show additional details for each extension | boolean |
#### Example
@@ -31,5 +31,6 @@ The executable has four main subcommands: `server`, `driver`, `plugin`, and `set
</div>
Appium also recognizes several [environment variables](./env-vars.md), which may be used for
advanced configuration.
The Appium server also recognizes several [environment variables](./env-vars.md) and
[insecure feature names](./insecure-features.md), though drivers and plugins can also define
variables and features of their own.
@@ -0,0 +1,23 @@
---
hide:
- toc
title: Insecure Features
---
The Appium server implements [a security protection mechanism](../../guides/security.md) that
allows the management of various insecure features.
The following features are defined on the server level and can be used even without drivers, but
they can only be enabled using the wildcard (`*`) prefix:
| Feature Name | Description |
| ------------------- | ------------------------------------------------------------------------------- |
| `session_discovery` | Allows retrieving the list of active server sessions via `GET /appium/sessions` |
Of course, Appium drivers and plugins are free to define additional insecure features of their own.
The following features are defined by official plugins:
| Feature Name | Plugin | Description |
| ----------------------- | ---------------- | ---------------------------------------------------------- |
| `execute_driver_script` | `execute_driver` | Allows sending a request that has multiple Appium commands |
@@ -48,6 +48,8 @@ appium
| `--log-no-colors` | Disable colors in the server log | boolean | `false` |
| `--log-timestamp` | Show timestamps in the server log | boolean | `false` |
| `--long-stacktrace` | Add long stack traces to log entries. Recommended for debugging only. | boolean | `false` |
| `--max-ipc-data-size` | Maximum byte size of IPC message objects. | integer | `1048576` (1MB) |
| `--max-ipc-topics` | Maximum number of IPC topics per session. | integer | `1000` |
| `--no-perms-check` | Skip various permission checks on the server startup | boolean | `false` |
| `--nodeconfig` | JSON configuration for registering Appium as a node with Selenium Grid 3 | object | |
| `--plugin` | Plugin-specific configuration. Keys should correspond to plugin package names | object | |
+9 -3
View File
@@ -5,8 +5,8 @@ hide:
title: Reference
---
This section of the Appium documentation provides a reference to the two main interfaces within the
Appium server: the command-line executable, and the supported API endpoints.
This section of the Appium documentation provides a reference to the core interfaces supported within the
Appium server:
<div class="grid cards" markdown>
@@ -16,10 +16,16 @@ Appium server: the command-line executable, and the supported API endpoints.
Learn how to use the Appium command-line executable
- :material-lan-connect: [**Session Properties**](./session/index.md)
---
See the values of global Appium session properties
- :material-cloud-braces: [**API Endpoints**](./api/index.md)
---
View endpoints supported by the Appium server
View endpoints supported by the core Appium server
</div>
@@ -0,0 +1,56 @@
---
hide:
- toc
title: Capabilities
---
The following [capabilities](../../guides/caps.md) are recognized by the Appium server/base driver,
and are therefore supported by all drivers as well. Some capabilities are directly handled by the
server/base driver, while others are only validated before being passed to the actual driver.
!!! note
Capabilities not listed here will _not_ be rejected by Appium: they will simply be forwarded
directly to the active driver/plugin.
### Required Capabilities
These capabilities are used in the Appium server/base driver, and are explicitly required in all
Appium sessions.
| Capability | Description | Type |
| ----------------------- | ------------------------------------------- | -------- |
| `platformName` | Type of platform hosting the app or browser | `string` |
| `appium:automationName` | Name of the Appium driver to use | `string` |
### Optional Capabilities
These capabilities are used in the Appium server/base driver, but are optional, and may have a
default value.
| <div style="width:19em">Capability</div> | Description | Type | Default |
| ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ------- |
| `webSocketUrl` | Toggle support of the WebDriver BiDi protocol | `boolean` | |
| `appium:eventTimings` (deprecated) | Toggle collection of [Event Timings](../../guides/event-timing.md). This capability is deprecated - please use the [`getLogEvents`](../api/appium.md#getlogevents) endpoint instead. | `boolean` | |
| `appium:newCommandTimeout` | Number of seconds the Appium server should wait for clients to send commands before stopping the session. A value of `0` disables the timeout. | `number` | `60` |
| `appium:printPageSourceOnFindFailure` | Toggle retrieval of the the page source and its printing to the Appium log, whenever a request to find an element fails | `boolean` | |
### Validated Capabilities
These capabilities are not directly used in the Appium server/base driver, but are still subject to
validation checks due to their relevance in other drivers. The actual handling of these
capabilities is optional and entirely driver-dependent.
| Capability | Validation |
| --------------------------------------------------- | ------------------------------------------------------------- |
| `platformVersion` | Must be `string` |
| `appium:app` | Must be `string`; empty values are ignored |
| `appium:autoLaunch` (deprecated) | Must be `boolean` |
| `appium:autoWebview` | Must be `boolean` |
| `appium:fullReset` | Must be `boolean`; mutually exclusive with `appium:noReset` |
| `appium:language` | Must be `string` |
| `appium:locale` | Must be `string` |
| `appium:orientation` | Must be either `LANDSCAPE` or `PORTRAIT` |
| `appium:noReset` | Must be `boolean`; mutually exclusive with `appium:fullReset` |
| `appium:udid` | Must be `string` |
@@ -0,0 +1,23 @@
---
hide:
- toc
title: Session Properties
---
An Appium session has several key properties, each with its own set of supported values:
capabilities, execute methods, settings, locator strategies, and others. The supported values for
each property are primarily defined by the active driver and plugins, but some properties also have
common values provided by the Appium server and its base driver:
<div class="grid cards" markdown>
- [**Capabilities**](./caps.md)
A small set of basic capabilities
- [**Command Endpoints**](../api/index.md)
The core set of API endpoints
</div>
+8 -3
View File
@@ -22,6 +22,11 @@ Hub.
We are very grateful for the support of our Development Partners, who donate Appium development and
maintenance as part of their employees' core job duties!
<a href="https://www.testmuai.com">
<img src="/docs/en/latest/assets/images/sponsor-logo-testmuai-dark.png#only-dark" width="250" alt="TestMu AI (formerly LambdaTest)" />
<img src="/docs/en/latest/assets/images/sponsor-logo-testmuai-light.png#only-light" width="250" alt="TestMu AI (formerly LambdaTest)" />
</a>
## Strategic Partners
We are very grateful for the financial and marketing support of our exclusive Strategic Partners,
@@ -33,9 +38,9 @@ contributors!
<img src="/docs/en/latest/assets/images/sponsor-logo-browserstack-light.png#only-light" width="250" alt="BrowserStack" />
</a>
<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="250" alt="LambdaTest" />
<img src="/docs/en/latest/assets/images/sponsor-logo-lambdatest-light.png#only-light" width="250" alt="LambdaTest" />
<a href="https://www.testmuai.com">
<img src="/docs/en/latest/assets/images/sponsor-logo-testmuai-dark.png#only-dark" width="250" alt="TestMu AI (formerly LambdaTest)" />
<img src="/docs/en/latest/assets/images/sponsor-logo-testmuai-light.png#only-light" width="250" alt="TestMu AI (formerly LambdaTest)" />
</a>
## Gold Sponsors
+4
View File
@@ -42,6 +42,10 @@ nav:
- reference/cli/extensions.md
- reference/cli/setup.md
- reference/cli/env-vars.md
- reference/cli/insecure-features.md
- Session Properties:
- reference/session/index.md
- reference/session/caps.md
- API Endpoints:
- reference/api/index.md
- reference/api/webdriver.md
+4
View File
@@ -42,6 +42,10 @@ nav:
- reference/cli/extensions.md
- reference/cli/setup.md
- reference/cli/env-vars.md
- reference/cli/insecure-features.md
- Session Properties:
- reference/session/index.md
- reference/session/caps.md
- API Endpoints:
- reference/api/index.md
- reference/api/webdriver.md
+21 -17
View File
@@ -9,40 +9,44 @@ theme:
nav:
- 欢迎使用: index.md
- 博客: blog/index.md
- 简介:
- 简介:
- intro/index.md
- 背景:
- 背景:
- intro/appium.md
- intro/drivers.md
- intro/clients.md
- intro/history.md
- 快速开始:
- 快速开始:
- quickstart/index.md
- quickstart/requirements.md
- quickstart/install.md
- quickstart/uiauto2-driver.md
- 写一个测试:
- 写一个测试:
- quickstart/test-js.md
- quickstart/test-py.md
- quickstart/test-java.md
- quickstart/test-rb.md
- quickstart/test-dotnet.md
- quickstart/next-steps.md
- 生态系统:
- 生态系统:
- ecosystem/index.md
- ecosystem/drivers.md
- ecosystem/clients.md
- ecosystem/plugins.md
- ecosystem/tools.md
- 参考:
- 参考:
- reference/index.md
- 命令行界面:
- 命令行界面:
- reference/cli/index.md
- reference/cli/server.md
- reference/cli/extensions.md
- reference/cli/setup.md
- reference/cli/env-vars.md
- API 端点:
- reference/cli/insecure-features.md
- Session Properties:
- reference/session/index.md
- reference/session/caps.md
- API 端点:
- reference/api/index.md
- reference/api/webdriver.md
- reference/api/bidi.md
@@ -51,11 +55,11 @@ nav:
- reference/api/appium.md
- reference/api/others.md
- reference/api/plugins.md
- 指南:
- 迁移:
- 指南:
- 迁移:
- guides/migrating-2-to-3.md
- guides/migrating-1-to-2.md
- 服务器/驱动程序配置:
- 服务器/驱动程序配置:
- guides/managing-exts.md
- guides/branch-testing.md
- guides/config.md
@@ -65,24 +69,24 @@ nav:
- guides/grid.md
- guides/caching.md
- guides/tls.md
- 会话配置:
- 会话配置:
- guides/caps.md
- guides/settings.md
- guides/execute-methods.md
- guides/context.md
- guides/event-timing.md
- 更多资源:
- 更多资源:
- resources/index.md
- 开发:
- 开发:
- developing/index.md
- developing/build-drivers.md
- developing/build-plugins.md
- developing/build-docs.md
- developing/build-doctor-checks.md
- developing/sensitive.md
- 开发者参考:
- 开发者参考:
- developing/config-system.md
- 贡献:
- 贡献:
- contributing/index.md
- 赞助者:
- 赞助者:
- sponsors/index.md
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

+8
View File
@@ -0,0 +1,8 @@
{% extends "base.html" %}
{% block announce %}
<center>
SeleniumConf & AppiumConf returns on May 6-8, 2026! Join us to learn and connect with the community!
<a href="https://seleniumconf.com/">Register Now</a>
</center>
{% endblock %}
@@ -5,7 +5,7 @@
<img src="/docs/en/latest/assets/images/sponsor-logo-browserstack-dark.png" />
</a>
<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" />
<a href="https://www.testmuai.com">
<img src="/docs/en/latest/assets/images/sponsor-logo-testmuai-dark.png" />
</a>
</div>
+4 -1
View File
@@ -20,7 +20,7 @@ const {
DOCS_REMOTE,
LATEST_ALIAS,
} = require('./utils');
const path = require('path');
const path = require('node:path');
const semver = require('semver');
const {version} = require('../../package.json');
@@ -31,6 +31,9 @@ const preview = Boolean(process.env.APPIUM_DOCS_PREVIEW);
const push = Boolean(process.env.APPIUM_DOCS_PUBLISH);
/**
* Builds and optionally deploys docs for each supported language.
*/
async function main() {
log.info(`Building Appium docs and committing to ${DOCS_BRANCH}`);
@@ -3,7 +3,7 @@
/* eslint-disable promise/prefer-await-to-callbacks */
/* eslint-disable promise/prefer-await-to-then */
const path = require('path');
const path = require('node:path');
const {fs} = require('@appium/support');
const {AppiumConfigJsonSchema} = require('@appium/schema');
@@ -12,6 +12,9 @@ const DOC_PATH = path.resolve(__dirname, '..', 'en', 'cli', 'args.md');
const START_TAG = `<!-- AUTOGEN-START -->`;
const STOP_TAG = `<!-- AUTOGEN-STOP -->`;
/**
* Regenerates the CLI arguments table in docs.
*/
async function main() {
console.log(`Gathering current cli doc file contents...`);
const [preStart, postEnd] = await getDocParts();
+1 -1
View File
@@ -3,7 +3,7 @@
// for simplicity this file is not transpiled and is run directly via an npm script
//
const {logger} = require('@appium/support');
const path = require('path');
const path = require('node:path');
const log = logger.getLogger('Docs');
@@ -0,0 +1,34 @@
---
authors:
- sai
- srini
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 -->
<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" />
</a>
</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.
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
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!
@@ -7,7 +7,7 @@ title: 对Appium 的贡献
Appium项目离不开来自公司和志愿者的代码、文档、维护和支持的众多贡献。 因此,我们欢迎贡献!
有许多不同的方式可以帮助项目——请参阅下方了解您可以做的一切以及每个贡献方法的流程。 请注意,无论您如何贡献,您的参与都受我们的[行为准则](https://github.com/appium/appium/blob/master/CONDUCT.md)管辖。
有许多不同的方式可以帮助项目——请参阅下方了解您可以做的一切以及每个贡献方法的流程。 请注意,无论您如何贡献,您的参与都受我们的[行为准则](https://github.com/appium/.github/blob/master/CODE_OF_CONDUCT.md)管辖。
## 加入讨论论坛
@@ -570,6 +570,33 @@ capability), and then to set an internal field to that value, so that it can be
bidiProxyUrl`. Once all this is in place, Appium will proxy BiDi commands from the client straight
to the upstream connection.
### Understand server-assigned driver properties and security flags
When your driver is running under the main Appium server, Appium assigns a small set of
server-related properties on your driver instance when a session is created:
- `cliArgs`: Driver-specific configuration derived from the Appium server’s CLI flags and/or
configuration files (for example via the `server.driver.<your-driver-name>` section). These
options are **not** user capabilities and cannot be influenced directly by test code.
- `server`, `serverHost`, `serverPort`, `serverPath`: Information about the HTTP server that is
hosting your driver. These values reflect how the Appium server was started (for example the
`--address`, `--port`, and `--base-path` flags) and are useful when your driver needs to construct
URLs that point back to the Appium server itself (for example when setting up proxies, webhooks,
or other callbacks).
`BaseDriver` and `AppiumDriver` also cooperate to expose security-related flags on your driver
instance:
- `relaxedSecurityEnabled`: Indicates whether the server is running with relaxed security enabled
(for example via `--relaxed-security`).
- `allowInsecure`: A list of insecure features which are explicitly allowed for this driver (derived
from server-level options like `--allow-insecure`).
- `denyInsecure`: A list of insecure features which are explicitly disabled for this driver (derived
from server-level options like `--deny-insecure`).
See [Hide behaviour behind security flags](#hide-behaviour-behind-security-flags) for how to use
these flags in your driver (e.g. via `isFeatureEnabled` and `assertFeatureEnabled`).
### Extend the existing protocol with new commands
You may find that the existing commands don't cut it for your driver. If you want to expose
@@ -864,3 +891,120 @@ this.onUnexpectedShutdown(handler)
`handler` should be a function which receives an error object (representing the reason for the
unexpected shutdown).
### Send messages to plugins running on the same session
Appium's driver and plugin architecture means that a single driver and any number of plugins can be
running together for a current session. The driver and plugins don't really know anything about
each other though, which can make coordination potentially difficult. Without creating any kind of
tight coupling between drivers or plugins, it's possible for drivers and plugins to communicate
along a pub/sub style message bus. With Appium's IPC feature, "message" means a combination of
"data" (the data intended to be published or received), and metadata (timestamp, the name of the
publisher, etc...).
Drivers and plugins can implement an instance method called `async onIpcInit`, in which they will
know that the IPC channel for the session is now active. At this point, they have access to the
following methods:
#### `ipcSubscribe<T>(topic: string): IIpcSubscription`
This method allows a driver or plugin to subscribe to a topic on the IPC channel for the session.
Topics are simply strings. To coordinate effectively, drivers or plugins would use the same topic
string (so this would be something advertised in the driver/plugin documentation).
The result of this call is an `IpcSubscription` object that allows:
- Looping through messages on the topic via an async generator
- Hooking up an event handler for new messages
- Getting the last message sent on the topic
- Publishing a message to the topic
- Unsubscribing from the topic
#### `IpcSubscription` object
Here is an example of how subscribing and use of these subscription methods might work:
```ts
async onIpcInit() {
// we know at this point in our driver/plugin lifecycle that we can use IPC methods
type MyMessageData = {myData: string}; // let's say the message data for this channel has this shape
const subscription = this.ipcSubscribe<MyMessageData>('coolTopic');
// listen for new messages on topic
subscription.on('message', (message) => {
console.log(message.data); // {myData: 'something'}
});
// publish data to the topic; might throw if the data is larger than configured max size, or we
// are no longer subscribed
await subscription.publish({myData: 'hi'});
// get last message sent to topic
const {data} = subscription.getMessage() ?? {data: null};
// data = {myData: 'hi'}
// unsubscribe
subscription.unsubscribe(); // returns true if we unsubscribed and false if no subscription existed
}
```
With a subscription object, we can also iterate async over it to receive new messages:
```ts
for await (const message of subscription) {
// here we have a message and can unwrap its data
}
```
Note that the iteration will stop when the subscription ends (i.e., when `unsubscribe` is called).
You can also check whether the subscription is still active (if your subscribe and unsubscribe
logic is not locally connected):
```ts
if (subscription.isActive) {
// we know we have not yet unsubscribed
}
```
If the subscription is not active, attempts to call `subscription.publish` will throw an error.
#### `IpcMessage` object
When you get a message on a topic, it has the following shape:
```ts
export type IpcMessage<T> = {
publisher: string, // the id of the publishing object (typically of the form <ClassName>@<uniqueObjectId>)
timestampMs: number, // when the message was published, in ms since epoch
topic: string, // the topic the message was published on
data: T, // the arbitrary message data. Must be serializable and a valid argument to 'structuredClone()'
};
```
#### IPC Notes
There are some important things to keep in mind when using Appium's IPC feature:
- IPC is only available once `onIpcInit` has been called, at the end of the `createSession` flow.
It cannot be used statically or in `createSession` hooks
- In sum, IPC is only for use during a session (this is also to prevent drivers/plugins from
accessing or reading data sent on IPC channels in other sessions.)
- The default max size of an IPC message is 1MB. This can be configured by the server-admin by
using the `--max-ipc-data-size` arg (value is a number in bytes).
- If a message exceeds the configured size, any call to `publish` methods will throw, so be
sure to cover this case in your error handling.
- The default max number of IPC topics per session is 1000. This can be configured by the
server-admin using the `--max-ipc-topics` arg.
- If the topic limit is reached, calls to `subscribe` or `publish` on a new topic will throw, so
be sure to cover this case in your error handling.
- Topic names exist within a global namespace per session. So if you don't want to clash with other
drivers or plugins, make sure you prefix your topic names with something unique, akin to vendor
prefixes in the WebDriver standard (for example: `fake-driver:some-topic`). We recommend the
format `<namespace>:<topic>`.
To see examples of IPC in action, check out Appium's own
[FakeDriver](https://github.com/appium/appium/blob/master/packages/fake-driver/lib/driver.ts) and
[FakePlugin](https://github.com/appium/appium/blob/master/packages/fake-plugin/lib/plugin.ts)
extensions, which showcase several ways of using IPC messages.
@@ -518,3 +518,12 @@ async onUnexpectedShutdown(driver, cause) {
}
}
```
### Send messages to the driver or other plugins running on the same session
Even though drivers and plugins don't know anything about each other, it's possible for them to
send messages that other drivers or plugins can listen for, within the context of the same session,
using an IPC channel. Given that the developer instructions for this feature are the same for
drivers and plugins, please head over to the IPC development docs for
drivers at the driver
development guide.
@@ -29,7 +29,7 @@ In lieu of a separate file, configuration can be embedded in a project's `packag
```
When an Appium server is started via the `appium` executable, the `init` function in `lib/main.js`
will call into `lib/config-file.js` to load and/or search for a configuration file and in
will call into `lib/bootstrap/config-file.js` to load and/or search for a configuration file and in
`package.json`.
!!! note
@@ -72,7 +72,7 @@ It is more straightforward to explain how config files are validated, so we'll s
### Validating Config Files
When a config file is found (`lib/config-file.js`), it will call the `validate` function exported
When a config file is found (`lib/bootstrap/config-file.js`), it will call the `validate` function exported
from `lib/schema/schema.js` with the contents of the config file. In turn, this asks `ajv` to
validate the data against the schema that Appium has provided it.
+55 -27
View File
@@ -21,6 +21,48 @@ Appium has a graphical client which can be used to inspect application screensho
application hierarchy, search for elements, run Appium commands, record app interactions, and more.
It can be very useful for Appium test development.
\=== "Install as an Appium Plugin"
````
```bash
appium plugin install inspector
```
````
\=== "Install Standalone"
```
Download the app from the Appium Inspector repo's [GitHub Releases section](https://github.com/appium/appium-inspector/releases).
```
### [Appium MCP](https://github.com/appium/appium-mcp)
Appium MCP is a Model Context Protocol (MCP) server that provides mobile test development and
automation capabilities using Appium.
```json title="Install This Tool"
// Add the following to your MCP client configuration
{
"appium-mcp": {
"disabled": false,
"timeout": 100,
"type": "stdio",
"command": "npx",
"args": ["appium-mcp@latest"],
"env": {
"ANDROID_HOME": "/path/to/android/sdk"
}
}
}
```
### [Skills](https://github.com/appium/skills)
A set of AI Agent skills to support Appium automation, for example:
- Help preparing Appium test environment from scratch, including common driver setup
- Help preparing XCUITest driver and WebDriverAgent for real device automation
## Extension Tools
Appium driver or plugin developers can choose to include these tools in their driver/plugin:
@@ -35,7 +77,7 @@ details needed for the driver/plugin have been set up correctly. The tool can be
appium {driver|plugin} doctor <extension-name>
```
It shows no results if the driver/plugin author did not implement Doctor support.
It shows no results if the driver/plugin does not have such validation checks.
!!! note
@@ -48,6 +90,18 @@ out the documentation on [Building Doctor Checks](../developing/build-doctor-che
These tools are not maintained by the Appium team:
### [AppClaw](https://github.com/AppiumTestDistribution/AppClaw)
AppClaw is a CLI-based agentic AI layer for mobile automation, powered by [Appium MCP](#appium-mcp).
Agent instructions can be passed directly via CLI, or defined as YAML flows in either structured
or natural language syntax.
Supported by: `@AppiumTestDistribution`
```sh title="Install This Tool"
npm install -g appclaw
```
### [Appium Installer](https://github.com/AppiumTestDistribution/appium-installer)
Appium Installer is a command-line tool for simplifying setups of new Appium test environments.
@@ -59,29 +113,3 @@ Supported by: `@AppiumTestDistribution`
```sh title="Install This Tool"
npm install -g appium-installer
```
### [Jarvis Appium](https://github.com/AppiumTestDistribution/mcp-appium)
Jarvis Appium is a Model Context Protocol (MCP) server that provides mobile test development and
automation capabilities using Appium.
Supported by: `@AppiumTestDistribution`
```json title="Install This Tool"
// Add the following to your MCP client configuration
{
"mcpServers": {
"jarvis-appium": {
"disabled": false,
"timeout": 100,
"type": "stdio",
"command": "npx",
"args": ["jarvis-appium"],
"env": {
"ANDROID_HOME": "/path/to/android/sdk",
"CAPABILITIES_CONFIG": "/path/to/your/capabilities.json"
}
}
}
}
```
+50 -55
View File
@@ -2,14 +2,14 @@
title: Session Capabilities
---
"Capabilities" is the name given to the set of parameters used to start an Appium session. The
information in the set describes what sort of "capabilities" you want your session to have, for
example, a certain mobile operating system or a certain version of a device. Capabilities are
represented as key-value pairs, with values allowed to be any valid JSON type, including
other objects.
Capabilities are the core parameters used to start an Appium session. They describe various
features that you want your session to have, for example, a certain mobile operating system or a
certain version of a device. Capabilities are represented as key-value pairs, with values allowed
to be any valid JSON type, including other objects. Most importantly, they cannot be changed
during the lifecycle of the session.
The W3C WebDriver spec's [section on Capabilities](https://w3c.github.io/webdriver/#capabilities)
identifies a small set of 10 standard capabilities, including the following:
The capabilities used in Appium follow [the W3C WebDriver specification of the same name](https://w3c.github.io/webdriver/#capabilities).
The WebDriver spec defines a small set of standard capabilities, including the following:
| Capability Name | Type | Description |
| ---------------- | -------- | ---------------------------------------------- |
@@ -17,68 +17,64 @@ identifies a small set of 10 standard capabilities, including the following:
| `browserVersion` | `string` | The specific version of the browser |
| `platformName` | `string` | The type of platform hosting the browser |
While the above capabilities are commonly used by Appium drivers, they are not sufficient for
describing Appium-specific features, such as the name of the driver to use, or the name of the app
to launch. In order to achieve this, Appium defines its own [extension capabilities](https://w3c.github.io/webdriver/#dfn-extension-capability).
## Common Appium Capabilities
Appium understands these browser-focused capabilities, but introduces a number of additional
capabilities. According to the WebDriver spec, any
non-standard "extension capabilities" must include a namespace prefix (signifying the vendor
introducing the capability), ending in a `:`. Appium's vendor prefix is
`appium:`, and so any Appium-specific capabilities must include this prefix. Depending on which
client you are using, 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.
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
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.
Here is a list of all the globally-recognized Appium capabilities:
Here are a few commonly (but not universally!) used Appium-specific capabilities:
!!! info
| Capability Name | Type | Description |
| ----------------------- | -------- | --------------------------------------------------------------- |
| `appium:automationName` | `string` | The name of the Appium driver to use |
| `appium:udid` | `string` | The unique device identifier of a particular device to automate |
| `appium:app` | `string` | The path to an installable application |
```
Individual drivers and plugins can support other capabilities, so refer to their documentation
for lists of specific capability names. Some drivers may also not support all of these capabilities
```
All capabilities recognized by the Appium base driver (inherited by all drivers) can be found in the
[Capabilities Reference document](../reference/session/caps.md). While this common capability set
is fairly small, it can be greatly extended by Appium drivers and plugins, who can (and should)
define their own capabilities. Make sure to reference their documentation to learn more about the
capabilities they support. You can find a list of known drivers in the [Ecosystem Drivers](../ecosystem/drivers.md) document.
| <div style="width:12em">Capability</div> | Type | Required? | Description |
| ---------------------------------------- | --------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `platformName` | `string` | yes | The type of platform hosting the app or browser |
| `appium:automationName` | `string` | yes | The name of the Appium driver to use |
| `browserName` | `string` | no | The name of the browser to launch and automate, if the driver supports web browsers as a special case |
| `appium:app` | `string` | no | The path to an installable application |
| `appium:deviceName` | `string` | no | The name of a particular device to automate, e.g., `iPhone 14` (currently only actually useful for specifying iOS simulators, since in other situations it's typically recommended to use a specific device id via the `appium:udid` capability). |
| `appium:platformVersion` | `string` | no | The version of a platform, e.g., for iOS, `16.0` |
| `appium:newCommandTimeout` | `number` | no | The number of seconds the Appium server should wait for clients to send commands before deciding that the client has gone away and the session should shut down. `60` seconds by default. Setting it to zero disables the timer. |
| `appium:noReset` | `boolean` | no | If true, instruct an Appium driver to avoid its usual reset logic during session start and cleanup (default `false`) |
| `appium:fullReset` | `boolean` | no | If true, instruct an Appium driver to augment its usual reset logic with additional steps to ensure maximum environmental reproducibility (default `false`) |
| `appium:eventTimings` | `boolean` | no | If true, instruct an Appium driver to collect [Event Timings](./event-timing.md) (default `false`) |
| `appium:printPageSourceOnFindFailure` | `boolean` | no | If true, collect the page source and print it to the Appium log whenever a request to find an element fails (default `false`) |
Drivers are also able to place more complex constraints on capabilities as a group. For example,
the XCUITest driver recommends that at least one of `browserName`, `appium:app`, or `appium:bundleId`
is included in the capabilities, otherwise it will not be able to auto-install or auto-launch any
application. Each driver will document how it interprets these capabilities and any other
platform-specific requirements.
Some drivers place more complex constraints on capabilities as a group. For example, while the
`appium:app` and `browserName` capabilities are listed above as optional, if you want to launch
a session with a specific app, the XCUITest driver requires that at least one of `appium:app`,
`browserName`, or `appium:bundleId` are included in the capabilities (otherwise it will not know
what app to install and/or launch and will simply open a session on the home screen). Each driver
will document how it interprets these capabilities and any other platform-specific requirements.
The way to construct capabilities and start a session will likely differ depending on your Appium
client. For examples of doing this in each client library, head to the [Ecosystem Clients](../ecosystem/clients.md)
page and click through to the appropriate client documentation.
!!! note
```
Capabilities are like parameters used when starting a session. After the capabilities are sent
and the session is started, they cannot be changed. If a driver supports updating aspects of
its behaviour in the course of a session, it will provide a [Setting](./settings.md) for this
purpose instead of, or in addition to, a capability.
Once your capabilities are sent to the server and the session is started, they cannot be
changed. If a driver supports updating its behaviour during a session, it will use the
[Settings API](./settings.md) for this purpose.
```
Each Appium client has its own way of constructing capabilities and starting a session. For
examples of doing this in each client library, head to the [Ecosystem](../ecosystem/index.md) page
and click through to the appropriate client documentation.
## BiDi Protocol Support
Appium supports [WebDriver BiDi](https://w3c.github.io/webdriver-bidi/) protocol since base–driver 9.5.0.
The actual behavior depends on individual drivers while the Appium and the baseーdriver support the protocol.
Please make sure if a driver supports the protocol and what kind of commands/events it supports in the documentation.
In addition to the standard WebDriver protocol (now known as WebDriver Classic), Appium supports the
[WebDriver BiDi](https://w3c.github.io/webdriver-bidi/) protocol. Support for this protocol is
opt-in, and requires the use of the standard `webSocketUrl` capability.
| Capability Name | Type | Description |
| --------------- | --------- | ------------------------------------------------------- |
| `webSocketUrl` | `boolean` | To enable BiDi protocol in the session. |
| Capability Name | Type | Description |
| --------------- | --------- | ----------------------------------------------- |
| `webSocketUrl` | `boolean` | Whether BiDi protocol is enabled in the session |
All BiDi commands supported by the Appium base driver (inherited by all drivers) can be found in the
[BiDi Protocol API Reference document](../reference/api/bidi.md). Similarly to WebDriver Classic
commands, individual Appium drivers and plugins can define their own supported standard and custom
BiDi commands, so make sure to reference their documentation.
## Using `appium:options` to Group Capabilities
@@ -124,8 +120,7 @@ creates in response to a new session request. This is through the concept of "al
!!! note
```
Check out the [spec itself](https://w3c.github.io/webdriver/#processing-capabilities) or
a [summarized version](https://github.com/jlipps/simple-wd-spec#processing-capabilities) for
Check out the [spec itself](https://w3c.github.io/webdriver/#processing-capabilities) for
a more in-depth description of how capabilities are processed.
```
+35 -35
View File
@@ -3,27 +3,27 @@ title: Appium Server Security
---
The Appium team makes every effort to ensure the security of the Appium server. This is especially
important when Appium is run in a multitenant environment, or when multiple users are running
sessions on the same Appium server. In general, you can only safely enable all Appium's features if
all the following are true:
important when Appium is run in a multi-tenant environment, or when multiple users are running
sessions on the same Appium server. To ensure a safe environment for Appium's purposes, all of the
following should be true:
- You're running your own Appium server locally or within a protected internal network
- You're not sharing it with any untrusted parties
- You don't expose Appium's port(s) to the wider internet
But because many Appium users might not be able to guarantee such a safe environment, the Appium
team puts many features behind a security protection mechanism which forces system admins (the
people that are in charge of starting the Appium server) to _explicitly opt-in_ to these features.
(Third-party driver and plugin authors can also hide behaviour behind security
flags.)
But because not all Appium hosts can guarantee such a safe environment, certain insecure Appium
features are disabled by default, and require explicit opt-in in order to enable them. Most
importantly, this can _only_ be done by the Appium server _host_, and Appium _client_ sessions are
not allowed to change this.
For security reasons, Appium client sessions can _not_ request feature enablement via capabilities;
this is the responsibility of the server admin who configures and launches the Appium server.
While it is possible for an Appium host to simply enable all insecure features at once, each
feature also has a unique name, which can be used for granular control over the server state.
## Security Server Args
The [Server CLI](../reference/cli/server.md) doc outlines three relevant arguments which may be passed to
Appium when starting it from the command line:
Enabling or disabling insecure features is done via [Appium server launch arguments](../reference/cli/server.md)
or [configuration file](./config.md). The former document outlines three relevant arguments for
achieving this:
| <div style="width:10em">Parameter</div> | Description |
| --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
@@ -31,36 +31,30 @@ Appium when starting it from the command line:
| `--allow-insecure` | Turns on _only_ specified features, except those blocked by `--deny-insecure`. Has no effect when used in combination with `--relaxed-security` |
| `--deny-insecure` | Explicitly turns _off_ specified features, overriding `--relaxed-security` and `--allow-insecure` |
All of the above arguments can also be specified in the [Appium Configuration file](./config.md).
Features passed to `--allow-insecure`/`--deny-insecure` must be specified as a comma-separated list,
and each feature in the list must additionally include a prefix, indicating the driver to which the
feature should apply. The prefix can be either the driver's `automationName`, or the wildcard (`*`)
symbol, if the feature should be applied to all drivers. The prefix and feature name are separated
using the colon character (`:`).
and each feature in the list must additionally include a prefix, indicating the driver to whose
sessions the feature should apply. The prefix can be either the driver's `automationName`, or the
wildcard (`*`) symbol, if the feature should be applied to all drivers. The prefix and feature name
are separated using the colon character (`:`).
For example, `first:foo` refers to the `foo` feature for the `first` driver, whereas `*:bar` refers
to the `bar` feature for all drivers.
## Insecure Features
Each Appium driver is responsible for its own security, and can create its own feature names. Thus
you should read through the documentation for a particular driver to know which feature names it
might use. Here is an incomplete list of examples from some of Appium's official drivers:
Almost all insecure features are defined on a per-driver or plugin basis, so make sure to read the
documentation for a particular driver/plugin to know which feature names it might use.
| <div style="width:12em">Feature Name</div> | Description | Supported Extension(s) |
| ------------------------------------------ | --------------------------------------------------------------------------------------- | ---------------------------------------------- |
| `get_server_logs` | Allows retrieving of Appium server logs via the Webdriver log interface | IOS, XCUITest, Android, UiAutomator2, Espresso |
| `adb_shell` | Allows execution of arbitrary shell commands via ADB, using the `mobile: shell` command | Android, UiAutomator2, Espresso |
| `record_audio` | Allow recording of host machine audio inputs | XCUITest |
| `execute_driver_script` | Allows to send a request which has multiple Appium commands. | Execute Driver Plugin |
Certain insecure features are also defined on the Appium server itself. For a list of these
features, as well as the features defined in official plugins, see
[the Insecure Features CLI Reference](../reference/cli/insecure-features.md) doc.
Some insecure features operate on the server level, and do not require a driver session. Enabling
these features requires using the wildcard prefix:
!!! note
| <div style="width:12em">Feature Name</div> | Description |
| ------------------------------------------ | ------------------------------------------------------------------------------- |
| `session_discovery` | Allows retrieving the list of active server sessions via `GET /appium/sessions` |
```
If you are a driver or plugin author and want to implement insecure features of your own, check
out the [Building Drivers documentation](../developing/build-drivers.md#understand-server-assigned-driver-properties-and-security-flags).
```
## Examples
@@ -73,17 +67,23 @@ appium --allow-insecure=first:foo
Turn on the `foo` feature for all drivers:
```bash
appium --allow-insecure=*:foo
appium --allow-insecure='*:foo'
```
Turn on the `foo` feature for all drivers _except_ `first`:
```bash
appium --allow-insecure=*:foo --deny-insecure=first:foo
appium --allow-insecure='*:foo' --deny-insecure=first:foo
```
Turn on all features _except_ `foo` for all drivers:
```bash
appium --relaxed-security --deny-insecure=*:foo
appium --relaxed-security --deny-insecure='*:foo'
```
Turn on multiple insecure features for specific drivers:
```bash
appium --allow-insecure=uiautomator2:adb_shell,xcuitest:get_server_logs
```
+3 -3
View File
@@ -29,9 +29,9 @@ title: 欢迎使用
</a>
</div>
<div class="homepageSponsor">
<a href="https://lambdatest.com/?utm_source=appium.io&utm_medium=organic&utm_campaign=june_25&utm_term=sk&utm_content=webpage">
<img src="assets/images/sponsor-logo-lambdatest-dark.png#only-dark" style="width: 220px;" />
<img src="assets/images/sponsor-logo-lambdatest-light.png#only-light" style="width: 220px;" />
<a href="https://www.testmuai.com">
<img src="assets/images/sponsor-logo-testmuai-dark.png#only-dark" style="width: 220px;" />
<img src="assets/images/sponsor-logo-testmuai-light.png#only-light" style="width: 220px;" />
</a>
</div>
</div>
+52 -161
View File
@@ -1,200 +1,91 @@
---
title: How Does Appium Work?
title: Appium 如何工作?
---
As mentioned on the main page, Appium is an open-source project and ecosystem of related software,
designed to facilitate UI automation of many app platforms. With the release of Appium 2, Appium
has the following primary goals:[^1]
正如主页所述,Appium 是一个开源项目和相关软件生态系统,旨在促进多种应用平台的 UI 自动化。 随着 Appium 2 的发布,Appium 具有以下主要目标:[^1]
- Make platform-specific automation capabilities available under a cross-platform, standard API
- Allow easy access to this API from any programming language
- Provide tools to enable convenient community development of Appium extensions
- 在跨平台标准 API 下提供特定于平台的自动化功能
- 允许从任何编程语言轻松访问此 API
- 提供工具以便社区方便地开发 Appium 扩展
[^1]: To meet these primary goals, we also work with a set of secondary goals or methodology
principles, which we also encourage for Appium extension developers:
[^1]: 为实现这些主要目标,我们还遵循一套次要目标或方法原则,我们也鼓励 Appium 扩展开发者遵循这些原则:
- As far as possible, rely on (and contribute to) open source technology
- As far as possible, rely on vendor-provided tools for a given platform
- As far as possible, rely on automation tools that allow automation of unmodified apps (prefer
not to require the user to build in additional SDKs or software that introduce discrepancies
between the test version of the app and the production version)
- As far as possible, rely on existing standards instead of creating new ones
- 尽可能依赖(并贡献于)开源技术
- 尽可能依赖给定平台的供应商提供的工具
- 尽可能依赖不修改应用就能实现自动化(最好不要要求用户构建额外的 SDK 或软件,从而在测试版本和生产版本之间引入差异)的自动化工具
- 尽可能依赖现有标准而不是创建新标准
So, take any app platform you know about, like iOS or Android. Appium wants for there to be a way
for developers and testers to write UI automation code for that platform, according to a single,
unified API. Based on Appium's goals, we have a lot of questions to answer to make it all work:
所以,以您了解的任何应用平台为例,如 iOS 或 Android。 Appium 希望开发者测试人员能够为该平台编写 UI 自动化代码,根据单一的统一 API。 根据 Appium 的目标,我们有很多问题需要回答以使其全部工作:
- Which API should that "single, unified" API be?
- How do we map that API to automation behaviour for a specific platform?
- How do we make that API accessible via multiple popular programming languages?
- “单一统一”的 API 应该是什么?
- 我们如何将此 API 映射到特定平台的自动化行为?
- 我们如何使此 API 通过多种流行编程语言访问?
There's another, larger, question lurking in the background here too, given that there are more app
platforms out there than just iOS and Android:
这里还有另一个更大的问题,鉴于除了 iOS 和 Android 之外还有更多应用平台:
- How do we enable automation for _all_ the platforms?
- 我们如何为_所有_平台启用自动化?
Exploring Appium's answers to these questions may not be the quickest way to learn what Appium is,
but it is certainly a good one! So let's dive in.
探索 Appium 对这些问题的答案可能不是学习 Appium 是什么的最快方式,但它肯定是一个好方法! 所以让我们深入了解。
## Appium's choice of API
## Appium 的 API 选择
Appium is very fortunate to have been preceded by a technology which has been a long-standing
pioneer in the field of UI automation, namely [Selenium](https://selenium.dev). The goal of the
Selenium project has been to support UI automation of web browsers, and in this way we can think of
it as occupying a subset of Appium's goals. Along the way, Selenium (and, after they merged,
another project called WebDriver) developed a relatively stable API for browser automation.
Appium 非常幸运地继承了一个在 UI 自动化领域长期领先的技术,即 [Selenium](https://selenium.dev)。 Selenium 项目的目标是支持 Web 浏览器的 UI 自动化,因此我们可以将其视为占据 Appium 目标子集的一部分。 在此过程中,Selenium(以及后来合并的另一个名为 WebDriver 的项目)开发了一个相对稳定的浏览器自动化 API。
Over the years, Selenium worked with various web browser vendors and the [W3C](https://w3.org)
standards group to turn its API into an official web browser standard, called the WebDriver
specification. All the main browsers now
implement automation capabilities inline with the WebDriver spec, without the Selenium team having
to maintain any software that performs actual automation; standards for the win!
多年来,Selenium 与各种 Web 浏览器供应商和 [W3C](https://w3.org) 标准小组合作,将其 API 转变为官方 Web 浏览器标准,称为 [WebDriver 规范](https://w3c.github.io/webdriver/)。
所有主要浏览器现在都实现了符合 WebDriver 规范的自动化功能,而无需 Selenium 团队维护任何执行实际自动化的软件;标准获胜!
Appium's initial goals were to develop an automation standard for mobile apps (iOS and Android). We
could have made up something new, but in the spirit of joining forces and keeping standards, well,
standard, we decided to adopt the WebDriver spec as Appium's API.[^2] While user interaction on
websites and in mobile native apps are not entirely identical (with even greater differences once
we start to consider, for example, TV platforms controlled by simple remotes), the fact is that
most software UIs are pretty much the same. This means that the WebDriver spec provides automation
API primitives (finding elements, interacting with elements, loading pages or screens, etc...) that
more or less map to any platform.
Appium 的最初目标是为移动应用(iOS 和 Android)开发自动化标准。 我们本可以发明一些新的东西,但为了团结力量并保持标准的标准化,我们决定采用 WebDriver 规范作为 Appium 的 API。[^2] 虽然网站和移动原生应用的用户交互并不完全相同(一旦我们开始考虑例如由简单遥控器控制的电视平台,差异会更大),但事实是大多数软件 UI 都非常相似。 这意味着 WebDriver 规范提供了自动化 API 原语(查找元素、与元素交互、加载页面或屏幕等) 这些原语或多或少映射到任何平台。
[^2]: Technically, when Appium was first written, we were dealing with something older than the
WebDriver spec, called the JSON Wire Protocol. Since then, Appium continued to evolve along with
the W3C spec and is fully W3C-compliant.
[^2]: 从技术上讲,当 Appium 首次编写时,我们处理的是比 WebDriver 规范更古老的东西,称为 JSON Wire Protocol。 从那时起,Appium 继续与 W3C 规范一起演化,并完全符合 W3C 规范。
Of course, Appium wants to support the cases where user interaction _does_ differ from web to
mobile or web to TV, and so Appium also makes use of the built-in _extensibility_ of the WebDriver
spec. The result is that, no matter what platform you want to automate, when you use Appium, you
will do so using the standard WebDriver spec, with two caveats:
当然,Appium 希望支持用户交互从 Web 到移动或 Web 到电视确实不同的情况,因此 Appium 还利用 WebDriver 规范的内置_可扩展性_。 结果是,无论您想要自动化哪个平台,当您使用 Appium 时,您将使用标准 WebDriver 规范,但有两个注意事项:
- We might not have any way to support a particular WebDriver API command on a given platform, and
so some commands might be unsupported (for example, getting or setting cookies is not possible in
the world of native mobile app automation).
- We might support automation behaviours that go _beyond_ what's available in the WebDriver API
command list, though any such commands will be valid and spec-compliant extensions to the
WebDriver API.
- 我们可能无法在给定平台上支持特定的 WebDriver API 命令,因此某些命令可能不受支持(例如,在原生移动应用自动化世界中,获取或设置 cookie 是不可能的)。
- 我们可能支持超出 WebDriver API 命令列表的自动化行为,尽管任何此类命令将是有效的、符合规范的 WebDriver API 扩展。
How do you actually _use_ the WebDriver API, particularly in the context of Appium? We'll cover
that in the [section below](#universal-programming-language-access) on how Appium provides
universal programming language access. All you need to know for now is that the way Appium
introduces a universal UI automation interface is by implementing the WebDriver protocol.
您实际上如何_使用_ WebDriver API,特别是 Appium 的背景下? 我们将在下面的[部分](#universal-programming-language-access)中介绍 Appium 如何提供通用编程语言访问。 您现在只需要知道 Appium 通过实现 WebDriver 协议来引入通用 UI 自动化接口。
## Platform automation behaviour
## 平台自动化行为
The next question is, how does Appium map this protocol to automation behaviour on a wide range of
platforms? The trick is that, strictly speaking, Appium doesn't! It leaves this responsibility up
to a kind of software module called an Appium _driver_. There's a whole Driver
Introduction which you can read next, so we won't go into huge detail on how they
work for now.
下一个问题是,Appium 如何将此协议映射到广泛平台的自动化行为? 严格来说,Appium 没有! 它将此责任留给一种称为 Appium _驱动程序_ 的软件模块。 您可以阅读整个[驱动程序](./drivers.md)的介绍,所以我们现在不会深入细节。
What's important to understand at the moment is that a driver is kind of like a pluggable module
for Appium that gives Appium the power to automate a particular platform (or set of platforms,
depending on the goal of the driver). At the end of the day, a driver's responsibility is to simply
implement an Appium-internal interface representing the WebDriver protocol. How it implements this
interface is totally up to the driver, based on its strategy for making automation happen on
a specific platform. Typically, and with a lot more complexity and difficulty in the details,
a driver does this by relying on platform-specific automation technologies. For example, Apple
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 because ultimately what it does is
convert the WebDriver protocol to XCUITest library calls.
目前重要的是要理解驱动程序有点像 Appium 的可插拔模块,它赋予 Appium 自动化特定平台(或平台集,取决于驱动程序的目标)的能力。 最终,驱动程序的责任只是实现代表 WebDriver 协议的 Appium 内部接口。 它如何实现此接口完全取决于驱动程序,基于其在特定平台上实现自动化的策略。 通常,在细节上具有更多复杂性和难度,驱动程序通过依赖特定于平台的自动化技术来实现这一点。 例如,Apple 维护一种称为 [XCUITest](https://developer.apple.com/documentation/xctest/user_interface_tests) 的 iOS 自动化技术。 支持 iOS 应用自动化的 Appium 驱动程序称为 [XCUITest 驱动程序](https://github.com/appium/appium-xcuitest-driver),因为它最终所做的是将 WebDriver 协议转换为 XCUITest 库调用。
One of the reasons that drivers are independent, pluggable modules is that they work completely
differently from one another. The tools and requirements for building and using drivers for
different platforms are completely different. And so Appium lets you use just the drivers that you
need for your automation tasks. Choosing drivers and installing them so that you can use them with
your Appium instance is so important that Appium has its very own CLI for managing
drivers.
驱动程序是独立、可插拔模块的原因之一是它们彼此完全不同。 构建和使用不同平台的驱动程序的工具和要求完全不同。 因此,Appium 让您只使用您自动化任务所需的驱动程序。 选择驱动程序并安装它们以便与您的 Appium 实例一起使用非常重要,以至于 Appium 有自己的 [CLI 来管理驱动程序](../reference/cli/extensions.md)。
So, to answer our original question, the way that Appium provides access to automation capabilities
for a given platform is that the Appium team (or anyone else[^3]) writes a _driver_ for that
platform, implementing as much or little of the WebDriver protocol as desired. The driver can then
be installed by anyone using Appium.
因此,为了回答我们最初的问题,Appium 为给定平台提供自动化功能访问的方式是 Appium 团队(或任何人[^3])为该平台编写一个_驱动程序_,实现 WebDriver 协议的尽可能多或少的部分。 然后,任何使用 Appium 的人都可以安装驱动程序。
[^3]: You can build and share your own drivers! Check out Building
Drivers to learn more about how to develop drivers in Node.js
that can be used with Appium.
[^3]: 您可以构建和分享自己的驱动程序! 查看[构建驱动程序](../developing/build-drivers.md)以了解更多关于如何在 Node.js 中开发可与 Appium 一起使用的驱动程序的信息。
## Universal programming language access
## 通用编程语言访问
But what does it mean, or look like, to _use_ Appium, anyway? Since Appium is ultimately a Node.js
program, it _could_ have looked like importing Appium and its drivers as libraries into your own
Node.js programs. But that wouldn't meet Appium's goal of providing automation capabilities to
people using any popular programming language.
但使用 Appium 意味着什么,或者看起来像什么? 由于 Appium 最终是一个 Node.js 程序,它_可以_看起来像将 Appium 及其驱动程序作为库导入到您自己的 Node.js 程序中。 但这不会满足 Appium 的目标,即为使用任何流行编程语言的人提供自动化功能。
Luckily, the fact that Appium rode in on Selenium's coattails meant that we had a solution to this
problem from day one. You see, the WebDriver specification is actually an HTTP-based protocol,
meaning it is designed to be used over a network rather than within the memory of a single program.
幸运的是,Appium 继承 Selenium 的遗产意味着我们从一开始就有了这个问题的解决方案。 您看,WebDriver 规范实际上是一个基于 HTTP 的协议,这意味着它被设计为通过网络而不是单个程序的内存使用。
One of the main benefits of this "client-server" architecture is that it allows the automation
implementer (the thing doing the automation, in this case the 'server') to be completely distinct
from the automation runner (the thing defining what automation should be done, in what steps,
etc..., in this case the 'client'). Basically, all the "hard stuff" (actually figuring out how to
make automation happen on a given platform) can be handled in one place by the server, and "thin"
client libraries can be written in any programming language which simply encode HTTP requests to
the server in language-appropriate way. It's possible, in other words, to bring basic Appium
/ WebDriver capabilities to a new programming language relatively easily, assuming high-level HTTP
libraries exist, simply by coding up a basic HTTP client in that language.
这种“客户端-服务器”架构的主要好处之一是,它允许自动化实现者(执行自动化的事物,在这种情况下是“服务器”)与自动化运行者(定义应该做什么自动化、以什么步骤等的事物,在这种情况下是“客户端”)完全不同。 基本上,所有“困难的东西”(弄清楚如何在给定平台上实现自动化)可以在服务器的一个地方处理,“瘦”客户端库可以在任何编程语言中编写,这些库只需以适合语言的方式编码对服务器的 HTTP 请求。 换句话说,假设存在高级 HTTP 库,只需在该语言中编写基本的 HTTP 客户端,就可以相对容易地将基本的 Appium / WebDriver 功能引入新的编程语言。
There are a couple important takeaways here for you, the Appium user:
这里有几个重要的点供 Appium 用户了解:
- Appium is an _HTTP server_. It must run as a process on some computer for as long as you want to
be able to use it for automation. It must be accessible on the network to whichever computer you
want to use to run the automation from (whether that is the same machine or one across the
world).
- Unless you want to write raw HTTP calls or use cURL, using Appium for automation involves the use
of an [Appium Client](clients.md) in the language of your choice. The goal of each of these
clients is to encapsulate the WebDriver protocol so that rather than worrying about the protocol
itself, you can work with objects and methods that feel idiomatic for your language.
- The Appium server and the Appium client do _not_ need to be running on the same computer. You
simply need to be able to send HTTP requests from the client to the server over some network.
This greatly facilitates the use of cloud providers for Appium, since they can host the Appium
server and any related drivers and devices, and all you need to do is point your client script to
their secure endpoints.
- Appium 是一个_HTTP 服务器_。 只要您想使用它进行自动化,它必须在某台计算机上作为进程运行。 它必须在网络上可访问,以方便您想要运行自动化的任何计算机访问(无论是同一台机器还是世界另一端的机器)。
- 除非您想编写原始 HTTP 调用或使用 cURL,否则请使用您选择的语言的 [Appium 客户端](clients.md)进行自动化。 每个客户端的目标是将 WebDriver 协议封装,以便您不必担心协议本身,而是可以使用感觉适合您语言的对象和方法。
- Appium 服务器和 Appium 客户端_不需要_在同一台计算机上运行。 您只需能够通过某个网络从客户端向服务器发送 HTTP 请求。
这大大促进了云提供商对 Appium 的使用,因为他们可以托管 Appium 服务器以及任何相关驱动程序和设备,您只需将客户端脚本指向他们的安全端点。
And of course, none of this is about "testing" per se, purely about the use of Appium and its
client libraries for automation purposes. If you want to do automation for the purpose of
"testing", you'll likely want to enlist the help of test runners, test frameworks, and the like,
none of which need be related to Appium; one of the benefits of Appium's "universal accessibility"
is that it plays well with whatever set of tools you find most beneficial for your situation.
当然,这一切都不是关于“测试”本身,只是出于自动化目的使用 Appium 及其客户端库。 如果您想出于“测试”目的进行自动化,您可能希望利用测试运行器、测试框架等的帮助,这些都不需要与 Appium 相关;Appium“通用可访问性”的好处之一是它与您发现最适合您情况的任何工具集配合良好。
## Appium's huge scope
## Appium 的巨大范围
Appium's vision (automation of everything under a single API) is huge! Certainly, much bigger than
the team of core maintainers for the open source project. So how does Appium hope to achieve this
goal? Basically, by empowering the community to develop functionality on top of Appium as
a _platform_. This is what we call the Appium "ecosystem".
Appium 的愿景(在单一 API 下自动化一切)是巨大的! 当然,比开源项目的核心维护者团队大得多。 那么 Appium 如何希望实现这一目标? 基本上,通过授权社区在 Appium 之上作为_平台_开发功能。 这就是我们所谓的 Appium“生态系统”。
The Appium team does officially maintain a few drivers itself (for example, the XCUITest driver
that we spoke about earlier). But it cannot hope to have the platform-specific expertise or the
capacity to maintain drivers for many different platforms. But what we have done, particularly
beginning with Appium 2, is to provide tools to empower the community to join in our vision:
Appium 团队确实自己维护了一些驱动程序(例如,我们之前讨论的 XCUITest 驱动程序)。 但它无法拥有特定于平台的专业知识或维护许多不同平台的驱动程序的能力。 但我们所做的,特别是从 Appium 2 开始,是提供工具来授权社区加入我们的愿景:
- Anyone can create a driver simply by creating a Node.js module that conforms to the appropriate
conventions and implements any (sub|super)set of the WebDriver protocol. Creating a driver often
involves a minimal amount of code because the WebDriver protocol details are abstracted away, and
many helper libraries are available---the same libraries that power the Appium team's own
drivers.
- Sharing drivers with others is easy using the Appium driver CLI. There is no central authority.
Anyone can share drivers publicly or privately, for free or for sale. Drivers can be open or
closed source (though obviously we appreciate open source!).
- 任何人都可以通过创建一个符合适当约定并实现 WebDriver 协议的任何(子|超)集的 Node.js 模块来创建驱动程序。 创建驱动程序通常涉及最少的代码,因为 WebDriver 协议细节被抽象化,许多帮助库可用---这些库为 Appium 团队自己的驱动程序提供动力。
- 使用 Appium 驱动程序 CLI 与他人分享驱动程序很容易。 没有中央权威。
任何人都可以公开或私下分享驱动程序,免费或收费。 驱动程序可以是开源或闭源的(尽管我们欣赏开源!)。
Appium's vision of being a platform for development extends beyond the support of automation for
all app platforms. As a popular automation tool, there are many opportunities for integrating
Appium with all kinds of other tools and services. In addition, there are many feature ideas for
Appium, either as a core server or in its incarnation across various drivers, which the core team
will never have time to build. And so, with Appium 2, Appium has released a plugin system that
enables anyone to build and share modules that change how Appium works!
Appium 作为开发平台的愿景超越了对所有应用平台自动化支持。 作为一个流行的自动化工具,有许多机会将 Appium 与各种其他工具和服务集成。 此外,Appium 有许多功能想法,要么作为核心服务器,要么在其各种驱动程序中的化身,核心团队没有足够的时间构建。 因此,Appium 2 发布了一个插件系统,使任何人都可以构建和分享改变 Appium 工作方式的模块!
In the same way that drivers are easily shareable and consumable via the Appium driver CLI, plugins
can be published and consumed via a parallel [Plugin CLI](../reference/cli/extensions.md). Plugins
can do all sorts of things, for example adding the ability for Appium to find and interact with
screen regions based on a template image (as in the images). There are very few
limitations on what you can do with plugins, so you might also be interested in learning how to
[Build Plugins](../developing/build-plugins.md) in Node.js that can be used with Appium.
就像驱动程序可以通过 Appium 驱动程序 CLI 轻松分享和消费一样,插件可以通过[插件 CLI](../reference/cli/extensions.md)发布和消费。 插件可以做各种事情,例如添加 Appium 根据模板图像查找和与屏幕区域交互的能力(例如[图像插件](https://github.com/appium/appium/tree/master/packages/images-plugin))。 插件几乎没有限制,所以您可能也对学习如何在 Node.js 中[构建插件](../developing/build-plugins.md)以与 Appium 一起使用感兴趣。
So that's Appium: an extensible, universal interface for the UI automation of potentially
everything! Read on into some of the specific intro docs for more details, or check out the various
guides to dive into some more general concepts and features of Appium.
所以这就是 Appium:一个可扩展的、潜在一切的 UI 自动化通用接口! 继续阅读一些具体的介绍文档以获取更多细节,或查看各种指南以深入了解 Appium 的一些更一般概念和功能。
+22 -61
View File
@@ -2,57 +2,31 @@
hide:
- toc
title: Intro to Appium Clients
title: Appium 客户端简介
---
For all the reasons discussed in the [main Overview](./appium.md), Appium is based on the W3C
WebDriver specification. This means that
Appium implements a client-server architecture. The server (consisting of Appium itself along with
any drivers or plugins you are using for automation) is connected to the devices under test, and
is actually responsible for making automation happen on those devices. The client (driven by _you_,
the Appium test author) is responsible for sending commands to the server over the network, and
receiving responses from the server as a result. These responses can be used to tell whether
automation commands are successful, or might contain information that you queried about the state
of the application. This document is a conceptual introduction to the client side of this equation.
出于[概述](./appium.md)中讨论的所有原因,Appium 基于 [W3C WebDriver 规范](https://w3c.github.io/webdriver/)。 这意味着 Appium 实现了客户端-服务器架构。 服务器(由 Appium 本身以及您用于自动化的任何驱动程序或插件组成)连接到测试设备,并实际负责在这些设备上实现自动化。 客户端(由_您_驱动,Appium 测试作者)负责通过网络向服务器发送命令,并接收来自服务器的响应。 这些响应可用于判断自动化命令是否成功,或可能包含您查询的关于应用程序状态的信息。 本文档是对客户端方面的概念性介绍。
!!! info
```
For more about the server side of the equation (i.e., how does Appium actually control
devices?), check out our [Intro to Appium Drivers](./drivers.md). To skip to a list of links to
Appium client libraries, check out the [list of clients](../ecosystem/clients.md).
有关服务器端的信息(即 Appium 如何实际控制设备?),请查看我们的 [Appium 驱动程序简介](./drivers.md)。要跳转到 Appium 客户端库链接列表,请查看[客户端列表](../ecosystem/clients.md)。
```
What sorts of automation commands are available? That is up to the particular driver and plugins
that you are using in any given session. A standard set of commands would include, for example, the
following:
有哪些自动化命令可用? 那取决于您在任何给定会话中使用的特定驱动程序和插件。 一组标准命令可能包括以下内容:
- Find Element
- Click Element
- Get Page Source
- Take Screenshot
- 查找元素
- 点击元素
- 获取页面源代码
- 截取屏幕截图
If you look at these commands in the WebDriver specification, you'll notice that they are not
defined in terms of any particular programming language. They are not Java commands, or JavaScript
commands, or Python commands. Instead, they form part of an HTTP API which can be accessed from
within _any_ programming language (or none! you could just use cURL if you want).
如果您查看 WebDriver 规范中的这些命令,您会注意到它们不是以任何特定编程语言定义的。 它们不是 Java 命令、JavaScript 命令或 Python 命令。 相反,它们形成了可以通过_任何_编程语言访问的 HTTP API( 如果您愿意,您可以只使用 cURL)。
So, for example, the `Find Element` command corresponds to an HTTP `POST` request sent to the HTTP
endpoint `/session/:sessionid/element` (where in this case, `:sessionid` is a placeholder for the
unique session ID generated by the server in a previous call to `Create Session`).
例如,`查找元素`命令对应于发送到 HTTP 端点 `/session/:sessionid/element` 的 HTTP `POST` 请求(其中`:sessionid` 是服务器在之前 `创建会话` 调用中生成的唯一会话 ID 的占位符)。
This information is primarily useful for people developing technology that works with the WebDriver
spec. It's not particularly useful for people trying to write Appium or Selenium tests. When you
write an Appium test, you want to use a programming language you're familiar with. Luckily, there
exist a set of [Appium client libraries](../ecosystem/clients.md)[^1] that take care of the
responsibility of speaking HTTP to the Appium server. Instead, they expose a set of "native"
commands for a particular programming language, so that, to the test author, it just feels like
you're writing Python, or JavaScript, or Java.
此信息主要对开发与 WebDriver 规范一起工作的技术的人有用。 它对试图编写 Appium 或 Selenium 测试的人不是特别有用。 当您编写 Appium 测试时,您希望使用您熟悉的编程语言。 幸运的是,存在一组 [Appium 客户端库](../ecosystem/clients.md)[^1],它们负责向 Appium 服务器发起HTTP 的请求。 它们为特定编程语言公开了一组“原生”命令,以便对测试作者来说,它就像您在编写 Python、JavaScript 或 Java。
As an example, here's the same simple set of Appium commands in five different programming
languages, using the recommended Appium client binding for each language (note that this is not
working sample code including all appropriate imports; see each client library's instructions for
setup and command reference):
以下是使用 Appium 客户端在五种不同编程语言中实现相同的 Appium 命令集的示例(注意,这不是包含所有导入的工作示例代码;请参阅每个客户端库的设置和命令参考说明):
\=== "JavaScript (Webdriver.io)"
@@ -109,31 +83,18 @@ System.Console.WriteLine(driver.PageSource);
```
````
Each of these scripts, despite being in different languages, does the same thing under the hood:
尽管这些脚本使用不同的编程语言,但它们在底层做的事情是相同的:
1. Call `Find Element` with a `using` parameter of `xpath` and a `value` parameter expressing the
XPath query used to find an element. (If you're confused about these terms, you might find an
introduction to Appium or Selenium useful)
2. Call `Click Element` with the ID of the element found in the previous call.
3. Call `Get Element Text` with the ID of the same element, and print it to the console.
4. Call `Get Page Source` to retrieve the page/app source and print it to the console.
1. 调用 `Find Element`,使用 `using` 参数值为 `xpath`,以及 `value` 参数表达用于查找元素的 XPath 查询。 (如果你对这些术语感到困惑,可以参考 Appium 或 Selenium 的入门介绍)
2. 使用在上一次调用中找到的元素 ID 调用 `Click Element`。
3. 使用同一元素的 ID 调用 `Get Element Text`,并将其打印到控制台。
4. 调用 `Get Page Source` 来检索页面/应用程序源代码并将其打印到控制台。
The only other thing to keep in mind before choosing or using a client is that each client is
independently maintained. Just because a feature is available in one client, it doesn't mean it's
available in another client (though all clients support at least the standard W3C protocol plus any
common appium extensions). Just because one client has a nice set of helper functions, doesn't mean
another will. Some clients are kept very frequently up to date, and others are not! So when
thinking about choosing a library, the first consideration is the language you want to use, and the
second consideration is how full-featured and well-maintained the library is!
在选择或使用客户端之前,需要记住的另一件事是每个客户端都是独立维护的。 仅仅因为某个功能在一个客户端中可用,并不意味着它在另一个客户端中也可用(尽管所有客户端至少支持标准的 W3C 协议以及任何常见的 Appium 扩展)。 仅仅因为一个客户端有一套很好的辅助函数,并不意味着另一个客户端也会有。 有些客户端更新非常频繁,而其他客户端则不然! 因此,在考虑选择一个库时,首要考虑的是你想使用的语言,第二个考虑因素是该库的功能完善程度和维护情况!
To learn how to use an Appium client, visit that client's homepage to learn more. In many cases,
the Appium client for a given language is built _on top of_ the _Selenium_ client for that
language, and so certain Appium clients may only document the features which the Appium client
added on top of the Selenium client. All that to say, for a full reference, you may need to visit
both the Appium client documentation as well as the Selenium client documentation.
要学习如何使用 Appium 客户端,请访问该客户端的主页以了解更多信息。 在许多情况下,特定语言的 Appium 客户端是在该语言的 _Selenium_ 客户端之上构建的,因此某些 Appium 客户端可能只记录 Appium 客户端在 Selenium 客户端基础上添加的功能。 也就是说,要获得完整的参考,你可能需要访问 Appium 客户端文档以及 Selenium 客户端文档。
That's all you need to know about Appium clients! Head over to the
[Clients](../ecosystem/clients.md) page to check out the current list of clients.
这就是你需要了解的关于 Appium 客户端的全部内容! 前往 [客户端](../ecosystem/clients.md) 页面查看当前的客户端列表。
[^1]: These libraries are alternately called "clients", "client libraries", or "client bindings".
They all mean the same thing!
[^1]: 这些库也被称为"客户端"、"客户端库"或"客户端绑定"。
它们的意思都是一样的!
+53 -140
View File
@@ -1,22 +1,14 @@
---
title: Intro to Appium Drivers
title: Appium 驱动程序介绍
---
As the [main Overview](./appium.md) makes clear, "drivers" are basically Appium's answer to the
question, "how do we support automation of multiple, unrelated platforms?" In this doc we'll get
into a little more detail about how drivers work. The specific details of how drivers work probably
don't matter too much for you, unless you're planning on writing your own driver or contributing to
an existing driver (things we hope you do!).
正如[概览](./appium.md)所阐明的那样,"驱动程序"基本上是 Appium 对"我们如何支持多个不相关平台的自动化?"这一问题的答案。 在本文档中,我们将更详细地了解驱动程序的工作原理。 驱动程序工作的具体细节对你来说可能并不那么重要,除非你打算编写自己的驱动程序或为现有驱动程序做贡献(我们希望你这样做!)。
The main benefit in understanding a bit more of how drivers work is that being aware of the typical
complexity or the typical driver architecture will inform your debugging process when you
inevitably run into an issue in one of your tests.
了解更多驱动程序工作原理的主要好处是,了解典型的复杂性或典型的驱动程序架构将有助于你在测试中遇到问题时进行调试。
## Interface Implementations
## 接口实现
At the most basic level, drivers are simply Node.js classes that extend a special class included in
Appium, called `BaseDriver`. You could have something very close to a "working" driver, with these
very simple lines of code:
在最基本的层面上,驱动程序只是扩展了 Appium 中包含的一个特殊类的 Node.js 类,这个类叫做 `BaseDriver`。 你可以用以下非常简单的几行代码就拥有一个非常接近"可工作"的驱动程序:
```js
import BaseDriver from '@appium/base-driver'
@@ -25,21 +17,11 @@ class MyNewDriver extends BaseDriver {
}
```
This empty driver doesn't _do_ anything, but you could wrap it up in a Node.js module, add a few
Appium-related fields to the module's manifest (`package.json`), and then install it using `appium
driver install`.
这个空驱动程序不会_做_任何事情,但你可以将它打包成一个 Node.js 模块,在模块的清单文件(`package.json`)中添加一些与 Appium 相关的字段,然后使用 `appium driver install` 安装它。
So, from a technical perspective, an Appium driver is just a bit of code that inherits from some
other Appium code. That's it! Now, inheriting from `BaseDriver` actually gives us a lot, because
`BaseDriver` is essentially an encapsulation of the entire WebDriver protocol. So all a driver
needs to do something useful is to _implement_ Node.js methods with names corresponding to
their WebDriver protocol equivalents.
因此,从技术角度来看,Appium 驱动程序只是一些继承自其他 Appium 代码的代码。 就是这样! 现在,继承自 `BaseDriver` 实际上给了我们很多东西,因为 `BaseDriver` 本质上是整个 WebDriver 协议的封装。 所以驱动程序要做一些有用的事情,只需要_实现_名称与其 WebDriver 协议等效的 Node.js 方法。
So let's say I wanted to do something with this empty driver; first I have to decide which
WebDriver command I want to implement. For our example, let's take the Navigate
To WebDriver command. Leave aside for the moment
what I want to have the driver _do_ when this command is executed. To tell Appium the driver can
handle the command, all we have to do is define a method like this in our driver class:[^1]
假设我想用这个空驱动程序做点什么;首先我必须决定要实现哪个 WebDriver 命令。 对于我们的例子,让我们选择[Navigate To](https://w3c.github.io/webdriver/#navigate-to) WebDriver 命令。 暂时不考虑当这个命令执行时我想让驱动程序_做_什么。 要告诉 Appium 驱动程序可以处理这个命令,我们所要做的就是在驱动程序类中定义一个像这样的方法:[^1]
```js
async setUrl(url) {
@@ -47,142 +29,73 @@ 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).
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!
[^1]: 你可能会注意到 `setUrl` 看起来与 `Navigate To` 完全不同,那么我们怎么知道使用它而不是其他随机字符串呢? 其实,Appium 的 WebDriver 协议到方法名的映射是在 `@appium/base-driver` 包中的一个特殊文件中定义的,叫做 [routes.js](https://github.com/appium/appium/blob/master/packages/base-driver/lib/protocol/routes.js)。
所以如果你正在编写驱动程序,这就是你要去找出要使用什么方法名和期望什么参数的地方。 或者你可以查看任何主要 Appium 驱动程序的源代码!
That's it! How we actually implement the command is totally up to us, and depends on the
platform(s) we want to support. Here are some different example implementations of this command for
different platforms:
就是这样! 我们如何实际实现该命令完全取决于我们自己,并取决于我们想要支持的平台。 以下是针对不同平台的此命令的一些不同示例实现:
- Browsers: execute some JavaScript to set `window.location.href`
- iOS apps: launch an app using a deep link
- Android apps: launch an app using a deep link
- React apps: load a specific route
- Unity: go to a named scene
- 浏览器:执行一些 JavaScript 来设置 `window.location.href`
- iOS 应用:使用深度链接启动应用
- Android 应用:使用深度链接启动应用
- React 应用:加载特定路由
- Unity:转到指定场景
So you can see there can be a lot of differences between how drivers implement the same WebDriver
command across platforms.[^2] What is the _same_, though, is how they express that they can handle
a protocol command.
因此,你可以看到,不同平台上驱动程序实现相同 WebDriver 命令的方式可能存在很大差异。[^2] 然而,_相同_的是它们表达可以处理协议命令的方式。
[^2]: Of course, we want to keep the semantics as similar as possible, but in the world of iOS, for
example, launching an app via a deep link (a URL with a special app-specific scheme) is about as
close as we are going to get to navigating to a web URL.
[^2]: 当然,我们希望保持语义尽可能相似,但在 iOS 的世界里,例如,通过深度链接(具有特殊应用特定方案的 URL)启动应用是我们最接近导航到 Web URL 的方式。
We're going into this great amount of detail (which you don't need to remember, by the way),
because it's important to stress the point that an Appium driver is not inherently anything in
particular, other than a bit of JS code that can handle WebDriver protocol commands. Where you go
from there is up to you, the driver author!
我们之所以如此详细地讨论(顺便说一下,你不需要记住这些),是因为重要的是要强调一点,Appium 驱动程序本质上不是任何特定的东西,只是一些可以处理 WebDriver 协议命令的 JS 代码。 从那里去哪里取决于你,驱动程序作者!
## 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
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.
但_通常_驱动程序作者想要做的是为给定的平台提供自动化行为,这些行为在语义上与浏览器的 WebDriver 规范实现非常相似。 当你想查找一个元素时,你应该得到一个 UI 元素的引用。 当你想点击或轻触该元素时,产生的行为应该与人点击或轻触该元素相同。 等等。
So the real challenge for driver authors is not how to work with the WebDriver protocol (because
`BaseDriver` encapsulates all that for you), but how to make the actual automation happen on the
target platform. Every driver relies on its own set of underlying technologies here. As mentioned
in the [Overview](index.md), the iOS driver uses an Apple technology called
[XCUITest](https://developer.apple.com/documentation/xctest/xcuielement). These underlying
automation technologies usually have proprietary or idiosyncratic APIs of their own. Writing
a driver becomes the task of mapping the WebDriver protocol to this underlying API (or sometimes
a set of different underlying APIs--for example, the UiAutomator2 driver relies not only on the
[UiAutomator2](https://developer.android.com/training/testing/other-components/ui-automator)
technology from Google, but also functions only available through
[ADB](https://developer.android.com/tools/adb), as well as functions only available
via the Android SDK inside a helper app). Tying it all together into a single, usable, WebDriver
interface is the incredibly useful (but incredibly challenging) art of driver development!
因此,驱动程序作者面临的真正挑战不是如何使用 WebDriver 协议(因为 `BaseDriver` 为你封装了所有这些),而是如何在目标平台上实现实际的自动化。 每个驱动程序都依赖于自己的一套底层技术。 正如[概览](index.md)中提到的,iOS 驱动程序使用 Apple 的一项名为 [XCUITest](https://developer.apple.com/documentation/xctest/xcuielement) 的技术。 这些底层自动化技术通常都有自己专有或特殊的 API。 编写驱动程序就是将 WebDriver 协议映射到这个底层 API 的任务(有时是一组不同的底层 API——例如,UiAutomator2 驱动程序不仅依赖于 Google 的 [UiAutomator2](https://developer.android.com/training/testing/other-components/ui-automator) 技术,还依赖于只能通过 [ADB](https://developer.android.com/tools/adb) 获得的功能,以及只能通过辅助应用内的 Android SDK 获得的功能)。 将所有这些整合到一个单一、可用的 WebDriver 接口中,是驱动程序开发这项非常有用(但极具挑战性)的艺术!
## Multi-level architecture
## 多层架构
In practice, this often results in a pretty complex architecture. Let's take iOS for example again.
The XCUITest framework (the one used by the Appium driver) expects code that calls it to be written
in Objective-C or Swift. Furthermore, XCUITest code can only be run in a special mode triggered by
Xcode (and directly or indirectly, the Xcode command line tools). In other words, there's no
straightforward way to go from a Node.js function implementation (like `setUrl()` above) to
XCUITest API calls.
在实践中,这通常会导致相当复杂的架构。 让我们再次以 iOS 为例。
XCUITest 框架(Appium 驱动程序使用的框架)期望调用它的代码用 Objective-C 或 Swift 编写。 此外,XCUITest 代码只能在由 Xcode(以及直接或间接的 Xcode 命令行工具)触发的特殊模式下运行。 换句话说,没有直接的方法从 Node.js 函数实现(如上面的 `setUrl()`)到 XCUITest API 调用。
What the XCUITest driver authors have done is instead to split the driver into two parts: one part
written in Node.js (the part which is incorporated into Appium and which initially handles the
WebDriver commands), and the other part written in Objective-C (the part which actually gets run on
an iOS device and makes XCUITest API calls). This makes interfacing with XCUITest possible, but
introduces the new problem of coordination between the two parts.
XCUITest 驱动程序作者所做的是将驱动程序分成两部分:一部分用 Node.js 编写(这部分被整合到 Appium 中并最初处理 WebDriver 命令),另一部分用 Objective-C 编写(这部分实际在 iOS 设备上运行并进行 XCUITest API 调用)。 这使得与 XCUITest 的接口成为可能,但引入了两部分之间协调的新问题。
The driver authors could have chosen any of a number of very different strategies to model the
communication between the Node.js side and the Objective-C side, but at the end of the day decided
to use ... the WebDriver protocol! That's right, the Objective-C side of the XCUITest driver is
itself a WebDriver implementation, called
[WebDriverAgent](https://github.com/appium/webdriveragent).[^3]
驱动程序作者本可以选择许多非常不同的策略来建模 Node.js 端和 Objective-C 端之间的通信,但最终决定使用……
WebDriver 协议! 没错,XCUITest 驱动程序的 Objective-C 端本身就是一个 WebDriver 实现,称为 [WebDriverAgent](https://github.com/appium/webdriveragent)。[^3]
[^3]: You could in theory, therefore, point your WebDriver client straight to WebDriverAgent and
bypass Appium entirely. This is usually not convenient, however, for a few reasons:
[^3]: 因此,理论上你可以将你的 WebDriver 客户端直接指向 WebDriverAgent 并完全绕过 Appium。 然而,这通常不方便,原因如下:
- The Appium XCUITest driver builds and manages WebDriverAgent for you, which can be a pain and
involves the use of Xcode.
- The XCUITest driver does lots more than what can be done by WebDriverAgent, for example working
with simulators or devices, installing apps, and the like.
- Appium XCUITest 驱动程序会为你构建和管理 WebDriverAgent,这可能很麻烦并涉及使用 Xcode。
- XCUITest 驱动程序做的事情远不止 WebDriverAgent 所能做的,例如使用模拟器或设备、安装应用等。
The moral of the story is that driver architectures can become quite complicated and multilayered,
due to the nature of the problem we're trying to solve. It also means it can be difficult sometimes
to tell where in this chain of technologies something has gone wrong, if you run into a problem
with a particular test. With the XCUITest world again, we have something like the following set of
technologies all in play at the same time:
这个故事的寓意是,由于我们试图解决的问题的性质,驱动程序架构可能会变得相当复杂和多层。 这也意味着,如果你在特定测试中遇到问题,有时很难判断这一系列技术中的哪个环节出了问题。 再以 XCUITest 为例,我们同时使用以下一组技术:
- Your test code (in its programming language) - owned by you
- The Appium client library - owned by Appium
- The Selenium client library - owned by Selenium
- The network (local or Internet)
- The Appium server - owned by Appium
- The Appium XCUITest driver - owned by Appium
- WebDriverAgent - owned by Appium
- Xcode - owned by Apple
- XCUITest - owned by Apple
- iOS itself - owned by Apple
- macOS (where Xcode and iOS simulators run) - owned by Apple
- 你的测试代码(使用其编程语言)- 由你拥有
- Appium 客户端库 - 由 Appium 拥有
- Selenium 客户端库 - 由 Selenium 拥有
- 网络(本地或互联网)
- Appium 服务器 - 由 Appium 拥有
- Appium XCUITest 驱动程序 - 由 Appium 拥有
- WebDriverAgent - 由 Appium 拥有
- Xcode - 由 Apple 拥有
- XCUITest - 由 Apple 拥有
- iOS 本身 - 由 Apple 拥有
- macOS(运行 Xcode 和 iOS 模拟器的地方)- 由 Apple 拥有
It's a pretty deep stack!
这是一个相当深的技术栈!
## Proxy mode
## 代理模式
There's one other important architectural aspect of drivers to understand. It can be exemplified
again by the XCUITest driver. Recall that we just discussed how the two "halves" of the XCUITest
driver both speak the WebDriver protocol---the Node.js half clicks right into Appium's WebDriver
server, and the Objective-c half (WebDriverAgent) is its own WebDriver implementation.
还有一个关于驱动程序的重要架构方面需要了解。 可以再次用 XCUITest 驱动程序来举例说明。 回想一下我们刚才讨论的 XCUITest 驱动程序的两个"部分"是如何都使用 WebDriver 协议的——Node.js 部分直接连接到 Appium 的 WebDriver 服务器,而 Objective-C 部分(WebDriverAgent)本身就是一个 WebDriver 实现。
This opens up the possibility of Appium taking a shortcut in certain cases. Let's imagine that the
XCUITest driver needs to implement the `Click Element` command. The internal code of this
implementation would look something like taking the appropriate parameters and constructing an HTTP
request to the WebDriverAgent server. In this case, we're basically just reconstructing the
client's original call to the Appium server\![^4] So there's really no need to even write a function
implementing the `Click Element` command. Instead, the XCUITest driver can just let Appium know
that this command should be proxied directly to some other WebDriver server.
这为 Appium 在某些情况下走捷径开辟了可能性。
让我们想象一下 XCUITest 驱动程序需要实现 `Click Element` 命令。 这个实现的内部代码看起来就像是获取适当的参数并构造一个到 WebDriverAgent 服务器的 HTTP 请求。 在这种情况下,我们基本上只是在重建客户端对 Appium 服务器的原始调用![^4] 所以实际上没有必要编写一个函数来实现 `Click Element` 命令。 相反,XCUITest 驱动程序可以让 Appium 知道这个命令应该直接代理到其他 WebDriver 服务器。
[^4]: It's not _exactly_ the same call, because the Appium server and the WebDriverAgent server
will generate different session IDs, but these differences will be handled transparently.
[^4]: 这不是_完全_相同的调用,因为 Appium 服务器和 WebDriverAgent 服务器会生成不同的会话 ID,但这些差异会被透明地处理。
If you're not familiar with the concept of "proxying," in this case it just means that the XCUITest
driver will not be involved at all in handling the command. Instead it will merely be repackaged
and forwarded to WebDriverAgent at the protocol level, and WebDriverAgent's response will likewise
be passed back directly to the client, without any XCUITest driver code seeing it or modifying it.
如果你不熟悉"代理"的概念,在这种情况下,它只是意味着 XCUITest 驱动程序根本不会参与处理该命令。 相反,它只会在协议级别被重新打包并转发到 WebDriverAgent,WebDriverAgent 的响应同样会直接传回客户端,而不会有任何 XCUITest 驱动程序代码看到或修改它。
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
example, you'll see that it implements basically no standard commands, because all of these are
proxied directly to an underlying SafariDriver process.
这种架构模式为选择在各处使用 WebDriver 协议而不是构建定制协议的驱动程序作者提供了一个很好的额外好处。 这也意味着 Appium 可以非常轻松地为任何其他现有的 WebDriver 实现创建包装驱动程序。 例如,如果你查看 [Appium Safari 驱动程序](https://github.com/appium/appium-safari-driver)代码,你会发现它基本上没有实现任何标准命令,因为所有这些命令都直接代理到底层的 SafariDriver 进程。
It's important to understand that this proxying business is sometimes happening under the hood,
because if you're ever diving into some open source driver code trying to figure out where
a command is implemented, you might be surprised to find no implementation at all in the Node.js
driver code itself! In that case, you'll need to figure out where commands are being proxied to so
you can look there for the appropriate implementation.
了解这种代理机制有时在幕后发生是很重要的,因为如果你曾经深入研究一些开源驱动程序代码试图找出命令的实现位置,你可能会惊讶地发现 Node.js 驱动程序代码本身根本没有任何实现! 在这种情况下,你需要找出命令被代理到哪里,以便你可以在那里查找相应的实现。
OK, that's enough for this very detailed introduction to drivers!
好了,对于这个非常详细的驱动程序介绍来说,这就足够了!
+36 -160
View File
@@ -1,196 +1,72 @@
---
title: Appium Project History
title: Appium 项目历史
---
Appium has been around in one form or another since 2012. It's been under the
direction of various individuals and organizations, and it's even been
implemented in 3 different programming languages! Welcome to more than you ever
wanted to know about how Appium got to be what is it today...
Appium 自 2012 年以来以某种形式存在。 它由不同的个人和组织指导,甚至用 3 种不同的编程语言实现过! 欢迎了解关于 Appium 如何发展到今天这个样子的更多信息……
## Early Inspiration
## 早期灵感
[Dan Cuellar](https://twitter.com/thedancuellar) was the Test Manager at Zoosk
in 2011, when he encountered a problem. The length of the test passes on the
iOS product was getting out of hand. Less testing was an option, but would come
with additional risk, especially with it taking several days to get patches
through the iOS App Store Review process. He thought back to his days working
on websites and realized automation was the answer.
[Dan Cuellar](https://twitter.com/thedancuellar) 在 2011 年担任 Zoosk 的测试经理时遇到了一个问题。 iOS 产品的测试通过时间变得越来越长,难以控制。 减少测试是一个选择,但会带来额外的风险,特别是在通过 iOS App Store 审核流程获得补丁需要几天时间的情况下。 他回想起自己在网站上工作的日子,意识到自动化是答案。
Dan surveyed the existing landscape of tools, only to find that all of them
hand major drawbacks. The tool supplied by Apple, UIAutomation, required tests
to be written in JavaScript, and did not allow for real-time debugging or
interpretation. It also had to be executed inside the Xcode profiling tool,
Instruments. Other 3rd-party tools used private APIs and required SDKs and HTTP
Servers to be embedded into the application. This seemed highly undesirable.
Dan 调查了现有的工具格局,却发现它们都有重大缺陷。 Apple 提供的工具 UIAutomation 要求测试必须用 JavaScript 编写,并且不允许实时调试或解释。 它还必须在 Xcode 的性能分析工具 Instruments 中执行。 其他第三方工具使用私有 API,并要求将 SDK 和 HTTP 服务器嵌入到应用程序中。 这看起来非常不可取。
Unsatisfied with the existing options, Dan asked his manager for some
additional time to see if he could find a better way. He spent 2 weeks poking
and prodding around to see if there was a way to use approved Apple
technologies to automate an iOS application. The first implementation he tried
used AppleScript to send messages to Mac UI elements using the OS
X accessibility APIs. This worked to some degree, but would never work on real
devices, not to mention other drawbacks.
对现有选项不满意,Dan 向他的经理要求一些额外的时间,看看他能否找到更好的方法。 他花了 2 周时间探索和试验,看看是否有办法使用 Apple 批准的技术来自动化 iOS 应用程序。 他尝试的第一个实现使用 AppleScript 通过 OS X 辅助功能 API 向 Mac UI 元素发送消息。 这在一定程度上有效,但永远无法在真实设备上工作,更不用说其他缺点了。
So he thought, what if I could get the UIAutomation framework to run in real
time like an interpreter? He looked into it and he determined that all he would
need to do is find a way to receive, execute, and reply to commands from within
a UIAutomation javascript program. Using the utility Apple provided for
executing shell commands he was able to `cat` sequentially ordered text files
to receive commands, `eval()` the output to execute them, and write them back
to disk with `python`. He then prepared code in C# that implemented the
Selenium-style syntax to write the sequentially ordered javascript commands.
iOSAuto is born.
所以他想,如果我能让 UIAutomation 框架像解释器一样实时运行会怎样? 他研究了一下,确定他所需要做的就是找到一种方法在 UIAutomation JavaScript 程序中接收、执行和回复命令。 使用 Apple 提供的用于执行 shell 命令的实用程序,他能够 `cat` 顺序排列的文本文件来接收命令,`eval()` 输出以执行它们,并用 `python` 将它们写回磁盘。 然后他用 C# 准备了实现 Selenium 样式语法的代码来编写顺序排列的 JavaScript 命令。
iOSAuto 诞生了。
## Selenium Conference 2012
## 2012 年 Selenium 大会
Dan was selected to speak at Selenium Conference 2012 in London about an
entirely different topic. As part of his presentation, he showed off iOS
Automation using Selenium syntax to demonstrate writing platform-agnostic tests
that use separate platform-specific page objects with a common interface. To
his surprise, the cool test architecture would take a backseat to the spectacle
of iOS tests running like WebDriver tests. Several people suggested that he
give a lightning talk later in the conference to explain exactly how it worked.
Dan 被选中在 2012 年伦敦 Selenium 大会上就一个完全不同的主题发表演讲。 作为他演讲的一部分,他展示了使用 Selenium 语法的 iOS 自动化,以演示编写平台无关的测试,这些测试使用具有通用接口的独立平台特定页面对象。 令他惊讶的是,酷炫的测试架构让 iOS 测试像 WebDriver 测试一样运行。 有几个人建议他稍后在会议上做一个闪电演讲来解释它是如何工作的。
On the second day of the conference, Dan stepped up on stage to give the
lightning talk. Jason Huggins, co-creator of Selenium, moderated the lightning
talks. Dan experienced technical difficulties getting his presentation to
load, and Jason nearly had to move on to the next lightning talk. At the last
moment, the screen turned on and Dan jumped into his presentation. He explained
the details of his implementation and how it worked, begged for contributors,
and in five minutes it was over. The crowd applauded politely, and he left the
stage.
在会议的第二天,Dan 走上舞台做闪电演讲。 Jason Huggins,Selenium 的共同创建者,主持了闪电演讲。 Dan 在加载演示文稿时遇到了技术困难,Jason 几乎不得不继续下一个闪电演讲。 在最后一刻,屏幕亮了,Dan 开始了他的演讲。 他解释了他的实现细节和工作原理,恳求贡献者,五分钟后就结束了。 观众礼貌地鼓掌,他离开了舞台。
## The Phone Rings
## 电话响起
Four months after the Selenium Conference, Jason called Dan. Jason had been
working on iOS testing support for a client at Sauce Labs. Jason remembered
Dan's lightning talk and thought the project might be useful to Jason's work,
but Dan's source code was not public. Jason asked Dan to meet up. Later that
week, Dan met Jason in a bar in San Francisco and showed him the source code
for iOS Auto.
Selenium 大会四个月后,Jason 打电话给 Dan。 Jason 一直在 Sauce Labs 为客户开发 iOS 测试支持。 Jason 记得 Dan 的闪电演讲,认为这个项目可能对 Jason 的工作有用,但 Dan 的源代码没有公开。 Jason 要求 Dan 见面。 那周晚些时候,Dan 在旧金山的一家酒吧见到了 Jason,并向他展示了 iOS Auto 的源代码。
A long-time open source advocate, Jason encouraged Dan to release his code
under an open source license. In August, Dan released the source
code
on GitHub in C#. Jason encouraged Dan to change the language to make the
project more appealing to potential contributors. Dan uploaded a new version
in
Python.
In September, Jason added a web server and began to implement the WebDriver
wire
protocol
over HTTP, making iOS Auto scriptable from any Selenium WebDriver client
library in any language.
作为一个长期的开源倡导者,Jason 鼓励 Dan 在开源许可下发布他的代码。 8 月,Dan 在 GitHub 上发布了 [C# 的源代码](https://github.com/penguinho/appium-old/commit/3ab56d3a5601897b2790b5256351f9b5af3f9e90)。 Jason 鼓励 Dan 更改语言以使项目对潜在贡献者更具吸引力。 Dan 上传了 [Python 的新版本]](https://github.com/penguinho/appium-old/commit/9b891207be0957bf209a77242750da17d3eb8eda)。
9 月,Jason 添加了一个 Web 服务器并开始通过 HTTP 实现 [WebDriver 协议](https://github.com/hugs/appium-old/commit/ae8fe4578640d9af9137d0546190fa29317d1499),使 iOS Auto 可以从任何语言的任何 Selenium WebDriver 客户端库编写脚本。
## The Mobile Testing Summit
## 移动测试峰会
Jason decided that the project should be presented at the Mobile Testing
Summit in November, but suggested that the
project get a new name first. Many ideas were thrown out and they settled on
AppleCart. A day later, while he was perusing some of Apple's guidance on
copyright and trademarks, Jason noticed that under the section of examples for
names Apple would defend its trademarks against, the first example was
"AppleCart". He called Dan and informed him of the situation, and they
brainstormed for a bit before Jason hit the jackpot. Appium... Selenium for
Apps.
Jason 决定该项目应该在 11 月的[移动测试峰会](https://twitter.com/mobtestsummit)上展示,但建议项目首先改个新名字。 人们提出了许多想法,他们最终选定了 AppleCart。 一天后,当 Jason 浏览 Apple 关于版权和商标的一些指导时,他注意到在 Apple 会保护其商标的名称示例部分下,第一个例子是"AppleCart"。 他打电话给 Dan 并告知了情况,他们集思广益了一会儿,然后 Jason 中了大奖。 Appium…… 应用程序的 Selenium。
## Sauce Labs and Node.js
## Sauce Labs 和 Node.js
In January 2013, not long after the Mobile Testing Summit, Sauce Labs decided
to fully back Appium and provide more developer power. A task force was created
to evaluate the current state and how best to move forward with the project.
The team, which included Jonathan Lipps (the current project lead), decided
that Appium needed a rebirth, and ultimately settled on Node.js as the
framework to use. Node is well-known as a fast and efficient web server
backend, and at the end of the day, Appium is just a highly-specialized web
server. It was also decided that JavaScript as a language was accessible enough
that Appium would be able to grow into a larger community of open-source
developers with JavaScript than the other options on the table.
2013 年 1 月,也就是移动测试峰会后不久,Sauce Labs 决定全力支持 Appium 并提供更多开发人员力量。 创建了一个工作组来评估当前状态以及如何最好地推进该项目。
该团队包括 Jonathan Lipps(现任项目负责人),他们决定 Appium 需要重生,并最终选择 Node.js 作为使用的框架。 Node 以快速高效的 Web 服务器后端而闻名,而归根结底,Appium 只是一个高度专业化的 Web 服务器。 还决定将 JavaScript 作为一种语言足够易于访问,使得 Appium 能够发展成为一个比其他选项更大的开源开发者社区。
In just a few days, the team leveraged the existing work on Appium and had
a new version of Appium with as much functionality as the previous Python
version. The foundation had been laid for Appium's basic architecture, and we
have been successfully building on it since. A few weeks into this sprint,
Jonathan Lipps was formally designated project lead and he began to strategize
how to get more people from the community involved with Appium's development.
仅仅几天之内,团队就利用 Appium 的现有工作,创建了一个与之前 Python 版本功能相当的新版本 Appium。 为 Appium 的基本架构奠定了基础,从那时起我们一直在成功地构建它。 在这次冲刺开始几周后,Jonathan Lipps 被正式指定为项目负责人,他开始制定战略,如何让更多来自社区的人参与 Appium 的开发。
## Appium Around the World
## Appium 走向世界
Ultimately, Jonathan decided that getting Appium in front of as many developers
at conferences and meetups was the best way to attract users and contributions.
Appium in its new incarnation was debuted at the Google Test Automation
Conference 2013. Later in 2013,
Appium was presented at conferences and meetups all around the US, as well as
in England, Poland, Portugal, and Australia. Notably, Jonathan had Appium
[perform as instruments in a band](https://www.youtube.com/watch?v=zsbNVkayYRQ)
and Dan Cuellar put together a fun Appium video
montage for Selenium Conference.
最终,Jonathan 决定在会议和聚会上让尽可能多的开发者了解 Appium 是吸引用户和贡献的最佳方式。
Appium 的新版本在 [2013 年谷歌测试自动化大会](https://www.youtube.com/watch?v=1J0aXDbjiUE)上首次亮相。 2013 年晚些时候,Appium 在美国各地以及英国、波兰、葡萄牙和澳大利亚的会议和聚会上展示。 值得注意的是,Jonathan 让 Appium [作为乐队中的乐器表演](https://www.youtube.com/watch?v=zsbNVkayYRQ),Dan Cuellar 为 Selenium 大会制作了一个有趣的 [Appium 视频集锦](https://www.youtube.com/watch?v=xkzrEn0v0II)。
But during all these presentations and conferences, the project continued to
develop. Early in 2013 we released Android and Selendroid support, making
Appium the first truly cross-platform automation framework. The project also
continued to attract users and contributors, and by the end of 2013, we'd
already had well over 1,000 commits.
在所有这些演讲和会议期间,项目继续发展。 2013 年初,我们发布了 Android 和 Selendroid 支持,使 Appium 成为第一个真正的跨平台自动化框架。 该项目还继续吸引用户和贡献者,到 2013 年底,我们已经有超过 1,000 次提交。
## The Road to Appium 1.0
## 通往 Appium 1.0 之路
Appium began to grow and mature significantly. In May 2014,
we released Appium 1.0, which stood as a milestone in Appium's development.
Appium was given
[various](https://www.prnewswire.com/news-releases/black-duck-announces-black-duck-open-source-rookies-of-the-year-winners-242383341.html)
[awards](https://www.infoworld.com/article/2241247/164642-bossie-awards-2014-the-best-open-source-application-development-tools.html)
and became the most popular open-source cross-platform mobile automation
framework. Stability improved, bugs were prioritized and fixed, and features
added. Sauce Labs increased the number of developers it donated to working
on Appium, but the entire community stayed involved in guiding the project and
contributing to it, and project governance continued to happen in the open, on
public mailing lists and GitHub's issue tracker.
Appium 开始显著增长和成熟。 2014 年 5 月,我们发布了 Appium 1.0,这是 Appium 发展的一个里程碑。
Appium 获得了[各种](https://www.prnewswire.com/news-releases/black-duck-announces-black-duck-open-source-rookies-of-the-year-winners-242383341.html)[奖项](https://www.infoworld.com/article/2241247/164642-bossie-awards-2014-the-best-open-source-application-development-tools.html),并成为最受欢迎的开源跨平台移动自动化框架。 稳定性得到改善,错误得到优先处理和修复,功能得到添加。 Sauce Labs 增加了捐赠给 Appium 工作的开发者数量,但整个社区继续参与指导项目并为其做出贡献,项目治理继续在公开的邮件列表和 GitHub 的问题跟踪器上进行。
## The Appium Umbrella Broadens
## Appium 扩大
Eventually, it became clear that the Appium codebase was not optimized for
a large team of distributed, sometime contributors. We took the opportunity as
a committer team to rewrite Appium from the ground up, using a more modern
version of the JavaScript language, and redoing Appium's architecture so that
it was easy for users or third-party developers to build their own Appium
"drivers". We wanted for it to be easier for new contributors to get ramped up
on the Appium codebase, and to see support for new platforms added to Appium by
groups other than the core team. That vision has begun to be fulfilled, with
groups like Microsoft and Youi.tv adding drivers to Appium for Windows desktop
app automation and Youi.tv app automation, respectively.
最终,很明显 Appium 代码库没有针对大型分布式团队的兼职贡献者进行优化。 作为提交者团队,我们借此机会从头开始重写 Appium,使用更现代的 JavaScript 语言版本,并重做 Appium 的架构,使用户或第三方开发者可以轻松构建自己的 Appium"驱动程序"。 我们希望新贡献者更容易熟悉 Appium 代码库,并看到核心团队以外的团队为 Appium 添加对新平台的支持。 这一愿景已经开始实现,微软和 Youi.tv 等团体分别为 Windows 桌面应用程序自动化和 Youi.tv 应用程序自动化向 Appium 添加了驱动程序。
## Appium To The People
## Appium 献给人民
In late 2016, Sauce Labs donated Appium as a project to the JS
Foundation, in order to cement for the world Sauce's
commitment that Appium remains open source. The JS Foundation is a non-profit
open source stewardship organization which takes responsibility for holding the
copyright for open source projects, as well as ensuring they have a long and
successful tenure in the community. As a result of our move to a non-profit
foundation, we hope that the door will open even more widely for new
contributors, either as individuals or representing one of the many companies
which now have an interest in seeing Appium move forward.
2016 年底,Sauce Labs 将 Appium 作为一个项目捐赠给 [JS 基金会](https://js.foundation),以便向世界证明 Sauce 承诺 Appium 保持开源。 JS 基金会是一个非营利性开源管理组织,负责持有开源项目的版权,并确保它们在社区中拥有长久和成功的任期。 由于我们转移到非营利基金会,我们希望新贡献者的大门会更加敞开,无论是作为个人还是代表现在对 Appium 前进有兴趣的众多公司之一。
Eventually, the JS Foundation merged into the [OpenJS Foundation](https://openjsf.org),
and Appium became an Impact Project in the foundation.
最终,JS 基金会并入了 [OpenJS 基金会](https://openjsf.org),Appium 成为该基金会的影响力项目。
## Appium 2.0
Appium 2 was released in 2023 and introduced an entirely revamped architecture, shifting focus to Appium
as an ecosystem rather than an all-in-one project. This unlocked the ability for anyone to develop
and share their own Appium extensions (drivers and plugins), opening up a world of possibilities
for automation-related development for platforms far beyond iOS and Android! As a result,
many third-party extensions were created, such as new drivers for Flutter and Windows, plugins for
mocking APIs and managing device farms, new Appium clients based on Rust and Swift, and much more.
Appium 2 于 2023 年发布,引入了一个全新的架构,将重点从一体化项目转移到作为生态系统的 Appium。 这为任何人开发和共享自己的 Appium 扩展(驱动程序和插件)开辟了可能性,为远超 iOS 和 Android 的平台的自动化相关开发打开了一个充满可能性的世界! 因此,创建了许多第三方扩展,例如用于 Flutter 和 Windows 的新驱动程序、用于模拟 API 和管理设备农场的插件、基于 Rust 和 Swift 的新 Appium 客户端等等。
Around this time was also when we started a sponsorship program for Appium, which attracted various
major and minor sponsors alike. This allowed us to give back to the Appium community, by compensating
contributors for their voluntary work on the project.
大约在这个时候,我们还启动了 Appium 的赞助计划,吸引了各种大小赞助商。 这使我们能够回馈 Appium 社区,为贡献者在项目上的志愿工作提供补偿。
## Appium 3.0
2025 saw the release of Appium 3. This update was a lot smaller than Appium 2 and included only a
few behavioral changes, instead focusing on removing deprecated code and updating compatibility for
more modern ecosystems. Still, this reduced scope was also to be expected: since Appium 2, the
main feature development efforts had shifted to individual drivers and plugins, many of which had
gone through multiple major updates during the Appium 2 era.
2025 年看到了 Appium 3 的发布。 这次更新比 Appium 2 小得多,只包括一些行为变化,而是专注于删除已弃用的代码并更新对更现代生态系统的兼容性。 尽管如此,这种缩小的范围也是意料之中的:自 Appium 2 以来,主要功能开发工作已转移到各个驱动程序和插件,其中许多在 Appium 2 时代经历了多次重大更新。
+18 -21
View File
@@ -2,38 +2,35 @@
hide:
- toc
title: Appium in a Nutshell
title: Appium 概览
---
As mentioned on the main page, Appium aims to support UI automation of many _different platforms_
(mobile, web, desktop, etc.). Not only that, but it also aims to support automation code written in
_different languages_ (JS, Java, Python, etc.). Combining all of this functionality in a single
program is a very daunting, if not impossible task!
如主页所述,Appium 旨在支持_多个不同平台_(移动端、Web、桌面等)的 UI 自动化。 不仅如此,它还旨在支持用_不同语言_(JS、Java、Python 等)编写的自动化代码。 将所有这些功能整合到一个程序中是一项非常艰巨的任务,甚至可以说是不可能完成的任务!
In order to achieve this, Appium is effectively split into four parts:
为了实现这一目标,Appium 实际上被分为四个部分:
<div class="grid cards" markdown>
- :material-image-filter-center-focus-strong: **Appium Core** - defines the core APIs
- :material-car: **Drivers** - implement connectivity to specific platforms
- :octicons-code-16: **Clients** - implement Appium's API in specific languages
- :fontawesome-solid-plug: **Plugins** - change or extend Appium's core functionality
- :material-image-filter-center-focus-strong: **Appium 核心** - 定义核心 API
- :material-car: **驱动程序** - 实现与特定平台的连接
- :octicons-code-16: **客户端库** - 用特定语言实现 Appium 的 API
- :fontawesome-solid-plug: **插件** - 改变或扩展 Appium 的核心功能
</div>
Therefore, in order to start automating something with Appium, you need to:
因此,要开始使用 Appium 进行自动化,你需要:
- Install Appium itself
- Install a driver for your target platform
- Install a client library for your target programming language
- (Optional) install one or more plugins
- 安装 Appium 本身
- 为你的目标平台安装驱动程序
- 为你的目标编程语言安装客户端库
- (可选)安装一个或多个插件
These are the basics! If you are ready to jump in, proceed with the [Quickstart](../quickstart/index.md)!
这些就是基础知识! 如果你已经准备好开始,请继续阅读[快速入门](../quickstart/index.md)!
If you wish to learn more details about how it all works, see these pages for background material:
如果你想了解更多关于其工作原理的详细信息,请参阅以下页面的背景材料:
- [Appium Core](./appium.md)
- [Appium Drivers](./drivers.md)
- [Appium Clients](./clients.md)
- [Appium 核心](./appium.md)
- [Appium 驱动程序](./drivers.md)
- [Appium 客户端](./clients.md)
Finally, to learn about the origins of Appium, check out the [Appium Project History](./history.md).
最后,要了解 Appium 的起源,请查看 [Appium 项目历史](./history.md)。
@@ -1,81 +1,64 @@
---
title: Install the UiAutomator2 Driver
title: 安装 UiAutomator2 驱动程序
---
You can't do much with Appium unless you have a [driver](../intro/drivers.md), which is an
interface that allows Appium to automate a particular platform.
除非您有[驱动程序](../intro/drivers.md),否则您无法使用 Appium 做太多事情,驱动程序是一个允许 Appium 自动化特定平台的接口。
!!! info
```
For this quickstart guide, we're going to be automating an app on the Android platform, because
the system requirements for Android automation via Appium are the same as for Appium itself
(whereas the iOS driver, for example, requires you to be using macOS).
对于这个快速入门指南,我们将在 Android 平台上自动化一个应用,因为通过 Appium 进行 Android 自动化的系统要求与 Appium 本身相同(而 iOS 驱动程序,则要求您使用 macOS)。
```
The driver we're going to use is called the UiAutomator2
Driver. It's worth visiting that driver's
documentation and bookmarking it, because it will be an invaluable reference down the line.
我们要使用的驱动程序称为 [UiAutomator2 驱动程序](https://github.com/appium/appium-uiautomator2-driver)。 请访问该驱动程序的文档并将其加入书签,因为它将成为未来宝贵的参考。
## Set up Android automation requirements
## 设置 Android 自动化要求
According to the driver, in addition to a working Appium server, we also need to set up the following:
根据驱动程序,除了工作 Appium 服务器,我们还需要设置以下内容:
### Android SDK
- The easiest way to set up the Android SDK requirements is by downloading [Android Studio](https://developer.android.com/studio).
We need to use its SDK manager (_Settings -> Languages & Frameworks -> Android SDK_)
to download the following items:
- Android SDK Platform (select whichever Android platform we want to automate, for example, API level 30)
- Android SDK Platform-Tools
- If you wish, you can also download these items without Android Studio:
- Android SDK Platform can be downloaded using `sdkmanager` included in [Android command-line tools](https://developer.android.com/studio#command-line-tools-only)
- [Android SDK Platform-Tools](https://developer.android.com/tools/releases/platform-tools)
- Set up the `ANDROID_HOME` environment variable to point to the directory where the Android SDK is
installed. You can usually find the path to this directory in the Android Studio SDK manager. It
will contain the `platform-tools` and other directories.
- 设置 Android SDK 的最简单方法是下载 [Android Studio](https://developer.android.com/studio)。
我们需要使用其 SDK 管理器(_设置 -> 语言和框架 -> Android SDK_)下载以下项目:
- Android SDK 平台(选择我们想要自动化的任何 Android 平台,例如 API 级别 30)
- Android SDK 平台工具
- 如果您愿意,您也可以在没有 Android Studio 的情况下下载这些项目:
- Android SDK 平台可以使用包含在 [Android 命令行工具](https://developer.android.com/studio#command-line-tools-only) 中的 `sdkmanager` 下载
- [Android SDK 平台工具](https://developer.android.com/tools/releases/platform-tools)
- 设置 `ANDROID_HOME` 环境变量指向安装 Android SDK 的目录。 您通常可以在 Android Studio SDK 管理器中找到此目录的路径。 它将包含 `platform-tools` 和其他目录。
### Java JDK
- Install the Java JDK (for the most recent Android API levels, JDK 9 is required, otherwise JDK
8 is required). You can download this from [Oracle](https://jdk.java.net/) or [Adoptium](https://adoptium.net/en-GB/temurin/releases/).
Make sure you get the JDK and not the JRE.
- Set up the `JAVA_HOME` environment variable to point to the JDK home directory. It will contain
the `bin`, `include`, and other directories.
- 安装 Java JDK(对于最新的 Android API 级别,需要 JDK 9,否则请用 JDK 8)。 您可以从 [Oracle](https://jdk.java.net/) 或 [Adoptium](https://adoptium.net/en-GB/temurin/releases/) 下载此软件。
确保您获得 JDK 而不是 JRE。
- 设置 `JAVA_HOME` 环境变量指向 JDK 主目录。 它将包含 `bin`、`include` 和其他目录。
### Prepare the Device
### 准备设备
- If using an emulator, use Android Studio to create and launch an Android Virtual Device (AVD).
You may need to download the system images for the API level of the emulator you want to
create. Using the AVD creation wizard in Android Studio is generally the easiest way to do all of
this.
- If using a real device, you should [set it up for development and enable USB Debugging](https://developer.android.com/studio/debug/dev-options).
- With the emulator or device connected, you can run `adb devices` (via the binary located at
`$ANDROID_HOME/platform-tools/adb`) to verify that your device shows up as connected.
- 如果使用模拟器,使用 Android Studio 创建和启动 Android 虚拟设备 (AVD)。
您可能需要下载要创建的模拟器的 API 级别的系统映像。 使用 Android Studio 中的 AVD 创建向导通常是完成所有这些的最简单方法。
- 如果使用真实设备,您应该为其设置[开发者模式并启用 USB 调试](https://developer.android.com/studio/debug/dev-options)。
- 连接模拟器或设备后,您可以运行 `adb devices`(adb位于 `$ANDROID_HOME/platform-tools/adb`)来验证您的设备是否显示为已连接。
Once your device shows up as connected in `adb`, and you've verified that the environment variables
are set up correctly, you should be good to go! If you ran into problems with any of these steps,
refer to the driver documentation, or the various Android or Java documentation sites as necessary.
一旦您的设备在 `adb` 中显示为已连接,并且您验证了环境变量设置正确,您应该准备好了! 如果您在这些步骤中的任何一个遇到问题,请参考驱动程序文档,或根据需要参考各种 Android 或 Java 文档站点。
Also, congratulations: whether or not you intended to, you now have the Android developer toolchain
set up on your system, so you can get busy making Android apps if you want!
恭喜:无论您是否打算这样做,您现在已经在系统上设置了 Android 开发者工具链,所以如果您愿意,可以开始制作 Android 应用!
## Install the driver itself
## 安装驱动程序本身
### Standard Install
### 标准安装
Like all Appium drivers, the UiAutomator2 driver is installed via the [Appium Extension CLI](../reference/cli/extensions.md).
Since UiAutomator2 is maintained by the core Appium team, it has an 'official' driver name
(`uiautomator2`), which makes the installation simpler.
像所有 Appium 驱动程序一样,UiAutomator 2 驱动程序通过 [Appium 扩展 CLI](../reference/cli/extensions.md) 安装。
由于 UiAutomator 2 由核心 Appium 团队维护,它有一个“官方”驱动程序名称(`uiautomator2`),这使得安装更简单。
Before installing, make sure your Appium server is _not_ running (if it is, quit it with _Ctrl-C_).
Then run the following command:
在安装之前,确保您的 Appium 服务器_未_运行(如果正在运行,请用 _Ctrl-C_ 退出)。
然后运行以下命令:
```bash
appium driver install uiautomator2
```
It should produce output that looks something like:
它应该产生看起来像这样的输出:
```
Attempting to find and install driver 'uiautomator2'
@@ -85,57 +68,45 @@ Driver uiautomator2@2.0.5 successfully installed
- platformNames: ["Android"]
```
Note how the installation process specifies what platforms is the driver valid for (in this case,
`Android`), and what automation name (the `appium:automationName` [capability](../guides/caps.md))
must be used to select this driver for use during an Appium session (in this case, `UiAutomator2`).
注意安装过程如何指定驱动程序的适用平台(在这里选 `Android`),以及必须用于在 Appium 会话期间选择此驱动程序的自动化名称(`appium:automationName` [能力](../guides/caps.md))(在这里选 `UiAutomator2`)。
!!! note
```
In this quickstart we have used the [Extension CLI](../reference/cli/extensions.md) to install the
UiAutomator2 driver, but if you are incorporating Appium into a Node.js project, you might
prefer to use `npm` to manage Appium and its connected drivers. To learn more about this
technique, visit the guide on [managing Appium extensions](../guides/managing-exts.md).
在这个快速入门中,我们使用了 [CLI扩展](../reference/cli/extensions.md) 来安装 UiAutomator 2 驱动程序,但如果您将 Appium 纳入 Node.js 项目,您可能更喜欢使用 `npm` 来管理 Appium 及其连接的驱动程序。要了解更多关于此技术的信息,请访问关于[管理 Appium 扩展](../guides/managing-exts.md)的指南。
```
### Batch Install
### 批量安装
You may want to use Appium with more than one driver. One way to accomplish this is to run
`appium driver install <driver-name>` for each individual driver, but you can also install multiple
drivers in one go:
您可能希望将 Appium 与多个驱动程序一起使用。 一种方法是为每个单独的驱动程序运行 `appium driver install <driver-name>`,但您也可以一次性安装多个驱动程序:
```
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).
运行此命令将安装 Appium 的移动端特定驱动程序:UiAutomator2、[XCUITest](https://appium.github.io/appium-xcuitest-driver/)(仅在运行 macOS 时),以及 [Espresso](https://github.com/appium/appium-espresso-driver)。
You can also use this command to batch install drivers for desktop applications or desktop browsers.
For more details on this, refer to the [Setup command documentation](../reference/cli/setup.md).
您也可以使用此命令批量安装桌面应用程序或桌面浏览器的驱动程序。
有关更多详细信息,请参考[设置命令文档](../reference/cli/setup.md)。
### Validating the Install
### 验证安装
The UiAutomator2 driver, like all official Appium drivers, comes with the Appium Doctor tool, which
allows validating whether all prerequisites have been set up correctly:
UiAutomator2 驱动程序,像所有官方 Appium 驱动程序一样,带有 Appium Doctor 工具,它允许验证是否所有先决条件都已正确设置:
```
appium driver doctor uiautomator2
```
This guide has focused on essential requirements, so Appium Doctor may suggest one or more optional
fixes. But if you see `0 required fixes needed`, that means everything is set up!
本指南专注于基本要求,因此 Appium Doctor 可能建议一个或多个可选修复。 但如果您看到 `0 required fixes needed`,那意味着一切都设置好了!
Now, start the Appium server again (run `appium`), and you should see that the newly-installed
driver is listed as available:
现在,再次启动 Appium 服务器(运行 `appium`),您应该看到新安装的驱动程序列为可用:
```
[Appium] Available drivers:
[Appium] - uiautomator2@2.0.5 (automationName 'UiAutomator2')
```
With the Android setup complete and the UiAutomator2 driver installed, you're ready to write your
first test! Now select your preferred language and give it a shot:
Android 设置完成并安装了 UiAutomator2 驱动程序,准备编写第一个测试吧! 现在选择您喜欢的语言并试试:
<div class="grid cards" markdown>
@@ -397,6 +397,45 @@ Deletes the virtual sensor with the type identified by `:sensorType`.
`null`
## Global Privacy Control Protocol
The [Global Privacy Control protocol](https://www.w3.org/TR/gpc) (GPC) is an extension of the W3C
WebDriver protocol.
### setGlobalPrivacyControl
```
POST /session/:sessionId/privacy
```
> GPC documentation: [Set Global Privacy Control](https://www.w3.org/TR/gpc/#set-global-privacy-control)
Sets the value of the do-not-sell-or-share preference for the current session.
#### Parameters
| Name | Description | Type |
| ----- | -------------------------------------------------------------------- | ------- |
| `gpc` | Whether the browser should perform do-not-sell-or-share interactions | boolean |
#### Response
`null`
### getGlobalPrivacyControl
```
GET /session/:sessionId/privacy
```
> GPC documentation: [Get Global Privacy Control](https://www.w3.org/TR/gpc/#get-global-privacy-control)
Retrieves the value of the do-not-sell-or-share preference for the current session.
#### Response
`boolean` - the preference value
## Permissions Protocol
The [Permissions protocol](https://www.w3.org/TR/permissions/) is an extension of the W3C WebDriver
@@ -524,6 +563,32 @@ Retrieves the available log types that can be used to call the [`getLog`](#getlo
`string[]` - an array of log types
## Storage Access Protocol
The [Storage Access protocol](https://privacycg.github.io/storage-access/) is an extension of the
W3C WebDriver protocol.
### setStorageAccess
```
POST /session/:sessionId/storageaccess
```
> Storage Access documentation: [Set Storage Access](https://privacycg.github.io/storage-access/#set-storage-access-command)
Sets the storage access policy of the current browsing context.
#### Parameters
| Name | Description | Type |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------- |
| `blocked` | Whether storage access should be blocked (`true`) or allowed (`false`) | boolean |
| `origin` | The origin to which the policy should be applied. Must be either a valid URL, or an asterisk (`*`) if the policy should apply to all origins. | string |
#### Response
`null`
## Web Authentication Protocol
The [Web Authentication protocol](https://w3c.github.io/webauthn/) (WebAuthn) is an extension of
@@ -118,6 +118,12 @@ appium {driver|plugin} install <install-spec>
appium driver install git://github.com/appium/appium-xcuitest-driver.git --source=git --package=appium-xcuitest-driver
```
- Install a branch of XCUITest driver repository using a Git URL:
```
appium driver install git://github.com/appium/appium-xcuitest-driver.git#specific-branch --source=git --package=appium-xcuitest-driver
```
## `list`
Lists all installed extensions, plus all official extensions that are not installed.
@@ -135,6 +141,7 @@ appium {driver|plugin} list
| `--installed` | Only list all installed extensions | boolean |
| `--json` | Return the result in JSON format | boolean |
| `--updates` | List all extensions along with information on whether newer versions are available. Only supported for extensions installed via `npm`. | boolean |
| `--verbose` | Show additional details for each extension | boolean |
#### Example
@@ -31,5 +31,6 @@ The executable has four main subcommands: `server`, `driver`, `plugin`, and `set
</div>
Appium also recognizes several [environment variables](./env-vars.md), which may be used for
advanced configuration.
The Appium server also recognizes several [environment variables](./env-vars.md) and
[insecure feature names](./insecure-features.md), though drivers and plugins can also define
variables and features of their own.
@@ -0,0 +1,23 @@
---
hide:
- toc
title: Insecure Features
---
The Appium server implements [a security protection mechanism](../../guides/security.md) that
allows the management of various insecure features.
The following features are defined on the server level and can be used even without drivers, but
they can only be enabled using the wildcard (`*`) prefix:
| Feature Name | Description |
| ------------------- | ------------------------------------------------------------------------------- |
| `session_discovery` | Allows retrieving the list of active server sessions via `GET /appium/sessions` |
Of course, Appium drivers and plugins are free to define additional insecure features of their own.
The following features are defined by official plugins:
| Feature Name | Plugin | Description |
| ----------------------- | ---------------- | ---------------------------------------------------------- |
| `execute_driver_script` | `execute_driver` | Allows sending a request that has multiple Appium commands |
@@ -48,6 +48,8 @@ appium
| `--log-no-colors` | Disable colors in the server log | boolean | `false` |
| `--log-timestamp` | Show timestamps in the server log | boolean | `false` |
| `--long-stacktrace` | Add long stack traces to log entries. Recommended for debugging only. | boolean | `false` |
| `--max-ipc-data-size` | Maximum byte size of IPC message objects. | integer | `1048576` (1MB) |
| `--max-ipc-topics` | Maximum number of IPC topics per session. | integer | `1000` |
| `--no-perms-check` | Skip various permission checks on the server startup | boolean | `false` |
| `--nodeconfig` | JSON configuration for registering Appium as a node with Selenium Grid 3 | object | |
| `--plugin` | Plugin-specific configuration. Keys should correspond to plugin package names | object | |
+9 -3
View File
@@ -5,8 +5,8 @@ hide:
title: Reference
---
This section of the Appium documentation provides a reference to the two main interfaces within the
Appium server: the command-line executable, and the supported API endpoints.
This section of the Appium documentation provides a reference to the core interfaces supported within the
Appium server:
<div class="grid cards" markdown>
@@ -16,10 +16,16 @@ Appium server: the command-line executable, and the supported API endpoints.
Learn how to use the Appium command-line executable
- :material-lan-connect: [**Session Properties**](./session/index.md)
---
See the values of global Appium session properties
- :material-cloud-braces: [**API Endpoints**](./api/index.md)
---
View endpoints supported by the Appium server
View endpoints supported by the core Appium server
</div>
@@ -0,0 +1,56 @@
---
hide:
- toc
title: Capabilities
---
The following [capabilities](../../guides/caps.md) are recognized by the Appium server/base driver,
and are therefore supported by all drivers as well. Some capabilities are directly handled by the
server/base driver, while others are only validated before being passed to the actual driver.
!!! note
Capabilities not listed here will _not_ be rejected by Appium: they will simply be forwarded
directly to the active driver/plugin.
### Required Capabilities
These capabilities are used in the Appium server/base driver, and are explicitly required in all
Appium sessions.
| Capability | Description | Type |
| ----------------------- | ------------------------------------------- | -------- |
| `platformName` | Type of platform hosting the app or browser | `string` |
| `appium:automationName` | Name of the Appium driver to use | `string` |
### Optional Capabilities
These capabilities are used in the Appium server/base driver, but are optional, and may have a
default value.
| <div style="width:19em">Capability</div> | Description | Type | Default |
| ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- | ------- |
| `webSocketUrl` | Toggle support of the WebDriver BiDi protocol | `boolean` | |
| `appium:eventTimings` (deprecated) | Toggle collection of [Event Timings](../../guides/event-timing.md). This capability is deprecated - please use the [`getLogEvents`](../api/appium.md#getlogevents) endpoint instead. | `boolean` | |
| `appium:newCommandTimeout` | Number of seconds the Appium server should wait for clients to send commands before stopping the session. A value of `0` disables the timeout. | `number` | `60` |
| `appium:printPageSourceOnFindFailure` | Toggle retrieval of the the page source and its printing to the Appium log, whenever a request to find an element fails | `boolean` | |
### Validated Capabilities
These capabilities are not directly used in the Appium server/base driver, but are still subject to
validation checks due to their relevance in other drivers. The actual handling of these
capabilities is optional and entirely driver-dependent.
| Capability | Validation |
| --------------------------------------------------- | ------------------------------------------------------------- |
| `platformVersion` | Must be `string` |
| `appium:app` | Must be `string`; empty values are ignored |
| `appium:autoLaunch` (deprecated) | Must be `boolean` |
| `appium:autoWebview` | Must be `boolean` |
| `appium:fullReset` | Must be `boolean`; mutually exclusive with `appium:noReset` |
| `appium:language` | Must be `string` |
| `appium:locale` | Must be `string` |
| `appium:orientation` | Must be either `LANDSCAPE` or `PORTRAIT` |
| `appium:noReset` | Must be `boolean`; mutually exclusive with `appium:fullReset` |
| `appium:udid` | Must be `string` |
@@ -0,0 +1,23 @@
---
hide:
- toc
title: Session Properties
---
An Appium session has several key properties, each with its own set of supported values:
capabilities, execute methods, settings, locator strategies, and others. The supported values for
each property are primarily defined by the active driver and plugins, but some properties also have
common values provided by the Appium server and its base driver:
<div class="grid cards" markdown>
- [**Capabilities**](./caps.md)
A small set of basic capabilities
- [**Command Endpoints**](../api/index.md)
The core set of API endpoints
</div>
+8 -3
View File
@@ -22,6 +22,11 @@ Hub.
We are very grateful for the support of our Development Partners, who donate Appium development and
maintenance as part of their employees' core job duties!
<a href="https://www.testmuai.com">
<img src="/docs/en/latest/assets/images/sponsor-logo-testmuai-dark.png#only-dark" width="250" alt="TestMu AI (formerly LambdaTest)" />
<img src="/docs/en/latest/assets/images/sponsor-logo-testmuai-light.png#only-light" width="250" alt="TestMu AI (formerly LambdaTest)" />
</a>
## Strategic Partners
We are very grateful for the financial and marketing support of our exclusive Strategic Partners,
@@ -33,9 +38,9 @@ contributors!
<img src="/docs/en/latest/assets/images/sponsor-logo-browserstack-light.png#only-light" width="250" alt="BrowserStack" />
</a>
<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="250" alt="LambdaTest" />
<img src="/docs/en/latest/assets/images/sponsor-logo-lambdatest-light.png#only-light" width="250" alt="LambdaTest" />
<a href="https://www.testmuai.com">
<img src="/docs/en/latest/assets/images/sponsor-logo-testmuai-dark.png#only-dark" width="250" alt="TestMu AI (formerly LambdaTest)" />
<img src="/docs/en/latest/assets/images/sponsor-logo-testmuai-light.png#only-light" width="250" alt="TestMu AI (formerly LambdaTest)" />
</a>
## Gold Sponsors
+1 -3
View File
@@ -1,11 +1,9 @@
#!/usr/bin/env node
const {asyncify} = require('asyncbox');
const appium = require('./build/lib/main.js');
if (require.main === module) {
asyncify(appium.main);
appium.main();
}
module.exports = appium;
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More