chore: add latest changes from master (#21227)

* chore(tsconfig): update dependency @tsconfig/node14 to v14.1.3 (#21065)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(workflows): update peter-evans/create-pull-request action to v7.0.8 (#21066)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency typescript-eslint to v8.26.0 (#21068)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update definitelytyped (#21067)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(docutils): update dependency typescript to v5.8.2 (#21057)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(docutils): update dependency mkdocs-git-revision-date-localized-plugin to v1.4.1 (#21071)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* feat(images-plugin): supports image elements included in actions. (#21055)

* chore(types): update dependency type-fest to v4.37.0 (#21073)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency finalhandler to v2 (#21074)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* test: Update tests of images plugin (#21078)

* test(images-plugin): Fix test host (#21079)

* chore(support): update dependency axios to v1.8.2 (#21080)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency eslint-config-prettier to v10.1.1 (#21081)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(fake-driver): accept 3.0.0-beta.0 as well (#21076)

* feat: Add storage plugin (#21075)

* chore(deps): update dependency @types/node to v22.13.10 (#21084)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* docs(base-driver): remove outdated READMEs (#21083)

* chore(deps): update eslint-related packages to v9.22.0 (#21085)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* feat(storage-plugin): Tune the files keeping behaviour (#21086)

* docs(appium): fix a broken character that caused incorrect rendering of mkdocs (#21090) (#21091)

* chore(storage-plugin): Simplify add to storage logic (#21092)

* chore(docutils): update dependency mkdocs-git-revision-date-localized-plugin to v1.4.4 (#21093)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* docs: add storage-plugin documentation (#21096)

* chore: fix typo

* chore: list storage-plugin as a known plugin

* docs: align storage-plugin docs with other plugins

* chore: address comments

* chore(deps): update eslint-related packages (#21097)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(base-driver): Fix proxy url generation (#21099)

* chore: publish

 - appium@2.17.0
 - @appium/base-driver@9.16.3
 - @appium/base-plugin@2.3.4
 - @appium/docutils@1.0.33
 - @appium/driver-test-support@0.7.7
 - @appium/execute-driver-plugin@4.0.3
 - @appium/fake-driver@5.7.2
 - @appium/fake-plugin@3.2.4
 - @appium/images-plugin@3.1.0
 - @appium/plugin-test-support@0.3.52
 - @appium/storage-plugin@0.1.0
 - @appium/support@6.0.7
 - @appium/test-support@3.1.7
 - @appium/tsconfig@0.3.5
 - @appium/types@0.25.2
 - @appium/universal-xml-plugin@1.0.31

* chore(deps): update dependency eslint-import-resolver-typescript to v3.8.5 (#21101)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(support): update dependency axios to v1.8.3 (#21102)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(execute-driver-plugin): update dependency webdriverio to v9.12.0 (#21072)

* chore(deps): update dependency eslint-import-resolver-typescript to v3.8.6 (#21103)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency eslint-import-resolver-typescript to v3.8.7 (#21107)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(docutils): update dependency mkdocs-material to v9.6.8 (#21108)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(universal-xml-plugin): update dependency fast-xml-parser to v5 (#21109)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency eslint-import-resolver-typescript to v3.9.0 (#21113)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(docutils): update dependency mkdocs-git-revision-date-localized-plugin to v1.4.5 (#21112)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency eslint-import-resolver-typescript to v3.9.1 (#21115)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(docutils): update dependency mkdocs-material to v9.6.9 (#21121)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(base-driver): Exclude proxied headers from the server response (#21120)

* chore: publish

 - appium@2.17.1
 - @appium/base-driver@9.16.4
 - @appium/base-plugin@2.3.5
 - @appium/docutils@1.0.34
 - @appium/driver-test-support@0.7.8
 - @appium/execute-driver-plugin@4.0.4
 - @appium/fake-plugin@3.2.5
 - @appium/images-plugin@3.1.1
 - @appium/storage-plugin@0.1.1
 - @appium/support@6.0.8
 - @appium/test-support@3.1.8
 - @appium/universal-xml-plugin@1.0.32

* docs: update zh contributing documentation (#21117)

* Translate Validation of Individual Arguments via AJV section

* Complete the translation of the config system file

* chore(docutils): update dependency consola to v3.4.2 (#21124)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency @types/express to v5.0.1 (#21126)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(support): update dependency axios to v1.8.4 (#21127)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(execute-driver-plugin): update dependency webdriverio to v9.12.1 (#21129)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency typescript-eslint to v8.27.0 (#21131)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(eslint-config-appium-ts): update dependency eslint-import-resolver-typescript to v4 (#21119)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(test-support): update dependency sinon to v19.0.4 (#21130)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency @types/node to v22.13.11 (#21135)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* feat: Add a possibility to mask sensitive log values depending on request headers (#21123)

* chore(deps): update eslint-related packages to v9.23.0 (#21138)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(types): update dependency type-fest to v4.38.0 (#21140)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update definitelytyped (#21139)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(test-support): update dependency sinon to v19.0.5 (#21141)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update eslint-related packages (#21142)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(test-support): update dependency sinon to v20 (#21143)

* chore(test-support): update dependency sinon to v20

* remove usingPromise

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Mykola Mokhnach <mokhnach@gmail.com>

* chore(deps): update dependency eslint-import-resolver-typescript to v4.2.5 (#21146)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update definitelytyped (#21147)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(storage-plugin): Use base driver import for W3C error response creation (#21153)

* chore(deps): update dependency eslint-import-resolver-typescript to v4.2.7 (#21155)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(execute-driver-plugin): update dependency webdriverio to v9.12.2 (#21151)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(docutils): update dependency yaml to v2.7.1 (#21158)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency eslint-import-resolver-typescript to v4.3.1 (#21159)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* feat(base-driver): Accept `x-request-id` as override to generated requestId in `handleLogContext` (#21154)

* chore(docutils): update dependency mkdocs-material to v9.6.10 (#21161)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency typescript-eslint to v8.29.0 (#21165)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update definitelytyped (#21164)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(docutils): update dependency mkdocs-material to v9.6.11 (#21167)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(types): update dependency type-fest to v4.39.0 (#21168)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(docutils): add & adjust various log messages (#21160)

* fix(docutils): add & adjust various log messages

* fix: use npm from support package for npm calls

* chore(deps): update dependency @types/node to v22.14.0 (#21172)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(types): update dependency type-fest to v4.39.1 (#21173)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* fix(logger): Error stack logging (#21176)

* chore(execute-driver-plugin): update dependency webdriverio to v9.12.3 (#21177)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(universal-xml-plugin): update dependency fast-xml-parser to v5.2.0 (#21178)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(docutils): update dependency typescript to v5.8.3 (#21179)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(execute-driver-plugin): update dependency webdriverio to v9.12.4 (#21180)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update eslint-related packages to v9.24.0 (#21182)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(support): update dependency sharp to v0.34.0 (#21183)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* feat(docutils): add MkDocs Material codeblock & text format features (#21184)

* chore(docutils): reorder Markdown extensions alphabetically

* feat(docutils): add MkDocs Material codeblock features

* chore(docutils): explicitly add Markdown tables support

* feat(docutils): add MkDocs Material linked tabs

* feat(docutils): add MkDocs Material text format features

* feat(docutils): add MkDocs Material task list

* fix(ci): run on all Node LTS versions instead of only active (#21185)

* fix(ci): run on LTS versions instead of only active

* chore: address comments

* chore(deps): update dependency eslint-import-resolver-typescript to v4.3.2 (#21186)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency typescript-eslint to v8.29.1 (#21189)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(support): update dependency sharp to v0.34.1 (#21191)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency tsd to v0.32.0 (#21194)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency eslint-config-prettier to v10.1.2 (#21195)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency lerna to v8.2.2 (#21197)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update dependency @types/node to v22.14.1 (#21199)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(execute-driver-plugin): update dependency webdriverio to v9.12.5 (#21200)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(base-driver): Mark IME commands and receive_async_response as deprecated (#21201)

* docs(appium): add NovaWindows driver to Appium other drivers list (#21202)

* chore(deps): update dependency typescript-eslint to v8.30.1 (#21206)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(types): update dependency type-fest to v4.40.0 (#21208)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(base-driver): Mark /session/:sessionId/network_connection deprecated (#21209)

* chore(execute-driver-plugin): update dependency webdriverio to v9.12.6 (#21210)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(docutils): update dependency mkdocs-material to v9.6.12 (#21211)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update eslint-related packages (#21214)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(deps): update eslint-related packages (#21216)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(execute-driver-plugin): update dependency webdriverio to v9.12.7 (#21218)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* docs: update Appium 2 migration guide (#21215)

* docs: rewrite Appium 2 migration guide

* docs: reorder breaking changes

* docs: identify changed endpoints

* docs: improve code example

* docs: address comments

* chore(universal-xml-plugin): update dependency fast-xml-parser to v5.2.1 (#21220)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* docs: remove SeleniumConf banner (#21221)

* docs(appium): address default timeout in newCommandTimeout (#21222)

* chore: publish

 - appium@2.18.0
 - @appium/base-driver@9.17.0
 - @appium/base-plugin@2.3.6
 - @appium/docutils@1.1.0
 - @appium/driver-test-support@0.7.9
 - @appium/eslint-config-appium-ts@1.0.4
 - @appium/execute-driver-plugin@4.0.5
 - @appium/fake-plugin@3.2.6
 - @appium/images-plugin@3.1.2
 - @appium/logger@1.7.0
 - @appium/opencv@3.0.9
 - @appium/plugin-test-support@0.3.53
 - @appium/storage-plugin@0.1.2
 - @appium/support@6.1.0
 - @appium/test-support@3.1.9
 - @appium/types@0.25.3
 - @appium/universal-xml-plugin@1.0.33

* chore(deps): update dependency @types/node to v22.15.2 (#21223)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

* chore(support): update dependency axios to v1.9.0 (#21225)

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: kkb912002 <57607392+kkb912002@users.noreply.github.com>
Co-authored-by: Mykola Mokhnach <mokhnach@gmail.com>
Co-authored-by: Kazuaki Matsuo <fly.49.89.over@gmail.com>
Co-authored-by: Sakura Nene <blade1565@outlook.com>
Co-authored-by: Jonathan Lipps <jonathan.lipps@sony.com>
Co-authored-by: zhangxh075 <zhangxh075@163.com>
Co-authored-by: Regan Karlewicz <regan@karlewr.net>
Co-authored-by: Teodor Nikolov <teo8447@gmail.com>
This commit is contained in:
Edgars Eglītis
2025-04-27 01:20:13 +03:00
committed by GitHub
parent 9a823cea0c
commit b7b8840afe
59 changed files with 2866 additions and 2118 deletions
+2 -2
View File
@@ -58,9 +58,9 @@ jobs:
prepare_matrix:
runs-on: ubuntu-latest
outputs:
versions: ${{ steps.generate-matrix.outputs.active }}
versions: ${{ steps.generate-matrix.outputs.lts }}
steps:
- name: Select all active LTS versions of Node.js
- name: Select all current LTS versions of Node.js
id: generate-matrix
uses: msimerson/node-lts-versions@v1
+2 -2
View File
@@ -12,9 +12,9 @@ jobs:
prepare_matrix:
runs-on: ubuntu-latest
outputs:
versions: ${{ steps.generate-matrix.outputs.active }}
versions: ${{ steps.generate-matrix.outputs.lts }}
steps:
- name: Select all active LTS versions of Node.js
- name: Select all current LTS versions of Node.js
id: generate-matrix
uses: msimerson/node-lts-versions@v1
+2067 -1630
View File
File diff suppressed because it is too large Load Diff
+11 -11
View File
@@ -85,7 +85,7 @@
},
"devDependencies": {
"@colors/colors": "1.6.0",
"@eslint/js": "9.23.0",
"@eslint/js": "9.25.1",
"@tsconfig/node14": "14.1.3",
"@types/argparse": "2.0.17",
"@types/archiver": "6.0.3",
@@ -105,7 +105,7 @@
"@types/mocha": "10.0.10",
"@types/mv": "2.1.4",
"@types/ncp": "2.0.8",
"@types/node": "22.13.14",
"@types/node": "22.15.2",
"@types/pluralize": "0.0.33",
"@types/semver": "7.7.0",
"@types/serve-favicon": "2.5.7",
@@ -118,7 +118,7 @@
"@types/uuid": "10.0.0",
"@types/which": "3.0.4",
"@types/wrap-ansi": "3.0.0",
"@types/ws": "8.18.0",
"@types/ws": "8.18.1",
"@types/xmldom": "0.1.34",
"@types/yargs": "17.0.33",
"asyncbox": "3.0.0",
@@ -127,16 +127,16 @@
"conventional-changelog-conventionalcommits": "7.0.2",
"cpy-cli": "5.0.0",
"cross-env": "7.0.3",
"eslint": "9.23.0",
"eslint-config-prettier": "10.1.1",
"eslint-import-resolver-typescript": "4.2.7",
"eslint": "9.25.1",
"eslint-config-prettier": "10.1.2",
"eslint-import-resolver-typescript": "4.3.4",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-mocha": "10.5.0",
"eslint-plugin-promise": "7.2.1",
"finalhandler": "2.1.0",
"get-port": "5.1.1",
"json-schema-to-typescript": "15.0.4",
"lerna": "8.2.1",
"lerna": "8.2.2",
"log-symbols": "4.1.0",
"midnight-smoker": "8.0.0",
"mjpeg-consumer": "2.0.0",
@@ -150,11 +150,11 @@
"sinon": "20.0.0",
"sync-monorepo-packages": "1.0.2",
"ts-node": "10.9.2",
"tsd": "0.31.2",
"typescript": "5.8.2",
"typescript-eslint": "8.28.0",
"tsd": "0.32.0",
"typescript": "5.8.3",
"typescript-eslint": "8.31.0",
"validate.js": "0.13.1",
"webdriverio": "9.12.2",
"webdriverio": "9.12.7",
"ws": "8.18.1",
"yaml-js": "0.3.1"
},
+11
View File
@@ -3,12 +3,23 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.18.0](https://github.com/appium/appium/compare/appium@2.17.1...appium@2.18.0) (2025-04-25)
### Features
* **base-driver:** Accept `x-request-id` as override to generated requestId in `handleLogContext` ([#21154](https://github.com/appium/appium/issues/21154)) ([a82476f](https://github.com/appium/appium/commit/a82476f2fcb4aa3a3c4660d96fdd261a98afa4af))
## [2.17.1](https://github.com/appium/appium/compare/appium@2.17.0...appium@2.17.1) (2025-03-17)
**Note:** Version bump only for package appium
## [2.17.0](https://github.com/appium/appium/compare/appium@2.16.2...appium@2.17.0) (2025-03-11)
@@ -44,6 +44,7 @@ These drivers are not maintained by the Appium team and can be used to target ad
|[Tizen](https://github.com/Samsung/appium-tizen-driver)|`--source=npm appium-tizen-driver`|Android|Native|Community / Samsung|
|[TizenTV](https://github.com/headspinio/appium-tizen-tv-driver)|`--source=npm appium-tizen-tv-driver`|Samsung TV|Web|HeadSpin|
|[Youi](https://github.com/YOU-i-Labs/appium-youiengine-driver)|`--source=npm appium-youiengine-driver`|iOS, Android, macOS, Linux, tvOS|Native|Community / You.i|
|[NovaWindows](https://github.com/AutomateThePlanet/appium-novawindows-driver)|`--source=npm appium-novawindows-driver`|Windows|Native|Community / Automate The Planet|
!!! note
+1 -1
View File
@@ -42,7 +42,7 @@ Here is a list of all the globally-recognized Appium capabilities:
| `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 |
| `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`) |
+17
View File
@@ -0,0 +1,17 @@
---
title: Header Handling
---
# Header Handling
## Request ID Tracking
Appium supports setting the request ID for each request through the `x-request-id` header. This is useful for tracing requests through your system, especially in environments where multiple services are involved or when debugging across different requests.
### Using `x-request-id`
When making requests to Appium, you can include an `x-request-id` header with a unique identifier. This ID will be:
- Used to track the request through Appium's logging system
- Preserved across the entire request lifecycle
- Generated automatically (as a UUID) if not provided
+275 -271
View File
@@ -6,141 +6,74 @@ This document is a guide for those who are using Appium 1 and wish to migrate to
contains a list of breaking changes and how to migrate your environments or test suites to ensure
compatibility with Appium 2.
!!! note
Appium 2 is the biggest Appium release in over 5 years. It is _not_ focused on changing the
automation behavior for any particular platform, but instead re-envisions Appium into an
_ecosystem_ of automation tools:
Latest Appium drivers/plugins would have update since we created this documentation
because we keep developing the ecosystem.
## Overview of Appium 2
Appium 2 is the most major new release of Appium in over 5 years. The changes in Appium 2 are _not_
primarily related to changes in automation behaviors for specific platforms. Instead, Appium 2
reenvisions Appium as a _platform_ where "drivers" (code projects that introduce support for
automation of a given platform) and "plugins" (code projects that allow for overriding, altering,
extending, or adding behaviors to Appium) can be easily created and shared.
* The core Appium module retains only platform-agnostic functionality
* Functionality for automating specific platforms is moved to separate _driver_ modules
* Functionality for altering/extending Appium is moved to separate _plugin_ modules
At the same time, the Appium project is taking the opportunity to remove many old and deprecated
bits of functionality.
Together these do introduce a few breaking changes to how Appium is installed, how drivers and
various features are managed, and protocol support. These are detailed below.
Since Appium 2 is a major architectural change, ^^we do not recommend directly updating your
Appium 1 installations to Appium 2^^. Instead, please uninstall Appium 1 first, and only install
Appium 2 afterwards.
## Breaking Changes
### :bangbang: Default server base path
### Drivers Installed Separately
With Appium 1, the server would accept commands by default on `http://localhost:4723/wd/hub`. The
`/wd/hub` base path was a legacy convention from the days of migrating from Selenium 1 to Selenium
2, and is no longer relevant. As such the default base path for the server is now `/`. If you want
to retain the old behaviour, you can set the base path via a command line argument as follows:
When installing Appium 1, all available drivers would be installed alongside the main Appium
server. In Appium 2, due to its modular structure, this is no longer the case - by default,
installing it only installs the core Appium server, without any drivers.
```
appium --base-path=/wd/hub
```
You can also set server arguments as [Config file](./config.md) properties.
### :bangbang: Installing drivers during setup
When you installed Appium 1, all available drivers would be installed at the same time as the main
Appium server. This is no longer the case. Simply installing Appium 2 (e.g., by `npm i -g appium`),
will install the Appium server only, but no drivers. To install drivers, you must instead use the
new [Appium extension CLI](../cli/extensions.md). For example, to install the latest versions of the
XCUITest and UiAutomator2 drivers, after installing Appium you would run the following commands:
```bash
appium driver install uiautomator2 # installs the latest driver version
appium driver install xcuitest@4.12.2 # installs a specific driver version
```
At this point, your drivers are installed and ready. There's a lot more you can do with the Appium 2
command line, so be sure to check out [its documentation](../cli/index.md). If you're running in a CI
environment or want to install Appium along with some drivers all in one step, you can do so using
some special flags during install, for example:
When it comes to installing Appium 2 drivers, there are several approaches you can take:
* Add the `--drivers` flag when installing Appium, for example:
```bash
npm i -g appium --drivers=xcuitest,uiautomator2
```
* Use the [Appium Extension CLI](../cli/extensions.md), for example:
```bash
appium driver install uiautomator2
```
* Use the [Appium Setup CLI command](../cli/setup.md) (added in Appium `2.6`), for example:
```bash
appium setup mobile
```
This will install Appium and the two drivers for you in one go. Please uninstall any existing Appium 1
`npm` packages (with `npm uninstall -g appium`) if you get an installation or startup error.
Check the [Managing Drivers and Plugins guide](./managing-exts.md) for more information.
### :bangbang: Drivers installation path
!!! info "Actions Needed"
When you installed Appium 1, all available drivers would be installed at the same time as the main
Appium server, at `/path/to/appium/node_modules`. For example, `appium-webdriveragent` was located
When installing Appium 2, use one of the above approaches for installing your desired drivers
### Driver Installation Path Changed
When installing Appium 1, all available drivers would be installed as dependencies of the main
Appium server, in `/path/to/appium/node_modules`. For example, `appium-webdriveragent` was located
at `/path/to/appium/node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent`.
Appium 2 installs such dependencies in the path defined by the `APPIUM_HOME` environment variable.
The default path is `~/.appium`. So, `appium-webdriveragent` would now be located at
`$APPIUM_HOME/node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent`.
In Appium 2, drivers (and plugins) are installed at the path defined by the `APPIUM_HOME`
environment variable, whose default value is `~/.appium`. So, `appium-webdriveragent` would now be
located at `$APPIUM_HOME/node_modules/appium-xcuitest-driver/node_modules/appium-webdriveragent`.
### :bangbang: Chromedriver installation flags
!!! info "Actions Needed"
In Appium 1, it was possible to customize the way Chromedriver was installed (as part of the
UiAutomator2 driver for example), using the following command line flags:
If your code uses paths to Appium driver files, update it to use the `APPIUM_HOME` environment
variable
* `--chromedriver-skip-install`
* `--chromedriver-version`
* `--chromedriver-cdnurl`
### Drivers Updated Separately
Because Appium 2 now installs drivers for you, and because these flags were implemented as `npm`
config flags, they will no longer work. Instead, use the following environment variables during
driver installation:
In Appium 1, in order to get updates to your drivers, you would simply wait for those updates to be
rolled into a new release of Appium, and then update your Appium version. With Appium 2, since the
server and drivers are separate packages, they can release new versions independently from each
other - this means that you no longer need to wait for a new Appium server release, but can install
the latest driver versions right away.
* `APPIUM_SKIP_CHROMEDRIVER_INSTALL`
* `CHROMEDRIVER_VERSION`
* `CHROMEDRIVER_CDNURL`
For example:
```bash
APPIUM_SKIP_CHROMEDRIVER_INSTALL=1 appium driver install uiautomator2
```
### :bangbang: Driver-specific command line options
With Appium 1, command-line options specific to particular drivers were all hosted on the main
Appium server. So, for example, `--chromedriver-executable` was a CLI parameter you could use with
Appium to set the location of a specific Chromedriver version for use with, say, the UiAutomator2 driver.
With Appium 2, all driver- and platform-specific CLI params have been moved to the drivers themselves.
To access the corresponding functionality, you'll need to refer to the driver/plugin documentation.
In some cases, the extension will continue to expose CLI parameters. For example, the XCUITest driver
used to expose a parameter `--webdriveragent-port`. Now, to access this parameter, it should be
prefixed with `driver-xcuitest`, to differentiate it from parameters other drivers might also expose.
To use this parameter, you thus need to start Appium with something like:
```bash
appium --driver-xcuitest-webdriveragent-port=5000
```
Some drivers have done away with CLI args entirely in favour of default capabilities. With the
above-mentioned `--chromedriver-executable` parameter for example, you now need to take advantage
of the `appium:chromedriverExecutable` capability supported by the UiAutomator2 driver. To set this
capability from the command line, do the following:
```bash
appium --default-capabilities '{"appium:chromedriverExecutable": "/path/to/chromedriver"}'
```
### :bangbang: Driver-specific automation commands
The definition of certain commands that pertain only to specific drivers has been moved to those
drivers' implementations. For example, `pressKeyCode` is specific to the UiAutomator2 driver and is
now understood only by that driver. In practice, the only breaking change here is the kind of error
you would encounter if the appropriate driver is not installed. Previously, you would get a `501
Not Yet Implemented` error if using a driver that didn't implement the command. Now, you will get
a `404 Not Found` error because if a driver that doesn't know about the command is not active, the
main Appium server will not define the route corresponding to the command.
### :bangbang: Driver updates
In the past, to get updates to your iOS or Android drivers, you'd simply wait for those updates to
be rolled into a new release of Appium, and then update your Appium version. With Appium 2, the
Appium server and the Appium drivers are versioned and released separately. This means that drivers
can be on their own release cadence, and you can get the latest driver version right away, rather
than waiting for a new Appium server release. The way to check for driver updates is with the CLI:
Checking for driver updates is done by using the [Appium Extension CLI](../cli/extensions.md):
```bash
appium driver list --updates
@@ -152,213 +85,284 @@ If any updates are available, you can then run the `update` command for any give
appium driver update xcuitest
```
(For a complete description of the update command, check out the
[Extension CLI](../cli/extensions.md#update) documentation)
To update the Appium server itself, you do the same thing as in the past: `npm install -g appium`.
Now, installing new versions of the Appium server will leave your drivers intact, so the whole
process will be much more quick.
If you would like to update to a specific driver version, not the latest, please uninstall the driver
and install the desired version using the `install` subcommand instead of `update`.
Updating the Appium server itself is the same as before:
```bash
appium driver uninstall xcuitest
appium driver install xcuitest@4.11.1
npm update -g appium
```
### :bangbang: Protocol changes
However, in Appium 2 this process is a lot quicker, since drivers are no longer bundled with the
server package.
!!! info "Actions Needed"
Make sure to use the [Appium Extension CLI](../cli/extensions.md) to manage your drivers
### Deprecated Packages No Longer Supported
The Appium 1 ecosystem included several drivers, clients and other packages that had since been
deprecated and replaced with newer packages. Appium 2 no longer includes support for these packages,
and it is recommended to migrate to the following replacements:
|Appium 1 Package|Replacement in Appium 2|
|--|--|
|iOS Driver|[XCUITest Driver](https://appium.github.io/appium-xcuitest-driver/latest/)|
|UiAutomator Driver|[UiAutomator2](https://github.com/appium/appium-uiautomator2-driver/)|
|`wd` Client|[WebdriverIO Client](https://webdriver.io/)|
|Appium Desktop|[Appium Inspector](https://github.com/appium/appium-inspector)|
!!! info "Actions Needed"
If you are using any of the aforementioned package(s), migrate to their recommended replacement(s)
### Default Server Base Path Changed
In Appium 1, the default Appium server URL was `http://localhost:4723/wd/hub`, where the `/wd/hub`
part (the base path) was a legacy convention from Selenium 1. Appium 2 changes the default base
path to `/`, therefore the default server URL is now `http://localhost:4723/`.
!!! info "Actions Needed"
In your test scripts, change the base path of the target server URL from `/wd/hub` to `/`.
Alternatively, you can retain the Appium 1 base path by launching Appium with the
`--base-path=/wd/hub` [command-line argument](../cli/args.md).
### Server Port 0 No Longer Supported
In Appium 1, it was possible to specify `--port 0` during server startup, which had the effect of
starting Appium on a random free port. Appium 2 no longer allows this, and requires port values to
be `1` or higher. If you wish to start Appium on a random port, you must now take care of this on
your own prior to launching the server.
!!! info "Actions Needed"
If you are launching Appium with `--port 0`, change the port number value to `1` or higher
### Driver-Specific CLI Options Changed
With Appium 1, command-line options specific to particular drivers were all hosted on the main
Appium server. So, for example, `--chromedriver-executable` was a CLI parameter you could use to
set the Chromedriver location for the UiAutomator2 driver.
In Appium 2, all driver-specific CLI options have been moved to the drivers themselves. However,
depending on the driver, these options may now need to be passed in another way:
* Some options can still be passed as different CLI flags, for example:
```bash
appium --webdriveragent-port=5000 # Appium 1
appium --driver-xcuitest-webdriveragent-port=5000 # Appium 2
```
* Some options can now be passed as environment variables, for example:
```bash
appium --chromedriver-version=100 # Appium 1
CHROMEDRIVER_VERSION=100 appium # Appium 2
```
* Some options can now be passed as [capabilities](https://appium.io/docs/en/latest/guides/caps/),
for example:
```
appium --chromedriver-executable=/path/to/chromedriver # Appium 1
{"appium:chromedriverExecutable": "/path/to/chromedriver"} # Appium 2
```
!!! info "Actions Needed"
If you are using driver-specific CLI options, refer to that driver's documentation for how to
apply them in Appium 2
### Filepaths No Longer Supported for Some CLI Options
In Appium 1, some server command-line options could be invoked by passing a filepath as their
value, and Appium would then parse the contents of that file as the actual value for that option.
There were four options that supported this:
* `--nodeconfig`
* `--default-capabilities`
* `--allow-insecure`
* `--deny-insecure`
Appium 2 no longer attempts to parse the contents of filepaths passed to these options, and offers
two ways to specify the value for these options:
* As strings, directly on the command line
* `--nodeconfig` / `--default-capabilities`: JSON string
* `--allow-insecure` / `--deny-insecure`: comma-separated list
* In the [Appium Configuration file](./config.md)
!!! info "Actions Needed"
If you are using any of the aforementioned CLI options with a filepath value, update your code
to pass the file contents either directly or through the Appium config file
### Old Protocols Dropped
Appium's API is based on the [W3C WebDriver Protocol](https://www.w3.org/TR/webdriver/), and it has
supported this protocol for years. Before the W3C WebDriver Protocol was designed as a web standard,
several other protocols were used for both Selenium and Appium. These protocols were the "JSONWP"
(JSON Wire Protocol) and "MJSONWP" (Mobile JSON Wire Protocol). The W3C Protocol differs from the
(M)JSONWP protocols in a few small ways.
supported this protocol for years. Before this protocol was designed as a web standard, the
[JSON Wire Protocol](https://www.selenium.dev/documentation/legacy/json_wire_protocol/) (JSONWP)
and [Mobile JSON Wire Protocol](https://github.com/SeleniumHQ/mobile-spec/blob/master/spec-draft.md)
(MJSONWP) were used instead.
Up until Appium 2, Appium supported both protocols, so that older Selenium/Appium clients could
still communicate with newer Appium servers. Appium 2 removes support for older protocols and is
now only compatible with the W3C WebDriver Protocol.
In Appium 1, all of these protocols were supported, so that older Selenium/Appium clients could
still communicate with newer Appium servers. Appium 2 removes support for JSONWP/MJSONWP and is now
only compatible with the W3C WebDriver Protocol.
### :bangbang: Capabilities must use vendor prefix
!!! info "Actions Needed"
One significant difference between old and new protocols is in the format of capabilities.
Previously called "desired capabilities", and now called simply "capabilities", there is now a
requirement for a so-called "vendor prefix" on any non-standard capabilities. The list of standard
capabilities is given in the [WebDriver Protocol spec](https://www.w3.org/TR/webdriver/#capabilities),
and includes a few commonly used capabilities such as `browserName` and `platformName`.
Make sure you are using Selenium/Appium clients compatible with the W3C WebDriver Protocol
These standard capabilities continue to be used as-is. All other capabilities must include a
"vendor prefix" in their name. A vendor prefix is a string followed by a colon, such as `appium:`.
Most of Appium's capabilities go beyond the standard W3C capabilities and must therefore include
vendor prefixes (we recommend that you use `appium:` unless directed otherwise by documentation).
For example:
### Capabilities Require Vendor Prefix
- `appium:app`
- `appium:noReset`
- `appium:deviceName`
In Appium 1, in order to create a session, you had to specify certain desired capabilities, which
would indicate session parameters, e.g. the driver you want to use. Appium 2 retains this behavior
and continues to accept desired capabilities (now renamed simply to 'capabilities'), but as part of
the W3C WebDriver Protocol specification, all non-standard capabilities are now required to use a
vendor prefix.
This requirement may or may not be a breaking change for your test suites when targeting Appium 2.
If you're using an updated Appium client (at least one maintained by the Appium team), the client
will add the `appium:` prefix for you on all necessary capabilities automatically. New versions of
[Appium Inspector](https://github.com/appium/appium-inspector) will also do this. Cloud-based Appium
providers may also do this. So simply be aware that if you get any messages to the effect that your
capabilities lack a vendor prefix, this is how you solve that problem.
The list of standard capabilities is described in the [WebDriver Protocol specification](https://www.w3.org/TR/webdriver/#capabilities),
and includes a few commonly used capabilities like `browserName` and `platformName`. All other
capabilities must now start with the vendor name and a colon (the vendor prefix), for example,
`moz:` or `goog:`. Since most of Appium's capabilities go beyond the standard W3C capabilities,
all of them must include the `appium:` prefix (unless specified otherwise):
To make everyone's lives a bit easier, we've also introduced the option of grouping up all
Appium-related capabilities into one object capability, `appium:options`. You can bundle together
anything that you would normally put an `appium:` prefix on into this one capability. Here's an
example (in raw JSON) of how you might start an iOS session on the Safari browser using `appium:options`:
```json
{
"platformName": "iOS",
"browserName": "Safari",
"appium:options": {
"platformVersion": "14.4",
"deviceName": "iPhone 11",
"automationName": "XCUITest"
}
}
```
deviceName # Appium 1
appium:deviceName # Appium 2
```
(Of course, each client will have a different way of creating structured capabilities like
`appium:options` or other ones that you might have seen such as `goog:chromeOptions`).
This requirement may or may not be a breaking change for your test suites. Up-to-date versions of
official Appium clients and the Appium Inspector will automatically add the `appium:` prefix to all
non-standard capabilities, and the same may apply to cloud-based Appium providers.
!!! note
Additionally, if you are starting a session with multiple Appium-specific capabilities (which will
likely be the case), it may seem repetitive to add the `appium:` prefix to each individual
capability. To avoid this, you can optionally group up all these capabilities under a single object
capability, `appium:options`, for example:
=== "Default Approach"
```json
{
"platformName": "iOS",
"browserName": "Safari",
"appium:platformVersion": "14.4",
"appium:deviceName": "iPhone 11",
"appium:automationName": "XCUITest"
}
```
=== "With `appium:options`"
```json
{
"platformName": "iOS",
"browserName": "Safari",
"appium:options": {
"platformVersion": "14.4",
"deviceName": "iPhone 11",
"automationName": "XCUITest"
}
}
```
!!! warning
Capabilities included in the `appium:options` object will overwrite capabilities of the same
name that are used outside of this object. (The `appium:options` syntax support by cloud
providers may vary.)
name that are used outside of this object. Note that cloud provider support for the
`appium:options` syntax may vary.
For more information on capabilities, have a look at the [Capabilities Guide](./caps.md).
### :bangbang: Removed Commands
!!! info "Actions Needed"
In addition to commands which have been moved to driver implementations, commands which were a part
of the old JSON Wire Protocol and not a part of the W3C Protocol are no longer available:
Add the `appium:` prefix to all Appium-specific capabilities used in your tests, or wrap them
inside an `appium:options` object
- TODO (these commands are being identified and removed and will be updated here when complete)
### Advanced Features Moved to Plugins
If you use a modern Appium or Selenium client, you should no longer have access to these anyway,
so any breaking changes should appear on the client side first and foremost.
One of the design goals for Appium 2 is to extract non-core features into special extensions called
[plugins](../ecosystem/plugins.md). Two such features of Appium 1 have been moved to plugins, and
are no longer bundled with Appium 2:
### :bangbang: Image analysis features moved to plugin
|Feature|Plugin Name|
|--|--|
|Image-related features (comparison, search by image, etc...)|[`images`](https://github.com/appium/appium/tree/master/packages/images-plugin)|
|The Execute Driver Script feature|[`execute-driver`](https://github.com/appium/appium/tree/master/packages/execute-driver-plugin)|
One of the design goals for Appium 2 is to migrate non-core features into special extensions called
[plugins](../ecosystem/plugins.md). This allows people to opt into features which require extra time
to download or extra system setup. The various image-related features of Appium (image comparison,
finding elements by image, etc...) have been moved into an officially supported plugin called
[images](https://github.com/appium/appium/tree/master/packages/images-plugin).
!!! info "Actions Needed"
If you use these image-related methods, to continue accessing them you will need to do two things:
If you were using the image-related features and/or the execute driver script feature in Appium
1, first install their plugin(s):
```
appium plugin install images
appium plugin install execute-driver
```
Afterwards, make sure to activate the plugin(s) upon launching the Appium server:
```
appium --use-plugins=images,execute-driver
```
1. Install the plugin: `appium plugin install images`
2. Ensure you start the Appium server with access to run the plugin by including it in the list of
plugins designated on the command line, e.g., `appium --use-plugins=images`
### Endpoint Changes
Image-related commands will also be removed on the client side of things, which means you will need
to follow the instructions on the plugin README for installing client-side plugins to access these features.
A few server endpoints used in Appium 1 were accepting old or unused parameters. Appium 2 removes
support for these parameters. The following is a list of these changed endpoints, along with the
parameters they no longer accept, as well as the parameters they continue to accept in Appium 2.
### :bangbang: Execute Driver Script command moved to plugin
* `POST /session/:sessionId/appium/device/gsm_signal`
* :octicons-x-24: `signalStrengh`
* :octicons-check-24: `signalStrength`
* `POST /session/:sessionId/appium/element/:elementId/value`
* :octicons-x-24: `value`
* :octicons-check-24: `text`
* `POST /session/:sessionId/appium/element/:elementId/replace_value`
* :octicons-x-24: `value`
* :octicons-check-24: `text`
If you use the advanced Execute Driver Script feature (which allows you to send in a WebdriverIO
script to have it executed completely on the server instead of command-by-command from the client),
this functionality has been moved to a plugin. Here's what to do to keep using it:
!!! info "Actions Needed"
1. Install the plugin: `appium plugin install execute-driver`
2. Ensure you start the Appium server with access to run the plugin by including it in the list of
plugins designated on the command line, e.g., `appium --use-plugins=execute-driver`
Check your Appium client documentation for the methods using these endpoints, and adjust your
code to only use the accepted parameters
### :bangbang: External Files No Longer Supported for `--nodeconfig`, `--default-capabilities`, `--allow-insecure` and `--deny-insecure`
### Internal Packages Renamed
These options can be provided as strings on the command line (a JSON string for `--nodeconfig` and
a comma-separated list of strings for `--allow-insecure` and `--deny-insecure`). Arguments provided
on the command line will likely need to be quoted or escaped.
In Appium 1, the internal dependency packages were each located in their own repository. Appium 2
moves to a monorepo structure and therefore renames many of these packages, for example:
The recommended method to provide these options is through a [configuration file](./config.md).
```
appium-base-driver # Appium 1
@appium/base-driver # Appium 2
```
In summary, if you are using a JSON Appium config file, you can simply cut-and-paste the contents
of your "nodeconfig" JSON file into the value of the `server.nodeconfig` property. Any CSV-like
files you had previously provided for `--allow-insecure` and `--deny-insecure` become the values
of the `server.allow-insecure` and `server.deny-insecure` properties in the Appium config files
(respectively); both are arrays of strings.
!!! info "Actions Needed"
### :bangbang: Old drivers removed
The old iOS and Android (UiAutomator 1) drivers and related tools (e.g., `authorize-ios`) have been
removed. They haven't been relevant for many years anyway.
### :bangbang: Server can no longer be started with `--port 0`
In Appium 1, it was possible to specify `--port 0` during server startup. This had the effect of
starting Appium on a random free port. In Appium 2, port values must be `1` or higher. The random
port assignment was never an intentional feature of Appium 1, but a consequence of how Node's
HTTP servers work and the fact that there was no port input validation in Appium 1. If you want
to find a random free port to start Appium on, you must now take care of this on your own prior to
starting Appium. Starting Appium on an explicit and known port is the correct practice moving
forward.
### :warning: Internal packages renamed
Some Appium-internal NPM packages have been renamed (for example, `appium-base-driver` is now
`@appium/base-driver`). This is not a breaking change for Appium users, only for people who have
built software that directly incorporates Appium's code.
### :warning: `wd` JavaScript client library no longer supported
For many years, some of Appium's authors maintained the [WD](https://github.com/admc/wd) client
library. This library has been deprecated and has not been updated for use with the W3C WebDriver
protocol. As such, if you're using this library you'll need to move to a more modern one. We
recommend [WebdriverIO](https://webdriver.io).
### :warning: Appium Desktop replaced with Appium Inspector
The inspector functionality of Appium Desktop has been moved to its own app:
[Appium Inspector](https://github.com/appium/appium-inspector). It is fully compatible with
standalone Appium 2 servers, but also works with later versions of Appium 1 servers. Appium Desktop
itself has been deprecated and is not compatible with Appium 2.
In addition to the app, Appium Inspector also has a browser version, accessible at
[inspector.appiumpro.com](https://inspector.appiumpro.com). Note that in order to use the
browser version with a local Appium server, you'll need to first start the server with the
`--allow-cors` flag.
If you do not directly import Appium packages into your code - none! However, if you do, make
sure to update the names of your Appium package imports!
## Major New Features
Apart from the breaking changes mentioned above, in this section is a list of some of the major new
features you may wish to take advantage of with Appium 2.
Apart from the breaking changes mentioned above, here are some of the major new features you may
wish to take advantage of with Appium 2:
### Plugins
### Third-Party Drivers and Plugins
#### :tada: Server Plugins
You are no longer limited to official drivers or plugins, or ones that the Appium team even knows
about! Developers can now create their own custom drivers or plugins, which can be installed via
Appium's [Extension CLI](../cli/extensions.md) from `npm`, `git`, GitHub, or even the local
filesystem. Interested in building a driver or plugin? Check out the
[Building Drivers](../developing/build-drivers.md) and
[Building Plugins](../developing/build-plugins.md) guides.
Appium extension authors can now develop their own server plugins, which can intercept and modify
any Appium command, or even adjust the way the underlying Appium HTTP server itself works. To learn
more about plugins, read the new [Appium Introduction](../intro/index.md). Interested in building
a plugin? Check out the [Building Plugins](../developing/build-plugins.md) guide.
### Configuration Files
### :tada: Install drivers and plugins from anywhere
You're no longer limited to the drivers that come with Appium, or that the Appium team even knows
about! Appium extension authors can now develop custom drivers, which can be downloaded or
installed via Appium's [Extension CLI](../cli/extensions.md) from `npm`, `git`, GitHub, or even the
local filesystem. Interested in building a driver? Check out the [Building
Drivers](../developing/build-drivers.md) guide.
### :tada: Configuration Files
Appium now supports _configuration files_ in addition to command-line arguments. In a nutshell,
nearly all arguments which Appium 1 required to be provided on the CLI are now able to be expressed
via a configuration file. Configuration files may be in JSON, JS, or YAML format. See the
[Config Guide](./config.md) for a full explanation.
Appium now supports _configuration files_ in addition to command-line arguments. Nearly all options
or flags that had to be specified on the CLI in Appium 1, can now also be provided in a
configuration file. The file can be in JSON, JS, or YAML format. For more information, refer to
the [Config File Guide](./config.md).
## Special Notes for Cloud Providers
The rest of this document has applied to Appium generally, but some of the architectural changes in
Appium 2 will constitute breaking changes for Appium-related service providers, whether a
cloud-based Appium host or an internal service. At the end of the day, the maintainer of the Appium
server is responsible for installing and making available the various Appium drivers and plugins
that end users may wish to use.
Most of this guide has applied to Appium end users or developers, but some of the architectural
changes in Appium 2 will constitute breaking changes for different Appium service providers. At the
end of the day, the maintainer of the Appium server is responsible for installing and exposing the
various Appium drivers and plugins that end users may wish to use.
We encourage cloud providers to thoroughly read and understand our [recommendation for cloud
provider capabilities](./caps.md#special-notes-for-cloud-providers) in order to support user needs in
-7
View File
@@ -12,13 +12,6 @@ title: Welcome
}
</style>
<div style="text-align:center;width:100%;background-color:#ec366d;margin-top:-3em;margin-bottom:2em;">
<h3 style="color:#ffffff;padding: 8px;">
AppiumConf 2025 is partnering with SeleniumConf<br/> <span style="font-size:0.8em;">March 26-28 in Valencia, Spain. Join us to learn and connect with the community!</span><br/>
<a style="color:#fcba12" href="https://seleniumconf.com/" target="_blank">Register Now</a>
</h3>
</div>
<div style="text-align: center">
<img src="assets/images/appium-logo-horiz.png" style="max-width: 400px;" />
</div>
+1
View File
@@ -58,6 +58,7 @@ nav:
- guides/config.md
- guides/security.md
- guides/log-filters.md
- guides/headers.md
- guides/grid.md
- guides/caching.md
- guides/tls.md
@@ -43,6 +43,7 @@ appium driver install <驱动名称>
|[Tizen](https://github.com/Samsung/appium-tizen-driver)|`--source=npm appium-tizen-driver`|Android|Native|Community / Samsung|
|[TizenTV](https://github.com/headspinio/appium-tizen-tv-driver)|`--source=npm appium-tizen-tv-driver`|Samsung TV|Web|HeadSpin|
|[Youi](https://github.com/YOU-i-Labs/appium-youiengine-driver)|`--source=npm appium-youiengine-driver`|iOS, Android, macOS, Linux, tvOS|Native|Community / You.i|
|[NovaWindows](https://github.com/AutomateThePlanet/appium-novawindows-driver)|`--source=npm appium-novawindows-driver`|Windows|Native|Community / Automate The Planet|
!!! 注意
+7 -7
View File
@@ -62,18 +62,18 @@
"dependencies": {
"@appium/base-driver": "^10.0.0-beta.0",
"@appium/base-plugin": "^3.0.0-beta.0",
"@appium/docutils": "^1.0.34",
"@appium/logger": "^1.6.1",
"@appium/docutils": "^1.1.0",
"@appium/logger": "^1.7.0",
"@appium/schema": "^0.8.1",
"@appium/support": "^6.0.8",
"@appium/types": "^0.25.2",
"@appium/support": "^6.1.0",
"@appium/types": "^0.25.3",
"@sidvind/better-ajv-errors": "3.0.1",
"ajv": "8.17.1",
"ajv-formats": "3.0.1",
"argparse": "2.0.1",
"async-lock": "1.4.1",
"asyncbox": "3.0.0",
"axios": "1.8.4",
"axios": "1.9.0",
"bluebird": "3.7.2",
"lilconfig": "3.1.3",
"lodash": "4.17.21",
@@ -84,11 +84,11 @@
"semver": "7.7.1",
"source-map-support": "0.5.21",
"teen_process": "2.3.1",
"type-fest": "4.38.0",
"type-fest": "4.40.0",
"winston": "3.17.0",
"wrap-ansi": "7.0.0",
"ws": "8.18.1",
"yaml": "2.7.0"
"yaml": "2.7.1"
},
"engines": {
"node": "^20.9.0 || >=22.11.0",
@@ -1,5 +1,5 @@
{
"devDependencies": {
"webdriverio": "9.12.2"
"webdriverio": "9.12.7"
}
}
+10
View File
@@ -3,6 +3,16 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [9.17.0](https://github.com/appium/appium/compare/@appium/base-driver@9.16.4...@appium/base-driver@9.17.0) (2025-04-25)
### Features
* Add a possibility to mask sensitive log values depending on request headers ([#21123](https://github.com/appium/appium/issues/21123)) ([c24d2ac](https://github.com/appium/appium/commit/c24d2ac46123f41ee9b54e0adefacfabd149089c))
* **base-driver:** Accept `x-request-id` as override to generated requestId in `handleLogContext` ([#21154](https://github.com/appium/appium/issues/21154)) ([a82476f](https://github.com/appium/appium/commit/a82476f2fcb4aa3a3c4660d96fdd261a98afa4af))
## [9.16.4](https://github.com/appium/appium/compare/@appium/base-driver@9.16.3...@appium/base-driver@9.16.4) (2025-03-17)
+13 -4
View File
@@ -57,13 +57,11 @@ export function allowCrossDomainAsyncExecute(basePath) {
* @returns {any}
*/
export function handleLogContext(req, res, next) {
const requestId = util.uuidV4();
const requestId = fetchHeaderValue(req, 'x-request-id') || util.uuidV4();
const sessionId = SESSION_ID_PATTERN.exec(req.url)?.[1];
const sessionInfo = sessionId ? {sessionId, sessionSignature: calcSignature(sessionId)} : {};
const isSensitiveHeaderValue = _.isArray(req.headers['x-appium-is-sensitive'])
? _.first(req.headers['x-appium-is-sensitive'])
: req.headers['x-appium-is-sensitive'];
const isSensitiveHeaderValue = fetchHeaderValue(req, 'x-appium-is-sensitive');
log.updateAsyncContext({
requestId,
@@ -141,3 +139,14 @@ export function catch404Handler(req, res) {
const [status, body] = getResponseForW3CError(new errors.UnknownCommandError());
res.status(status).json(body);
}
/**
* @param {import('express').Request} req
* @param {string} name
* @returns {string | undefined}
*/
function fetchHeaderValue(req, name) {
return _.isArray(req.headers[name])
? req.headers[name][0]
: req.headers[name];
}
+12 -6
View File
@@ -251,19 +251,23 @@ export const METHOD_MAP = /** @type {const} */ ({
// Appium specific
//
'/session/:sessionId/ime/available_engines': {
GET: {command: 'availableIMEEngines'},
GET: {command: 'availableIMEEngines', deprecated: true},
},
'/session/:sessionId/ime/active_engine': {
GET: {command: 'getActiveIMEEngine'},
GET: {command: 'getActiveIMEEngine', deprecated: true},
},
'/session/:sessionId/ime/activated': {
GET: {command: 'isIMEActivated'},
GET: {command: 'isIMEActivated', deprecated: true},
},
'/session/:sessionId/ime/deactivate': {
POST: {command: 'deactivateIMEEngine'},
POST: {command: 'deactivateIMEEngine', deprecated: true},
},
'/session/:sessionId/ime/activate': {
POST: {command: 'activateIMEEngine', payloadParams: {required: ['engine']}},
POST: {
command: 'activateIMEEngine',
payloadParams: {required: ['engine']},
deprecated: true,
},
},
'/session/:sessionId/rotation': {
GET: {command: 'getRotation'},
@@ -288,16 +292,18 @@ export const METHOD_MAP = /** @type {const} */ ({
GET: {command: 'getContexts'},
},
'/session/:sessionId/network_connection': {
GET: {command: 'getNetworkConnection'},
GET: {command: 'getNetworkConnection', deprecated: true},
POST: {
command: 'setNetworkConnection',
payloadParams: {unwrap: 'parameters', required: ['type']},
deprecated: true,
},
},
'/session/:sessionId/receive_async_response': {
POST: {
command: 'receiveAsyncResponse',
payloadParams: {required: ['status', 'value']},
deprecated: true,
},
},
'/appium/sessions': {
+4 -4
View File
@@ -44,12 +44,12 @@
"test:types": "tsd"
},
"dependencies": {
"@appium/support": "^6.0.8",
"@appium/types": "^0.25.2",
"@appium/support": "^6.1.0",
"@appium/types": "^0.25.3",
"@colors/colors": "1.6.0",
"async-lock": "1.4.1",
"asyncbox": "3.0.0",
"axios": "1.8.4",
"axios": "1.9.0",
"bluebird": "3.7.2",
"body-parser": "1.20.3",
"express": "5.0.1",
@@ -62,7 +62,7 @@
"path-to-regexp": "8.2.0",
"serve-favicon": "2.5.0",
"source-map-support": "0.5.21",
"type-fest": "4.38.0"
"type-fest": "4.40.0"
},
"optionalDependencies": {
"spdy": "4.0.2"
@@ -1,4 +1,7 @@
import {match} from 'path-to-regexp';
import sinon from 'sinon';
import log from '../../../lib/express/logger';
import {handleLogContext} from '../../../lib/express/middleware';
describe('middleware', function () {
before(async function () {
@@ -21,4 +24,55 @@ describe('middleware', function () {
match(pathname)(currentPathname).should.not.be.false;
});
});
describe('handleLogContext', function () {
let req, res, next, updateAsyncContextStub;
beforeEach(function () {
req = {
headers: {},
url: '/some/path'
};
res = {};
next = sinon.spy();
updateAsyncContextStub = sinon.stub(log, 'updateAsyncContext');
});
afterEach(function () {
updateAsyncContextStub.restore();
});
it('should use provided x-request-id header', function () {
const testRequestId = '123-test-id';
req.headers['x-request-id'] = testRequestId;
handleLogContext(req, res, next);
updateAsyncContextStub.calledOnce.should.be.true;
updateAsyncContextStub.firstCall.args[0].should.have.property('requestId', testRequestId);
next.calledOnce.should.be.true;
});
it('should handle x-request-id when provided as array', function () {
const testRequestId = '123-test-id';
req.headers['x-request-id'] = [testRequestId, 'ignored-id'];
handleLogContext(req, res, next);
updateAsyncContextStub.calledOnce.should.be.true;
updateAsyncContextStub.firstCall.args[0].should.have.property('requestId', testRequestId);
next.calledOnce.should.be.true;
});
it('should generate uuid when x-request-id is not provided', function () {
handleLogContext(req, res, next);
updateAsyncContextStub.calledOnce.should.be.true;
updateAsyncContextStub.firstCall.args[0].should.have.property('requestId');
updateAsyncContextStub.firstCall.args[0].requestId.should.match(
/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
);
next.calledOnce.should.be.true;
});
});
});
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [2.3.6](https://github.com/appium/appium/compare/@appium/base-plugin@2.3.5...@appium/base-plugin@2.3.6) (2025-04-25)
**Note:** Version bump only for package @appium/base-plugin
## [2.3.5](https://github.com/appium/appium/compare/@appium/base-plugin@2.3.4...@appium/base-plugin@2.3.5) (2025-03-17)
**Note:** Version bump only for package @appium/base-plugin
+1 -1
View File
@@ -41,7 +41,7 @@
},
"dependencies": {
"@appium/base-driver": "^10.0.0-beta.0",
"@appium/support": "^6.0.8"
"@appium/support": "^6.1.0"
},
"engines": {
"node": "^20.9.0 || >=22.11.0",
+14
View File
@@ -3,6 +3,20 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.1.0](https://github.com/appium/appium/compare/@appium/docutils@1.0.34...@appium/docutils@1.1.0) (2025-04-25)
### Features
* **docutils:** add MkDocs Material codeblock & text format features ([#21184](https://github.com/appium/appium/issues/21184)) ([55da22f](https://github.com/appium/appium/commit/55da22fc4000a1142782cc5fddcb526cb30b2f09))
### Bug Fixes
* **docutils:** add & adjust various log messages ([#21160](https://github.com/appium/appium/issues/21160)) ([804b1a3](https://github.com/appium/appium/commit/804b1a3c15acdf95066d45e7c36518cb8600dbbb))
## [1.0.34](https://github.com/appium/appium/compare/@appium/docutils@1.0.33...@appium/docutils@1.0.34) (2025-03-17)
**Note:** Version bump only for package @appium/docutils
+23 -10
View File
@@ -1,20 +1,30 @@
markdown_extensions:
- meta
- attr_list
- admonition
- attr_list
- footnotes
- md_in_html
- pymdownx.highlight:
anchor_linenums: true
- pymdownx.inlinehilite
- pymdownx.snippets
- pymdownx.superfences
- meta
- pymdownx.caret
- pymdownx.critic
- pymdownx.details
- pymdownx.tabbed:
alternate_style: true
- pymdownx.emoji:
emoji_index: !!python/name:material.extensions.emoji.twemoji
emoji_generator: !!python/name:material.extensions.emoji.to_svg
- footnotes
- pymdownx.highlight:
anchor_linenums: true
line_spans: __span
pygments_lang_class: true
- pymdownx.inlinehilite
- pymdownx.keys
- pymdownx.mark
- pymdownx.snippets
- pymdownx.superfences
- pymdownx.tabbed:
alternate_style: true
- pymdownx.tasklist:
custom_checkbox: true
- pymdownx.tilde
- tables
- toc:
permalink: true
@@ -63,6 +73,9 @@ theme:
quote: octicons/quote-16
features:
- content.action.edit
- content.code.annotate
- content.code.copy
- content.tabs.link
- navigation.sections
- navigation.tabs
- navigation.top
+7 -8
View File
@@ -16,10 +16,9 @@ import {
NAME_BIN,
NAME_MIKE,
NAME_MKDOCS_YML,
NAME_PYTHON,
} from '../constants';
import {DocutilsError} from '../error';
import {findMike, findMkDocsYml, findPython, readPackageJson} from '../fs';
import {findMike, findMkDocsYml, isMkDocsInstalled, readPackageJson, requirePython} from '../fs';
import {getLogger} from '../logger';
import {argify, spawnBackgroundProcess, SpawnBackgroundProcessOpts, stopwatch} from '../util';
@@ -37,6 +36,7 @@ async function doServe(
opts: SpawnBackgroundProcessOpts = {},
) {
const finalArgs = ['serve', ...args];
log.debug('Executing %s via: %s %O', NAME_MIKE, mikePath, finalArgs);
return spawnBackgroundProcess(mikePath, finalArgs, opts);
}
@@ -99,18 +99,17 @@ export async function deploy({
}: DeployOpts = {}) {
const stop = stopwatch('deploy');
const pythonPath = await findPython();
await requirePython();
if (!pythonPath) {
throw new DocutilsError(
`Could not find ${NAME_PYTHON}3/${NAME_PYTHON} executable in PATH; please install Python v3`,
);
const mkdocsInstalled = await isMkDocsInstalled();
if (!mkdocsInstalled) {
throw new DocutilsError(`Could not find MkDocs executable; please run "${NAME_BIN} init"`);
}
mkDocsYmlPath = mkDocsYmlPath ?? (await findMkDocsYml(cwd));
if (!mkDocsYmlPath) {
throw new DocutilsError(
`Could not find ${NAME_MKDOCS_YML} from ${cwd}; run "${NAME_BIN} init" to create it`,
`Could not find ${NAME_MKDOCS_YML} from ${cwd}; please run "${NAME_BIN} init"`,
);
}
version = version ?? (await findDeployVersion(packageJsonPath, cwd));
+8 -8
View File
@@ -7,9 +7,9 @@
import path from 'node:path';
import {exec, TeenProcessExecOptions} from 'teen_process';
import {DEFAULT_SITE_DIR, NAME_BIN, NAME_MKDOCS, NAME_MKDOCS_YML, NAME_PYTHON} from '../constants';
import {DEFAULT_SITE_DIR, NAME_BIN, NAME_MKDOCS, NAME_MKDOCS_YML} from '../constants';
import {DocutilsError} from '../error';
import {findMkDocsYml, findPython, readMkDocsYml} from '../fs';
import {findMkDocsYml, isMkDocsInstalled, readMkDocsYml, requirePython} from '../fs';
import {getLogger} from '../logger';
import {relative, spawnBackgroundProcess, SpawnBackgroundProcessOpts, stopwatch} from '../util';
@@ -58,11 +58,11 @@ export async function buildSite({
}: BuildMkDocsOpts = {}) {
const stop = stopwatch('build-mkdocs');
const pythonPath = await findPython();
if (!pythonPath) {
throw new DocutilsError(
`Could not find ${NAME_PYTHON}3/${NAME_PYTHON} executable in PATH; please install Python v3`,
);
const pythonPath = await requirePython();
const mkdocsInstalled = await isMkDocsInstalled();
if (!mkdocsInstalled) {
throw new DocutilsError(`Could not find MkDocs executable; please run "${NAME_BIN} init"`);
}
mkDocsYmlPath = mkDocsYmlPath
@@ -70,7 +70,7 @@ export async function buildSite({
: await findMkDocsYml(cwd);
if (!mkDocsYmlPath) {
throw new DocutilsError(
`Could not find ${NAME_MKDOCS_YML} from ${cwd}; run "${NAME_BIN} init" to create it`,
`Could not find ${NAME_MKDOCS_YML} from ${cwd}; please run "${NAME_BIN} init"`,
);
}
const mkdocsArgs = ['-f', mkDocsYmlPath];
+5 -5
View File
@@ -73,11 +73,6 @@ export const NAME_TYPESCRIPT = 'typescript';
*/
export const NAME_ERR_ENOENT = 'ENOENT';
/**
* Code for a "file already exists" error
*/
export const NAME_ERR_EEXIST = 'EEXIST';
/**
* Name of the default theme
*/
@@ -153,3 +148,8 @@ export const DEFAULT_SITE_DIR = 'site';
* To ensure backwards compatibility, its environment variable version is used
*/
export const PIP_ENV_VARS = {PIP_BREAK_SYSTEM_PACKAGES: '1'};
/**
* Error message emitted when the path to Python was not found
*/
export const MESSAGE_PYTHON_MISSING = 'Could not find Python in PATH. Is it installed?';
+44 -7
View File
@@ -11,7 +11,15 @@ import _pkgDir from 'pkg-dir';
import readPkg, {NormalizedPackageJson, PackageJson} from 'read-pkg';
import {JsonValue} from 'type-fest';
import YAML from 'yaml';
import {NAME_MIKE, NAME_MKDOCS_YML, NAME_NPM, NAME_PACKAGE_JSON, NAME_PYTHON} from './constants';
import {
MESSAGE_PYTHON_MISSING,
NAME_MIKE,
NAME_MKDOCS,
NAME_MKDOCS_YML,
NAME_NPM,
NAME_PACKAGE_JSON,
NAME_PYTHON,
} from './constants';
import {DocutilsError} from './error';
import {getLogger} from './logger';
import {MkDocsYml} from './model';
@@ -152,18 +160,14 @@ export const readJson = _.memoize(
);
/**
* Writes a file, but will not overwrite an existing file unless `overwrite` is true
*
* Will stringify JSON objects
* Writes contents to a file. Any JSON objects are stringified
* @param filepath - Path to file
* @param content - File contents
* @param overwrite - If `true`, overwrite existing files
*/
export function safeWriteFile(filepath: string, content: JsonValue, overwrite = false) {
export function writeFileString(filepath: string, content: JsonValue) {
const data: string = _.isString(content) ? content : JSON.stringify(content, undefined, 2);
return fs.writeFile(filepath, data, {
encoding: 'utf8',
flag: overwrite ? 'w' : 'wx',
});
}
@@ -189,6 +193,28 @@ const whichPython = _.partial(cachedWhich, NAME_PYTHON, {nothrow: true});
*/
const whichPython3 = _.partial(cachedWhich, `${NAME_PYTHON}3`, {nothrow: true});
/**
* Check if `mkdocs` is installed
*/
export const isMkDocsInstalled = _.memoize(async (): Promise<boolean> => {
// see if it's in PATH
const mkDocsPath = await cachedWhich(NAME_MKDOCS, {nothrow: true});
if (mkDocsPath) {
return true;
}
// if it isn't, it should be invokable via `python -m`
const pythonPath = await findPython();
if (!pythonPath) {
return false;
}
try {
await exec(pythonPath, ['-m', NAME_MKDOCS]);
return true;
} catch {
return false;
}
});
/**
* `mike` cannot be invoked via `python -m`, so we need to find the script.
*/
@@ -225,6 +251,17 @@ export const findPython = _.memoize(
async (): Promise<string | null> => (await whichPython3()) ?? (await whichPython()),
);
/**
* Check if a path to Python exists, otherwise raise DocutilsError
*/
export async function requirePython(pythonPath?: string): Promise<string> {
const foundPythonPath = pythonPath ?? (await findPython());
if (!foundPythonPath) {
throw new DocutilsError(MESSAGE_PYTHON_MISSING);
}
return foundPythonPath;
}
/**
* Reads an `mkdocs.yml` file, merges inherited configs, and returns the result. The result is cached.
*
+7 -7
View File
@@ -5,7 +5,7 @@
*/
import * as JSON5 from 'json5';
import {NAME_MKDOCS_YML, NAME_TSCONFIG_JSON, NAME_PYTHON, PIP_ENV_VARS, REQUIREMENTS_TXT_PATH} from './constants';
import {NAME_MKDOCS_YML, NAME_TSCONFIG_JSON, PIP_ENV_VARS, REQUIREMENTS_TXT_PATH} from './constants';
import YAML from 'yaml';
import {exec} from 'teen_process';
import {Simplify} from 'type-fest';
@@ -15,7 +15,7 @@ import type { ScaffoldTask } from './scaffold';
import {getLogger} from './logger';
import {MkDocsYml, TsConfigJson} from './model';
import _ from 'lodash';
import {findPython, stringifyJson5, stringifyYaml} from './fs';
import {requirePython, stringifyJson5, stringifyYaml} from './fs';
/**
* Data for the base `mkdocs.yml` file
@@ -139,7 +139,7 @@ export async function initPython({
dryRun = false,
upgrade = false,
}: InitPythonOptions = {}): Promise<void> {
pythonPath = pythonPath ?? (await findPython()) ?? NAME_PYTHON;
const foundPythonPath = await requirePython(pythonPath);
const args = ['-m', 'pip', 'install', '-r', REQUIREMENTS_TXT_PATH];
if (upgrade) {
@@ -148,19 +148,19 @@ export async function initPython({
if (dryRun) {
dryRunLog.info(
'Would execute command: %s %s (environment variables: %s)',
pythonPath,
foundPythonPath,
args.join(' '),
PIP_ENV_VARS,
);
} else {
log.debug('Executing command: %s %s (environment variables: %s)',
pythonPath,
foundPythonPath,
args.join(' '),
PIP_ENV_VARS,
);
log.info('Installing Python dependencies...');
try {
const result = await exec(pythonPath, args, {env: PIP_ENV_VARS, shell: true});
const result = await exec(foundPythonPath, args, {env: PIP_ENV_VARS, shell: true});
const {code, stdout} = result;
if (code !== 0) {
throw new DocutilsError(`Could not install Python dependencies. Reason: ${stdout}`);
@@ -171,7 +171,7 @@ export async function initPython({
);
}
}
log.success('Installed Python dependencies (or dependencies already installed)');
log.success('Successfully installed Python dependencies');
}
/**
+19 -20
View File
@@ -12,8 +12,8 @@ import {JsonValue, JsonObject} from 'type-fest';
import {DocutilsError} from './error';
import {relative} from './util';
import _ from 'lodash';
import {stringifyJson, readPackageJson, safeWriteFile} from './fs';
import {NAME_ERR_ENOENT, NAME_ERR_EEXIST} from './constants';
import {stringifyJson, readPackageJson, writeFileString} from './fs';
import {NAME_ERR_ENOENT} from './constants';
const log = getLogger('init');
const dryRunLog = getLogger('dry-run', log);
@@ -91,7 +91,7 @@ export function createScaffoldTask<Opts extends ScaffoldTaskOptions, T extends J
dest = dest ?? path.join(pkgDir, defaultFilename);
const relativeDest = relativePath(dest);
log.debug('Initializing %s', relativeDest);
let shouldWriteDest = false;
let destChangesNeeded = false;
let isNew = false;
let destContent: T;
let result: ScaffoldTaskResult<T>;
@@ -103,7 +103,7 @@ export function createScaffoldTask<Opts extends ScaffoldTaskOptions, T extends J
if (err.code !== NAME_ERR_ENOENT) {
throw err;
}
shouldWriteDest = true;
destChangesNeeded = true;
log.debug('Creating new file %s', relativeDest);
destContent = {} as T;
isNew = true;
@@ -112,9 +112,9 @@ export function createScaffoldTask<Opts extends ScaffoldTaskOptions, T extends J
const defaults: T = transform(defaultContent, opts, pkg);
const finalDestContent: T = _.defaultsDeep({}, destContent, defaults);
shouldWriteDest = shouldWriteDest || !_.isEqual(destContent, finalDestContent);
destChangesNeeded = destChangesNeeded || !_.isEqual(destContent, finalDestContent);
if (shouldWriteDest) {
if (destChangesNeeded) {
log.info('Changes needed in %s', relativeDest);
log.debug('Original %s: %O', relativeDest, destContent);
log.debug('Final %s: %O', relativeDest, finalDestContent);
@@ -126,20 +126,19 @@ export function createScaffoldTask<Opts extends ScaffoldTaskOptions, T extends J
return result;
}
try {
await safeWriteFile(dest, finalDestContent, overwrite);
if (isNew) {
log.success('Initialized %s', description);
} else {
log.success('Updated %s', description);
}
} catch (e) {
const err = e as NodeJS.ErrnoException;
// this should only be thrown if `force` is false
if (err.code === NAME_ERR_EEXIST) {
log.info(`${relativeDest} already exists; continuing...`);
log.debug(`Tried to apply patch:\n\n${patch}`);
} else {
if (!isNew && !overwrite) {
log.info('File %s already exists, continuing (enable overwrite with "--force")', relativeDest);
log.debug('Tried to apply patch:\n\n%s', patch);
} else {
try {
await writeFileString(dest, finalDestContent);
if (isNew) {
log.success('Initialized %s', description);
} else {
log.success('Updated %s', description);
}
} catch (e) {
const err = e as NodeJS.ErrnoException;
throw new DocutilsError(`Could not write to ${relativeDest}. Reason: ${err.message}`, {
cause: err,
});
+84 -65
View File
@@ -4,7 +4,7 @@
* @module
*/
import {fs, util} from '@appium/support';
import {fs, npm, util} from '@appium/support';
import chalk from 'chalk';
import _ from 'lodash';
import {EventEmitter} from 'node:events';
@@ -13,6 +13,7 @@ import {satisfies} from 'semver';
import {exec} from 'teen_process';
import {
DOCUTILS_PKG,
MESSAGE_PYTHON_MISSING,
NAME_BIN,
NAME_ERR_ENOENT,
NAME_MKDOCS,
@@ -27,7 +28,15 @@ import {
REQUIREMENTS_TXT_PATH,
} from './constants';
import {DocutilsError} from './error';
import {findMkDocsYml, findPkgDir, readJson5, readMkDocsYml, whichNpm, findPython} from './fs';
import {
findMkDocsYml,
findPkgDir,
isMkDocsInstalled,
readJson5,
readMkDocsYml,
whichNpm,
findPython,
} from './fs';
import {getLogger} from './logger';
import {MkDocsYml, PipPackage} from './model';
import {relative} from './util';
@@ -281,12 +290,16 @@ export class DocutilsValidator extends EventEmitter {
* Validates that the correct version of `mkdocs` is installed
*/
protected async validateMkDocs() {
const pythonPath = this.pythonPath ?? (await findPython());
log.debug(`Validating MkDocs version`);
const pythonPath = this.pythonPath ?? (await findPython());
if (!pythonPath) {
return this.fail(
`Could not find ${NAME_PYTHON} executable in PATH. If it is installed, check your PATH environment variable.`,
);
return this.fail(MESSAGE_PYTHON_MISSING);
}
const mkdocsInstalled = await isMkDocsInstalled();
if (!mkdocsInstalled) {
return this.fail(`Could not find MkDocs executable; please run "${NAME_BIN} init"`);
}
let rawMkDocsVersion: string | undefined;
@@ -296,26 +309,21 @@ export class DocutilsValidator extends EventEmitter {
return this.fail(`Failed to get MkDocs version: ${err}`);
}
const match = rawMkDocsVersion.match(MKDOCS_VERSION_REGEX);
if (match) {
const version = match[1];
const reqs = await this.parseRequirementsTxt();
const mkDocsPipPkg = _.find(reqs, {name: NAME_MKDOCS});
if (!mkDocsPipPkg) {
throw new DocutilsError(
`No ${NAME_MKDOCS} package in ${REQUIREMENTS_TXT_PATH}. This is a bug.`,
);
}
const {version: mkDocsReqdVersion} = mkDocsPipPkg;
if (version !== mkDocsReqdVersion) {
return this.fail(
`${NAME_MKDOCS} is v${version}, but ${REQUIREMENTS_TXT_PATH} requires v${mkDocsReqdVersion}`,
);
}
} else {
if (!match) {
return this.fail(`Could not parse MkDocs version. Output was ${rawMkDocsVersion}`);
}
const version = match[1];
const reqs = await this.parseRequirementsTxt();
const mkDocsPipPkg = _.find(reqs, {name: NAME_MKDOCS});
if (!mkDocsPipPkg) {
throw new DocutilsError(
`Could not parse version from MkDocs. This is a bug. Output was ${rawMkDocsVersion}`,
`No ${NAME_MKDOCS} package in ${REQUIREMENTS_TXT_PATH}. This is a bug`,
);
}
const {version: mkDocsReqdVersion} = mkDocsPipPkg;
if (version !== mkDocsReqdVersion) {
return this.fail(`MkDocs v${version} is installed, but v${mkDocsReqdVersion} is required`);
}
this.ok('MkDocs install OK');
}
@@ -325,13 +333,16 @@ export class DocutilsValidator extends EventEmitter {
*
* It checks if the file exists, if it can be parsed as YAML, and if it has a `site_name` property.
*/
protected async validateMkDocsConfig(mkDocsYmlPath?: string) {
mkDocsYmlPath = mkDocsYmlPath ?? this.mkDocsYmlPath ?? (await findMkDocsYml(this.cwd));
protected async validateMkDocsConfig() {
log.debug(`Validating ${NAME_MKDOCS_YML}`);
const mkDocsYmlPath = this.mkDocsYmlPath ?? (await findMkDocsYml(this.cwd));
if (!mkDocsYmlPath) {
return this.fail(
`Could not find ${NAME_MKDOCS_YML} from ${this.cwd}. Run "${NAME_BIN} init" to create it`,
`Could not find ${NAME_MKDOCS_YML} from ${this.cwd}; please run "${NAME_BIN} init"`,
);
}
let mkDocsYml: MkDocsYml;
try {
mkDocsYml = await readMkDocsYml(mkDocsYmlPath);
@@ -358,24 +369,25 @@ export class DocutilsValidator extends EventEmitter {
* This is required because other validators need `npm exec` to work, which is only available in npm 7+.
*/
protected async validateNpmVersion() {
log.debug(`Validating ${NAME_NPM} version`);
const npmEngineRange = DOCUTILS_PKG.engines?.npm;
if (!npmEngineRange) {
throw new DocutilsError('Could not find property engines.npm in package.json. This is a bug');
throw new DocutilsError(`Could not find property 'engines.npm' in ${NAME_PACKAGE_JSON}. This is a bug`);
}
const npmPath = this.npmPath ?? (await whichNpm());
if (!npmPath) {
throw new DocutilsError(`Could not find ${NAME_NPM} in PATH. That seems weird, doesn't it?`);
}
try {
const npmPath = this.npmPath ?? (await whichNpm());
if (!npmPath) {
throw new DocutilsError(
`Could not find ${NAME_NPM} in PATH. That seems weird, doesn't it?`,
);
}
const {stdout: npmVersion} = await exec(npmPath, ['-v']);
const {stdout: npmVersion} = await npm.exec('-v', [], {cwd: this.cwd});
if (!satisfies(npmVersion.trim(), npmEngineRange)) {
this.fail(`${NAME_NPM} is version ${npmVersion}, but ${npmEngineRange} is required`);
return;
return this.fail(`${NAME_NPM} v${npmVersion} is installed, but ${npmEngineRange} is required`);
}
} catch {
return this.fail(`Could not find ${this.npmPath} in PATH. Is it installed?`);
return this.fail(`Could not retrieve ${NAME_NPM} version`);
}
this.ok(`${NAME_NPM} version OK`);
}
@@ -387,11 +399,14 @@ export class DocutilsValidator extends EventEmitter {
* contents of our `requirements.txt`. Versions _must_ match exactly.
*/
protected async validatePythonDeps() {
let pipListOutput: string;
log.debug(`Validating required ${NAME_PYTHON} package versions`);
const pythonPath = this.pythonPath ?? (await findPython());
if (!pythonPath) {
return this.fail(`Could not find ${NAME_PYTHON} in PATH. Is it installed?`);
return this.fail(MESSAGE_PYTHON_MISSING);
}
let pipListOutput: string;
try {
({stdout: pipListOutput} = await exec(pythonPath, [
'-m',
@@ -401,16 +416,16 @@ export class DocutilsValidator extends EventEmitter {
'json',
]));
} catch {
return this.fail(`Could not find ${NAME_PIP} in PATH. Is it installed?`);
return this.fail(
`Could not find ${NAME_PIP} installation for Python at ${pythonPath}. Is it installed?`
);
}
let installedPkgs: PipPackage[];
try {
installedPkgs = JSON.parse(pipListOutput) as PipPackage[];
} catch {
throw new DocutilsError(
`Could not parse output of "${NAME_PIP} list" as JSON: ${pipListOutput}`,
);
return this.fail(`Could not parse output of "${NAME_PIP} list" as JSON: ${pipListOutput}`);
}
const pkgsByName = _.mapValues(_.keyBy(installedPkgs, 'name'), 'version');
@@ -423,8 +438,7 @@ export class DocutilsValidator extends EventEmitter {
const version = pkgsByName[reqdPkg.name];
if (!version) {
missingPackages.push(reqdPkg);
}
if (version !== reqdPkg.version) {
} else if (version !== reqdPkg.version) {
invalidVersionPackages.push([reqdPkg, {name: reqdPkg.name, version}]);
}
}
@@ -464,36 +478,44 @@ export class DocutilsValidator extends EventEmitter {
* Asserts that the Python version is 3.x
*/
protected async validatePythonVersion() {
log.debug(`Validating ${NAME_PYTHON} version`);
const pythonPath = this.pythonPath ?? (await findPython());
if (!pythonPath) {
return this.fail(`Could not find ${NAME_PYTHON} in PATH. Is it installed?`);
return this.fail(MESSAGE_PYTHON_MISSING);
}
try {
const {stdout} = await exec(pythonPath, ['--version']);
if (!stdout.includes(PYTHON_VER_STR)) {
return this.fail(
`Could not find Python 3.x in PATH; found ${stdout}. Please use --python-path`,
);
return this.fail(`Could not find Python 3.x in PATH; found ${stdout}`);
}
} catch {
return this.fail(`Could not find Python 3.x in PATH.`);
return this.fail(`Could not retrieve Python version`);
}
this.ok('Python version OK');
}
/**
* Asserts that TypeScript is installed, runnable, the correct version, and a parseable `tsconfig.json` exists.
* Asserts that TypeScript is installed, runnable, and the correct version.
*/
protected async validateTypeScript() {
log.debug(`Validating ${NAME_TYPESCRIPT} version`);
const pkgDir = await this.findPkgDir();
if (!pkgDir) {
return this.fail(`Could not find package.json in ${this.cwd}`);
return this.fail(`Could not find ${NAME_PACKAGE_JSON} in ${this.cwd}`);
}
const npmPath = this.npmPath ?? (await whichNpm());
if (!npmPath) {
throw new DocutilsError(`Could not find ${NAME_NPM} in PATH. That seems weird, doesn't it?`);
}
let typeScriptVersion: string;
let rawTypeScriptVersion: string;
try {
({stdout: rawTypeScriptVersion} = await exec(NAME_NPM, ['exec', 'tsc', '--', '--version'], {
({stdout: rawTypeScriptVersion} = await npm.exec('exec', ['tsc', '--', '--version'], {
cwd: pkgDir,
}));
} catch {
@@ -510,16 +532,15 @@ export class DocutilsValidator extends EventEmitter {
}
const reqdTypeScriptVersion = DOCUTILS_PKG.dependencies?.typescript;
if (!reqdTypeScriptVersion) {
throw new DocutilsError(
`Could not find a dep for ${NAME_TYPESCRIPT} in ${NAME_PACKAGE_JSON}. This is a bug.`,
`Could not find ${NAME_TYPESCRIPT} dependency in ${NAME_PACKAGE_JSON}. This is a bug`,
);
}
if (!satisfies(typeScriptVersion, reqdTypeScriptVersion)) {
return this.fail(
`Found TypeScript version ${typeScriptVersion}, but ${reqdTypeScriptVersion} is required`,
`TypeScript v${typeScriptVersion} is installed, but v${reqdTypeScriptVersion} is required`,
);
}
this.ok('TypeScript install OK');
@@ -529,25 +550,23 @@ export class DocutilsValidator extends EventEmitter {
* Validates a `tsconfig.json` file
*/
protected async validateTypeScriptConfig() {
log.debug(`Validating ${NAME_TSCONFIG_JSON}`);
const pkgDir = await this.findPkgDir();
if (!pkgDir) {
return this.fail(new DocutilsError(`Could not find package.json in ${this.cwd}`));
return this.fail(`Could not find ${NAME_PACKAGE_JSON} in ${this.cwd}`);
}
const tsconfigJsonPath = (this.tsconfigJsonPath =
this.tsconfigJsonPath ?? path.join(pkgDir, NAME_TSCONFIG_JSON));
const tsconfigJsonPath = this.tsconfigJsonPath ?? path.join(pkgDir, NAME_TSCONFIG_JSON);
const relTsconfigJsonPath = relative(this.cwd, tsconfigJsonPath);
try {
await readJson5(tsconfigJsonPath);
} catch (e) {
if (e instanceof SyntaxError) {
return this.fail(
new DocutilsError(`Unparseable ${NAME_TSCONFIG_JSON} at ${relTsconfigJsonPath}: ${e}`),
);
return this.fail(`Could not parse ${NAME_TSCONFIG_JSON} at ${relTsconfigJsonPath}: ${e}`);
}
return this.fail(
new DocutilsError(
`Missing ${NAME_TSCONFIG_JSON} at ${relTsconfigJsonPath}; "${NAME_BIN} init" can help`,
),
`Could not find ${NAME_TSCONFIG_JSON} at ${relTsconfigJsonPath}; please run "${NAME_BIN} init"`,
);
}
+5 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/docutils",
"version": "1.0.34",
"version": "1.1.0",
"description": "Documentation generation utilities for Appium and related projects",
"keywords": [
"automation",
@@ -48,7 +48,7 @@
"start": "node ./build/lib/cli/index.js"
},
"dependencies": {
"@appium/support": "^6.0.8",
"@appium/support": "^6.1.0",
"@appium/tsconfig": "^0.3.5",
"@sliphua/lilconfig-ts-loader": "3.2.2",
"chalk": "4.1.2",
@@ -62,9 +62,9 @@
"semver": "7.7.1",
"source-map-support": "0.5.21",
"teen_process": "2.3.1",
"type-fest": "4.38.0",
"typescript": "5.8.2",
"yaml": "2.7.0",
"type-fest": "4.40.0",
"typescript": "5.8.3",
"yaml": "2.7.1",
"yargs": "17.7.2",
"yargs-parser": "21.1.1"
},
+1 -1
View File
@@ -1,5 +1,5 @@
mkdocs==1.6.1
mkdocs-git-revision-date-localized-plugin==1.4.5
mkdocs-material==9.6.9
mkdocs-material==9.6.12
mkdocs-redirects==1.2.2
mike==2.1.3
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.7.9](https://github.com/appium/appium/compare/@appium/driver-test-support@0.7.8...@appium/driver-test-support@0.7.9) (2025-04-25)
**Note:** Version bump only for package @appium/driver-test-support
## [0.7.8](https://github.com/appium/appium/compare/@appium/driver-test-support@0.7.7...@appium/driver-test-support@0.7.8) (2025-03-17)
**Note:** Version bump only for package @appium/driver-test-support
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/driver-test-support",
"version": "0.7.8",
"version": "0.7.9",
"description": "Test utilities for Appium drivers",
"keywords": [
"automation",
@@ -41,8 +41,8 @@
},
"types": "./build/lib/index.d.ts",
"dependencies": {
"@appium/types": "^0.25.2",
"axios": "1.8.4",
"@appium/types": "^0.25.3",
"axios": "1.9.0",
"bluebird": "3.7.2",
"chai": "5.2.0",
"chai-as-promised": "8.0.1",
@@ -50,7 +50,7 @@
"lodash": "4.17.21",
"sinon": "20.0.0",
"source-map-support": "0.5.21",
"type-fest": "4.38.0"
"type-fest": "4.40.0"
},
"peerDependencies": {
"appium": "^2.0.0-beta.43 || ^3.0.0-beta.0",
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.0.4](https://github.com/appium/appium/compare/@appium/eslint-config-appium-ts@1.0.3...@appium/eslint-config-appium-ts@1.0.4) (2025-04-25)
**Note:** Version bump only for package @appium/eslint-config-appium-ts
## [1.0.3](https://github.com/appium/appium/compare/@appium/eslint-config-appium-ts@1.0.2...@appium/eslint-config-appium-ts@1.0.3) (2025-02-19)
**Note:** Version bump only for package @appium/eslint-config-appium-ts
@@ -1,7 +1,7 @@
{
"name": "@appium/eslint-config-appium-ts",
"type": "module",
"version": "1.0.3",
"version": "1.0.4",
"description": "Shared ESLint config for Appium projects (TypeScript version)",
"keywords": [
"eslint",
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [4.0.5](https://github.com/appium/appium/compare/@appium/execute-driver-plugin@4.0.4...@appium/execute-driver-plugin@4.0.5) (2025-04-25)
**Note:** Version bump only for package @appium/execute-driver-plugin
## [4.0.4](https://github.com/appium/appium/compare/@appium/execute-driver-plugin@4.0.3...@appium/execute-driver-plugin@4.0.4) (2025-03-17)
**Note:** Version bump only for package @appium/execute-driver-plugin
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/execute-driver-plugin",
"version": "4.0.4",
"version": "4.0.5",
"description": "Plugin for batching and executing driver commands with Appiums",
"keywords": [
"automation",
@@ -41,7 +41,7 @@
"bluebird": "3.7.2",
"lodash": "4.17.21",
"source-map-support": "0.5.21",
"webdriverio": "9.12.2"
"webdriverio": "9.12.7"
},
"peerDependencies": {
"appium": "^2.0.0-beta.35 || ^3.0.0-beta.0"
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.2.6](https://github.com/appium/appium/compare/@appium/fake-plugin@3.2.5...@appium/fake-plugin@3.2.6) (2025-04-25)
**Note:** Version bump only for package @appium/fake-plugin
## [3.2.5](https://github.com/appium/appium/compare/@appium/fake-plugin@3.2.4...@appium/fake-plugin@3.2.5) (2025-03-17)
**Note:** Version bump only for package @appium/fake-plugin
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/fake-plugin",
"version": "3.2.5",
"version": "3.2.6",
"description": "A fake Appium 2.0 plugin",
"keywords": [
"automation",
@@ -40,7 +40,7 @@
},
"dependencies": {
"@appium/base-plugin": "^3.0.0-beta.0",
"@appium/support": "^6.0.8",
"@appium/support": "^6.1.0",
"bluebird": "3.7.2",
"lodash": "4.17.21",
"source-map-support": "0.5.21"
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.1.2](https://github.com/appium/appium/compare/@appium/images-plugin@3.1.1...@appium/images-plugin@3.1.2) (2025-04-25)
**Note:** Version bump only for package @appium/images-plugin
## [3.1.1](https://github.com/appium/appium/compare/@appium/images-plugin@3.1.0...@appium/images-plugin@3.1.1) (2025-03-17)
**Note:** Version bump only for package @appium/images-plugin
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/images-plugin",
"version": "3.1.1",
"version": "3.1.2",
"description": "Plugin for working with images and image elements in Appium",
"keywords": [
"automation",
@@ -39,11 +39,11 @@
"test:unit": "mocha \"./test/unit/**/*.spec.*js\""
},
"dependencies": {
"@appium/opencv": "^3.0.8",
"@appium/support": "^6.0.8",
"@appium/opencv": "^3.0.9",
"@appium/support": "^6.1.0",
"lodash": "4.17.21",
"lru-cache": "10.4.3",
"sharp": "0.33.5",
"sharp": "0.34.1",
"source-map-support": "0.5.21"
},
"peerDependencies": {
+15
View File
@@ -3,6 +3,21 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.7.0](https://github.com/appium/appium/compare/@appium/logger@1.6.1...@appium/logger@1.7.0) (2025-04-25)
### Features
* Add a possibility to mask sensitive log values depending on request headers ([#21123](https://github.com/appium/appium/issues/21123)) ([c24d2ac](https://github.com/appium/appium/commit/c24d2ac46123f41ee9b54e0adefacfabd149089c))
### Bug Fixes
* **appium:** Return hostname as web socket url for BiDi if a broadcast address is assigned to the server ([#20603](https://github.com/appium/appium/issues/20603)) ([f0de55d](https://github.com/appium/appium/commit/f0de55da0da2fc0305876a948704c1f0a2a5990f))
* **logger:** Error stack logging ([#21176](https://github.com/appium/appium/issues/21176)) ([1de5d0a](https://github.com/appium/appium/commit/1de5d0a0e8994b170a44eebe2d0575d5c74c3ff2))
## [1.6.1](https://github.com/appium/appium/compare/@appium/logger@1.6.0...@appium/logger@1.6.1) (2024-08-07)
+5 -2
View File
@@ -237,8 +237,11 @@ export class Log extends EventEmitter implements Logger {
let stack: string | undefined;
for (const arg of [message, ...args]) {
const result = this._formatLogArgument(arg);
stack = result.stack;
messageArguments.push(result.arg);
if (result.stack) {
stack = result.stack;
} else {
messageArguments.push(result.arg);
}
}
if (stack) {
messageArguments.unshift(`${stack}\n`);
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/logger",
"version": "1.6.1",
"version": "1.7.0",
"author": "https://github.com/appium",
"description": "A Universal Logger For The Appium Ecosystem",
"repository": {
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.0.9](https://github.com/appium/appium/compare/@appium/opencv@3.0.8...@appium/opencv@3.0.9) (2025-04-25)
**Note:** Version bump only for package @appium/opencv
## [3.0.8](https://github.com/appium/appium/compare/@appium/opencv@3.0.7...@appium/opencv@3.0.8) (2025-02-19)
**Note:** Version bump only for package @appium/opencv
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/opencv",
"version": "3.0.8",
"version": "3.0.9",
"description": "OpenCV-related helper library",
"keywords": [
"automation",
@@ -44,7 +44,7 @@
"bluebird": "3.7.2",
"lodash": "4.17.21",
"opencv-bindings": "4.5.5",
"sharp": "0.33.5",
"sharp": "0.34.1",
"source-map-support": "0.5.21"
},
"engines": {
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.3.53](https://github.com/appium/appium/compare/@appium/plugin-test-support@0.3.52...@appium/plugin-test-support@0.3.53) (2025-04-25)
**Note:** Version bump only for package @appium/plugin-test-support
## [0.3.52](https://github.com/appium/appium/compare/@appium/plugin-test-support@0.3.51...@appium/plugin-test-support@0.3.52) (2025-03-11)
**Note:** Version bump only for package @appium/plugin-test-support
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/plugin-test-support",
"version": "0.3.52",
"version": "0.3.53",
"description": "Testing utilities for Appium plugins",
"keywords": [
"automation",
@@ -41,7 +41,7 @@
"test:unit": "exit 0"
},
"dependencies": {
"@appium/types": "^0.25.2",
"@appium/types": "^0.25.3",
"get-port": "5.1.1",
"log-symbols": "4.1.0",
"source-map-support": "0.5.21",
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.1.2](https://github.com/appium/appium/compare/@appium/storage-plugin@0.1.1...@appium/storage-plugin@0.1.2) (2025-04-25)
**Note:** Version bump only for package @appium/storage-plugin
## [0.1.1](https://github.com/appium/appium/compare/@appium/storage-plugin@0.1.0...@appium/storage-plugin@0.1.1) (2025-03-17)
**Note:** Version bump only for package @appium/storage-plugin
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/storage-plugin",
"version": "0.1.1",
"version": "0.1.2",
"description": "Server-side storage plugin",
"keywords": [
"automation",
@@ -41,7 +41,7 @@
"test:e2e": "mocha --timeout 20s --slow 10s \"./test/e2e/**/*.spec.*js\""
},
"dependencies": {
"@appium/support": "^6.0.8",
"@appium/support": "^6.1.0",
"async-lock": "1.4.1",
"bluebird": "3.7.2",
"lodash": "4.17.21",
+9
View File
@@ -3,6 +3,15 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [6.1.0](https://github.com/appium/appium/compare/@appium/support@6.0.8...@appium/support@6.1.0) (2025-04-25)
### Features
* Add a possibility to mask sensitive log values depending on request headers ([#21123](https://github.com/appium/appium/issues/21123)) ([c24d2ac](https://github.com/appium/appium/commit/c24d2ac46123f41ee9b54e0adefacfabd149089c))
## [6.0.8](https://github.com/appium/appium/compare/@appium/support@6.0.7...@appium/support@6.0.8) (2025-03-17)
**Note:** Version bump only for package @appium/support
+6 -6
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/support",
"version": "6.0.8",
"version": "6.1.0",
"description": "Support libs used across appium packages",
"keywords": [
"automation",
@@ -41,12 +41,12 @@
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
},
"dependencies": {
"@appium/logger": "^1.6.1",
"@appium/logger": "^1.7.0",
"@appium/tsconfig": "^0.3.5",
"@appium/types": "^0.25.2",
"@appium/types": "^0.25.3",
"@colors/colors": "1.6.0",
"archiver": "7.0.1",
"axios": "1.8.4",
"axios": "1.9.0",
"base64-stream": "1.0.0",
"bluebird": "3.7.2",
"bplist-creator": "0.1.1",
@@ -73,13 +73,13 @@
"source-map-support": "0.5.21",
"supports-color": "8.1.1",
"teen_process": "2.3.1",
"type-fest": "4.38.0",
"type-fest": "4.40.0",
"uuid": "11.1.0",
"which": "4.0.0",
"yauzl": "3.2.0"
},
"optionalDependencies": {
"sharp": "0.33.5"
"sharp": "0.34.1"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [3.1.9](https://github.com/appium/appium/compare/@appium/test-support@3.1.8...@appium/test-support@3.1.9) (2025-04-25)
**Note:** Version bump only for package @appium/test-support
## [3.1.8](https://github.com/appium/appium/compare/@appium/test-support@3.1.7...@appium/test-support@3.1.8) (2025-03-17)
**Note:** Version bump only for package @appium/test-support
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/test-support",
"version": "3.1.8",
"version": "3.1.9",
"description": "A collection of test utilities used across Appium packages",
"keywords": [
"automation",
@@ -45,7 +45,7 @@
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
},
"dependencies": {
"@appium/support": "^6.0.8",
"@appium/support": "^6.1.0",
"@colors/colors": "1.6.0",
"bluebird": "3.7.2",
"lodash": "4.17.21",
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.25.3](https://github.com/appium/appium/compare/@appium/types@0.25.2...@appium/types@0.25.3) (2025-04-25)
**Note:** Version bump only for package @appium/types
## [0.25.2](https://github.com/appium/appium/compare/@appium/types@0.25.1...@appium/types@0.25.2) (2025-03-11)
**Note:** Version bump only for package @appium/types
+3 -3
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/types",
"version": "0.25.2",
"version": "0.25.3",
"description": "Various type declarations used across Appium",
"keywords": [
"automation",
@@ -38,10 +38,10 @@
"test:types": "tsd"
},
"dependencies": {
"@appium/logger": "^1.6.1",
"@appium/logger": "^1.7.0",
"@appium/schema": "^0.8.1",
"@appium/tsconfig": "^0.3.5",
"type-fest": "4.38.0"
"type-fest": "4.40.0"
},
"engines": {
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.0.33](https://github.com/appium/appium/compare/@appium/universal-xml-plugin@1.0.32...@appium/universal-xml-plugin@1.0.33) (2025-04-25)
**Note:** Version bump only for package @appium/universal-xml-plugin
## [1.0.32](https://github.com/appium/appium/compare/@appium/universal-xml-plugin@1.0.31...@appium/universal-xml-plugin@1.0.32) (2025-03-17)
**Note:** Version bump only for package @appium/universal-xml-plugin
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@appium/universal-xml-plugin",
"version": "1.0.32",
"version": "1.0.33",
"description": "Appium plugin for making XML source and XPath queries the same across iOS and Android",
"keywords": [
"automation",
@@ -38,7 +38,7 @@
},
"dependencies": {
"@xmldom/xmldom": "0.9.8",
"fast-xml-parser": "5.0.9",
"fast-xml-parser": "5.2.1",
"lodash": "4.17.21",
"source-map-support": "0.5.21",
"xpath": "0.0.34"