mirror of
https://github.com/appium/appium.git
synced 2026-11-02 07:13:52 +08:00
Compare commits
56
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
820428b769 | ||
|
|
034a51b686 | ||
|
|
f2cff24685 | ||
|
|
53bfc68eee | ||
|
|
dce45bdf83 | ||
|
|
e73e47de18 | ||
|
|
a080b72920 | ||
|
|
c8e9059711 | ||
|
|
d5f3a288c2 | ||
|
|
998e2586a7 | ||
|
|
78a22b2a1c | ||
|
|
a5876c8f26 | ||
|
|
4ef0c49b24 | ||
|
|
c18b43f2bd | ||
|
|
2f69e6db2a | ||
|
|
ed8e83c76c | ||
|
|
d6204b6902 | ||
|
|
f0a01aea48 | ||
|
|
b64092dc8c | ||
|
|
6082cb1164 | ||
|
|
b88ac49577 | ||
|
|
c933732089 | ||
|
|
b71340a4ba | ||
|
|
5a2611137b | ||
|
|
aaf58c3de6 | ||
|
|
fb34ab9172 | ||
|
|
a21ae6ab2b | ||
|
|
1358937db2 | ||
|
|
f9ba31383a | ||
|
|
b85a92a912 | ||
|
|
544aeec149 | ||
|
|
97c5d9268a | ||
|
|
3e1eda0193 | ||
|
|
a9e86aabc6 | ||
|
|
a888e26331 | ||
|
|
12147d518f | ||
|
|
03ddcdfcaf | ||
|
|
fc01fb958a | ||
|
|
9a5c9ae55c | ||
|
|
2e187804b2 | ||
|
|
6c4189b400 | ||
|
|
95a34185d1 | ||
|
|
a8cc551210 | ||
|
|
9ad0dfc3c8 | ||
|
|
5f39ae1857 | ||
|
|
aaf31a577c | ||
|
|
97d8f0df44 | ||
|
|
de5b55ae90 | ||
|
|
5d32946a44 | ||
|
|
93b6a470cd | ||
|
|
ead861077a | ||
|
|
8ef51855e3 | ||
|
|
c320e8a1a6 | ||
|
|
f548a8bfed | ||
|
|
0ffafd034b | ||
|
|
39e6b234c4 |
@@ -80,7 +80,7 @@ body:
|
||||
placeholder: 'https://gist.github.com/...'
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Futher Information
|
||||
label: Further Information
|
||||
description: |
|
||||
Links? References? Anything that will give us more context about the issue you are encountering!
|
||||
|
||||
|
||||
@@ -42,21 +42,33 @@ permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
prepare_matrix:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
versions: ${{ steps.generate-matrix.outputs.versions }}
|
||||
steps:
|
||||
- name: Select 3 most recent LTS versions of Node.js
|
||||
id: generate-matrix
|
||||
run: echo "versions=$(curl -s https://endoflife.date/api/nodejs.json | jq -c '[[.[] | select(.lts != false)][:3] | .[].cycle | tonumber]')" >> "$GITHUB_OUTPUT"
|
||||
|
||||
test:
|
||||
needs:
|
||||
- prepare_matrix
|
||||
name: Tests
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [16.x, 18.x, 20.x]
|
||||
node-version: ${{ fromJSON(needs.prepare_matrix.outputs.versions) }}
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- windows-latest
|
||||
# TODO: Windows is not stable and slow to run
|
||||
# - windows-latest
|
||||
# TODO: Enable below envs after all tests have been verified green
|
||||
# - macos-latest
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@c85c95e3d7251135ab7dc9ce3241c5835cc595a9 # v3
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3
|
||||
uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: 'npm'
|
||||
|
||||
@@ -18,7 +18,7 @@ jobs:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
steps:
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3
|
||||
uses: actions/setup-node@5e21ff4d9bc1a8cf6de233a3057d20ec6b3fb69d # v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Install Appium
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node
|
||||
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs
|
||||
|
||||
name: Run publish:doc
|
||||
name: Publish docs
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -25,8 +25,14 @@ jobs:
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
- name: Install dependencies (Node.js)
|
||||
uses: bahmutov/npm-install@1a235c31658a322a3b024444759650ee6345c26d # tag=v1
|
||||
with:
|
||||
useRollingCache: true
|
||||
install-command: npm ci
|
||||
- name: Install dependencies (Python)
|
||||
run: pip install -r packages/docutils/requirements.txt
|
||||
- run: |
|
||||
- name: Publish docs
|
||||
run: |
|
||||
cd packages/appium
|
||||
npm run publish:docs
|
||||
|
||||
@@ -38,7 +38,13 @@ To install Appium 2 server using Node Package Manager (npm) run the following co
|
||||
npm i --location=global appium
|
||||
```
|
||||
|
||||
:bangbang: Make sure Appium 1 is fully unistalled before upgrading it to Appium 2 (`npm uninstall --location=global appium`). Unexpected errors might appear if this has not been done.
|
||||
To update Appium 2 server using Node Package Manager (npm) run the following command:
|
||||
|
||||
```bash
|
||||
npm install --location=global appium@latest
|
||||
```
|
||||
|
||||
:bangbang: Make sure Appium 1 is fully uninstalled before upgrading it to Appium 2 (`npm uninstall --location=global appium`). Unexpected errors might appear if this has not been done.
|
||||
|
||||
### Drivers
|
||||
|
||||
@@ -188,10 +194,6 @@ Repo](https://github.com/appium/appium/tree/master/packages/appium/docs) as well
|
||||
Please take a look at our [contribution documentation](CONTRIBUTING.md)
|
||||
for instructions on how to build, test, and run Appium from the source.
|
||||
|
||||
### Roadmap
|
||||
|
||||
Interested in where Appium is heading in the future? Check out the [Roadmap](ROADMAP.md)
|
||||
|
||||
### Project History, Credits & Inspiration
|
||||
|
||||
* [History](https://appium.io/docs/en/latest/intro/history/)
|
||||
|
||||
Generated
+2069
-1582
File diff suppressed because it is too large
Load Diff
+16
-16
@@ -84,45 +84,45 @@
|
||||
"singleQuote": true
|
||||
},
|
||||
"devDependencies": {
|
||||
"@colors/colors": "1.5.0",
|
||||
"@commitlint/cli": "17.6.6",
|
||||
"@commitlint/config-conventional": "17.6.6",
|
||||
"@colors/colors": "1.6.0",
|
||||
"@commitlint/cli": "17.7.1",
|
||||
"@commitlint/config-conventional": "17.7.0",
|
||||
"@tsconfig/node14": "1.0.3",
|
||||
"@types/chai": "4.3.5",
|
||||
"@types/chai-as-promised": "7.1.5",
|
||||
"@types/diff": "5.0.3",
|
||||
"@types/mocha": "10.0.1",
|
||||
"@types/node": "18.16.19",
|
||||
"@types/node": "18.17.6",
|
||||
"@types/semver": "7.5.0",
|
||||
"@types/sinon": "10.0.15",
|
||||
"@types/sinon": "10.0.16",
|
||||
"@types/sinon-chai": "3.2.9",
|
||||
"@types/source-map-support": "0.5.6",
|
||||
"@types/teen_process": "2.0.0",
|
||||
"@types/ws": "8.5.5",
|
||||
"@types/yargs": "17.0.24",
|
||||
"@typescript-eslint/eslint-plugin": "5.61.0",
|
||||
"@typescript-eslint/parser": "5.61.0",
|
||||
"@typescript-eslint/eslint-plugin": "5.62.0",
|
||||
"@typescript-eslint/parser": "5.62.0",
|
||||
"asyncbox": "2.9.4",
|
||||
"chai": "4.3.7",
|
||||
"chai-as-promised": "7.1.1",
|
||||
"chai-webdriverio-async": "2.7.0",
|
||||
"conventional-changelog-conventionalcommits": "5.0.0",
|
||||
"cpy-cli": "4.2.0",
|
||||
"eslint": "8.44.0",
|
||||
"eslint-config-prettier": "8.8.0",
|
||||
"conventional-changelog-conventionalcommits": "6.1.0",
|
||||
"cpy-cli": "5.0.0",
|
||||
"eslint": "8.46.0",
|
||||
"eslint-config-prettier": "8.10.0",
|
||||
"eslint-find-rules": "4.1.0",
|
||||
"eslint-import-resolver-typescript": "3.5.5",
|
||||
"eslint-plugin-import": "2.27.5",
|
||||
"eslint-plugin-import": "2.28.1",
|
||||
"eslint-plugin-mocha": "10.1.0",
|
||||
"eslint-plugin-promise": "6.1.1",
|
||||
"fancy-log": "2.0.0",
|
||||
"finalhandler": "1.2.0",
|
||||
"get-port": "5.1.1",
|
||||
"handlebars": "4.7.7",
|
||||
"handlebars": "4.7.8",
|
||||
"husky": "8.0.3",
|
||||
"json-schema-to-typescript": "13.0.2",
|
||||
"lerna": "6.6.2",
|
||||
"lint-staged": "13.2.3",
|
||||
"lint-staged": "13.3.0",
|
||||
"log-symbols": "4.1.0",
|
||||
"midnight-smoker": "2.0.4",
|
||||
"mjpeg-consumer": "2.0.0",
|
||||
@@ -134,7 +134,7 @@
|
||||
"rewiremock": "3.14.5",
|
||||
"rimraf": "5.0.1",
|
||||
"serve-static": "1.15.0",
|
||||
"sinon": "15.1.2",
|
||||
"sinon": "15.2.0",
|
||||
"sinon-chai": "3.7.0",
|
||||
"sync-monorepo-packages": "1.0.2",
|
||||
"through2": "4.0.2",
|
||||
@@ -145,7 +145,7 @@
|
||||
"typedoc-plugin-resolve-crossmodule-references": "0.3.3",
|
||||
"typescript": "5.0.4",
|
||||
"validate.js": "0.13.1",
|
||||
"webdriverio": "7.32.0",
|
||||
"webdriverio": "7.32.3",
|
||||
"ws": "8.13.0",
|
||||
"yaml-js": "0.3.1"
|
||||
},
|
||||
|
||||
@@ -3,6 +3,33 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.1.1](https://github.com/appium/appium/compare/appium@2.1.0...appium@2.1.1) (2023-08-21)
|
||||
|
||||
**Note:** Version bump only for package appium
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.0](https://github.com/appium/appium/compare/appium@2.0.1...appium@2.1.0) (2023-08-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **base-driver:** Make it possible to provide settings as a map in session capabilities ([#18970](https://github.com/appium/appium/issues/18970)) ([aaf58c3](https://github.com/appium/appium/commit/aaf58c3de66fee2eb10225d05e156e7416a4ac79))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **appium:** Fix the plural form ([97d8f0d](https://github.com/appium/appium/commit/97d8f0df44d915b346a6ecd0d052369dd80a9569))
|
||||
* **appium:** update dependency winston to v3.10.0 ([b85a92a](https://github.com/appium/appium/commit/b85a92a912b3d2854e8102b41119fc780e1a6cc2))
|
||||
* **appium:** Update the GET /status response to be in sync with the standard ([#18972](https://github.com/appium/appium/issues/18972)) ([5a26111](https://github.com/appium/appium/commit/5a2611137b2a7428bb2e593fc945e21874c4cdae))
|
||||
* **support:** update dependency glob to v10 ([#18490](https://github.com/appium/appium/issues/18490)) ([aaf31a5](https://github.com/appium/appium/commit/aaf31a577cb0b9cbe22646dcd888dc393a03aa11))
|
||||
* **support:** update dependency semver to v7.5.4 ([03ddcdf](https://github.com/appium/appium/commit/03ddcdfcafbccf6698868a272e499cbdac41d791))
|
||||
* **types:** update dependency type-fest to v3.13.1 ([fb34ab9](https://github.com/appium/appium/commit/fb34ab917216121d2b554677a12f07a03393d218))
|
||||
|
||||
|
||||
|
||||
## [2.0.1](https://github.com/appium/appium/compare/appium@2.0.0...appium@2.0.1) (2023-07-24)
|
||||
|
||||
|
||||
|
||||
@@ -38,7 +38,13 @@ To install Appium 2 server using Node Package Manager (npm) run the following co
|
||||
npm i --location=global appium
|
||||
```
|
||||
|
||||
:bangbang: Make sure Appium 1 is fully unistalled before upgrading it to Appium 2 (`npm uninstall --location=global appium`). Unexpected errors might appear if this has not been done.
|
||||
To update Appium 2 server using Node Package Manager (npm) run the following command:
|
||||
|
||||
```bash
|
||||
npm install --location=global appium@latest
|
||||
```
|
||||
|
||||
:bangbang: Make sure Appium 1 is fully uninstalled before upgrading it to Appium 2 (`npm uninstall --location=global appium`). Unexpected errors might appear if this has not been done.
|
||||
|
||||
### Drivers
|
||||
|
||||
@@ -188,10 +194,6 @@ Repo](https://github.com/appium/appium/tree/master/packages/appium/docs) as well
|
||||
Please take a look at our [contribution documentation](CONTRIBUTING.md)
|
||||
for instructions on how to build, test, and run Appium from the source.
|
||||
|
||||
### Roadmap
|
||||
|
||||
Interested in where Appium is heading in the future? Check out the [Roadmap](ROADMAP.md)
|
||||
|
||||
### Project History, Credits & Inspiration
|
||||
|
||||
* [History](https://appium.io/docs/en/latest/intro/history/)
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
title: Server Environment Variables
|
||||
---
|
||||
|
||||
The primary way of configuring the Appium server is via [CLI Args](./args.md). However, some more
|
||||
advanced features are toggled or configured via environment variables. To set environment
|
||||
variables, refer to the documentation for your operating system and terminal. These are the
|
||||
environment variables that the Appium server understands:
|
||||
|
||||
|Variable |Description|
|
||||
|--------|-----------|
|
||||
|`APPIUM_HOME`|By default, Appium creates a directory called `.appium` in the home directory for your system user. You can adjust the directory with this variable, as detailed in the [Managing Extensions](../guides/managing-exts.md) guide.|
|
||||
|`APPIUM_TMP_DIR`|By default, Appium uses a random temporary directory for many of its operations. If you wish to use a specific directory, you may do so by including an absolute path as the value of this variable. The behaviour is equivalent to using the `--tmp` CLI arg.|
|
||||
|`APPIUM_PREFER_SYSTEM_UNZIP`|Set to `0` or `false` to request that Appium not use the `unzip` binary included on your system for unzipping downloaded apps or other artifacts. Instead it will use a JS-based unzip library. This could help on some systems with non-existent or non-standard `unzip` commands. Note that if unzipping fails using the system library, the fallback library will be attempted in any case, so setting this env var merely saves time in the event you know the system unzip will fail.|
|
||||
|`APPIUM_HOST`|Same as the `--address` CLI arg|
|
||||
|`APPIUM_PORT`|Same as the `--port` CLI arg|
|
||||
|`APPIUM_RELOAD_EXTENSIONS`|Set to `1` to cause Appium to re-require extensions when new sessions are created. This is mostly useful for [building extensions](../ecosystem/build-drivers.md)|
|
||||
|`APPIUM_OMIT_PEER_DEPS`|Adds `--omit=peer` to all the NPM commands run internally by Appium. Mostly an internal feature.|
|
||||
@@ -152,6 +152,16 @@ your driver locally:
|
||||
appium driver install --source=local /path/to/your/driver/dev/dir
|
||||
```
|
||||
|
||||
### Refreshing your driver during development
|
||||
|
||||
When the Appium server starts, it loads your driver into memory. Changes to your driver code will
|
||||
not take effect until the next time the Appium server starts. Simply starting a new session is not
|
||||
sufficient to cause your driver's code to be reloaded.
|
||||
|
||||
However, you can set the `APPIUM_RELOAD_EXTENSIONS` environment variable to `1` to request that
|
||||
Appium clear its module cache and reload extensions whenever a new session is requested. This may
|
||||
obviate the need to restart the server when you make code changes to your driver.
|
||||
|
||||
## Standard driver implementation ideas
|
||||
|
||||
These are things you will probably find yourself wanting to do when creating a driver.
|
||||
|
||||
@@ -141,7 +141,9 @@ Appium's start server methods to handle starting and stopping the Appium server
|
||||
Of course, you can always install it locally as described above as well.
|
||||
|
||||
Anytime you make changes to your plugin code, you'll need to restart the Appium server to make sure
|
||||
it picks up the latest code.
|
||||
it picks up the latest code. As with drivers, you can set the `APPIUM_RELOAD_EXTENSIONS`
|
||||
environment variable if you wish Appium to try to re-require your plugin module when a new session
|
||||
starts.
|
||||
|
||||
## Standard plugin implementation ideas
|
||||
|
||||
|
||||
@@ -41,6 +41,18 @@ would construct a set of capabilities that includes the following in its JSON re
|
||||
}
|
||||
```
|
||||
|
||||
Also, since base-driver version 9.4.0, there is a possibility to provide multiple settings
|
||||
in a single `appium:settings` capability value:
|
||||
|
||||
```json
|
||||
{
|
||||
"appium:settings": {
|
||||
"ignoreUnimportantViews": true,
|
||||
"allowInvisibleElements": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Of course, initializing a setting via capabilities doesn't prevent you from changing it later on
|
||||
via the Settings API. To learn more about how to use the Settings API in the context of your
|
||||
specific client library, visit the documentation for that library.
|
||||
|
||||
@@ -28,6 +28,7 @@ nav:
|
||||
- CLI Reference:
|
||||
- cli/index.md
|
||||
- cli/args.md
|
||||
- cli/env-vars.md
|
||||
- cli/extensions.md
|
||||
- Guides:
|
||||
- guides/migrating-1-to-2.md
|
||||
|
||||
@@ -114,6 +114,7 @@ class AppiumDriver extends DriverCore {
|
||||
this.sessionPlugins = {};
|
||||
this.sessionlessPlugins = [];
|
||||
this.desiredCapConstraints = desiredCapabilityConstraints;
|
||||
this._isShuttingDown = false;
|
||||
|
||||
// allow this to happen in the background, so no `await`
|
||||
(async () => {
|
||||
@@ -155,11 +156,32 @@ class AppiumDriver extends DriverCore {
|
||||
|
||||
// eslint-disable-next-line require-await
|
||||
async getStatus() {
|
||||
// https://www.w3.org/TR/webdriver/#dfn-status
|
||||
const statusObj = this._isShuttingDown
|
||||
? {
|
||||
ready: false,
|
||||
message: 'The server is shutting down',
|
||||
} : {
|
||||
ready: true,
|
||||
message: 'The server is ready to accept new connections',
|
||||
};
|
||||
return {
|
||||
...statusObj,
|
||||
build: _.clone(getBuildInfo()),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string|null} reason An optional shutdown reason
|
||||
*/
|
||||
async shutdown(reason = null) {
|
||||
this._isShuttingDown = true;
|
||||
await this.deleteAllSessions({
|
||||
force: true,
|
||||
reason,
|
||||
});
|
||||
}
|
||||
|
||||
async getSessions() {
|
||||
return _.toPairs(this.sessions).map(([id, driver]) => ({
|
||||
id,
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
*/
|
||||
|
||||
import B from 'bluebird';
|
||||
import glob from 'glob';
|
||||
import {env, fs} from '@appium/support';
|
||||
import _ from 'lodash';
|
||||
import path from 'path';
|
||||
@@ -212,23 +211,13 @@ export class Manifest {
|
||||
];
|
||||
|
||||
// add dependencies to the queue
|
||||
await new B((resolve, reject) => {
|
||||
glob(
|
||||
'node_modules/{*,@*/*}/package.json',
|
||||
{cwd: this.#appiumHome, silent: true, absolute: true},
|
||||
// eslint-disable-next-line promise/prefer-await-to-callbacks
|
||||
(err) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
resolve();
|
||||
}
|
||||
)
|
||||
.on('error', reject)
|
||||
.on('match', (filepath) => {
|
||||
queue.push(onMatch(filepath));
|
||||
});
|
||||
const filepaths = await fs.glob('node_modules/{*,@*/*}/package.json', {
|
||||
cwd: this.#appiumHome,
|
||||
absolute: true,
|
||||
});
|
||||
for (const filepath of filepaths) {
|
||||
queue.push(onMatch(filepath));
|
||||
}
|
||||
|
||||
// wait for everything to finish
|
||||
await B.all(queue);
|
||||
|
||||
@@ -347,7 +347,7 @@ function logServerAddress(url) {
|
||||
: href;
|
||||
};
|
||||
logger.info(
|
||||
`You can provide the following ${util.pluralize('URL', interfaces.length, false)} ` +
|
||||
`You can provide the following ${interfaces.length === 1 ? 'URL' : 'URLs'} ` +
|
||||
`in your client code to connect to this server:\n` +
|
||||
interfaces.map((iface) => `\t${toLabel(iface)}`).join('\n')
|
||||
);
|
||||
@@ -440,10 +440,7 @@ async function main(args) {
|
||||
process.once(signal, async function onSignal() {
|
||||
logger.info(`Received ${signal} - shutting down`);
|
||||
try {
|
||||
await appiumDriver.deleteAllSessions({
|
||||
force: true,
|
||||
reason: `The process has received ${signal} signal`,
|
||||
});
|
||||
await appiumDriver.shutdown(`The process has received ${signal} signal`);
|
||||
await server.close();
|
||||
process.exit(0);
|
||||
} catch (e) {
|
||||
|
||||
@@ -276,11 +276,18 @@ function adjustNodePath() {
|
||||
/**
|
||||
* Pulls the initial values of Appium settings from the given capabilities argument.
|
||||
* Each setting item must satisfy the following format:
|
||||
* `setting[setting_name]: setting_value`
|
||||
* `settings[setting_name]: setting_value`
|
||||
* or
|
||||
* ```
|
||||
* settings = {
|
||||
* setting_name1: 'setting_value1',
|
||||
* setting_name2: 'setting_value2',
|
||||
* }
|
||||
* ```
|
||||
* The capabilities argument itself gets mutated, so it does not contain parsed
|
||||
* settings anymore to avoid further parsing issues.
|
||||
* Check
|
||||
* https://github.com/appium/appium/blob/master/docs/en/advanced-concepts/settings.md
|
||||
* https://appium.io/docs/en/latest/guides/settings/
|
||||
* for more details on the available settings.
|
||||
*
|
||||
* @param {?Object} caps - Capabilities dictionary. It is mutated if
|
||||
@@ -295,14 +302,19 @@ function pullSettings(caps) {
|
||||
}
|
||||
|
||||
const result = {};
|
||||
const singleSettings = {};
|
||||
for (const [key, value] of _.toPairs(caps)) {
|
||||
const match = /\bsettings\[(\S+)\]$/.exec(key);
|
||||
if (!match) {
|
||||
continue;
|
||||
let match;
|
||||
if (/^(s|appium:s)ettings$/.test(key) && _.isPlainObject(value)) {
|
||||
Object.assign(result, value);
|
||||
delete caps[key];
|
||||
} else if ((match = /^(s|appium:s)ettings\[(\S+)\]$/.exec(key))) {
|
||||
singleSettings[match[2]] = value;
|
||||
delete caps[key];
|
||||
}
|
||||
|
||||
result[match[1]] = value;
|
||||
delete caps[key];
|
||||
}
|
||||
if (!_.isEmpty(singleSettings)) {
|
||||
Object.assign(result, singleSettings);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "appium",
|
||||
"version": "2.0.1",
|
||||
"version": "2.1.1",
|
||||
"description": "Automation for Apps.",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -60,12 +60,12 @@
|
||||
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@appium/base-driver": "^9.3.16",
|
||||
"@appium/base-plugin": "^2.2.16",
|
||||
"@appium/docutils": "^0.4.5",
|
||||
"@appium/base-driver": "^9.3.18",
|
||||
"@appium/base-plugin": "^2.2.18",
|
||||
"@appium/docutils": "^0.4.7",
|
||||
"@appium/schema": "^0.3.1",
|
||||
"@appium/support": "^4.1.3",
|
||||
"@appium/types": "^0.13.2",
|
||||
"@appium/support": "^4.1.5",
|
||||
"@appium/types": "^0.13.3",
|
||||
"@sidvind/better-ajv-errors": "2.1.0",
|
||||
"@types/argparse": "2.0.10",
|
||||
"@types/bluebird": "3.5.38",
|
||||
@@ -82,18 +82,17 @@
|
||||
"bluebird": "3.7.2",
|
||||
"cross-env": "7.0.3",
|
||||
"find-up": "5.0.0",
|
||||
"glob": "8.1.0",
|
||||
"lilconfig": "2.1.0",
|
||||
"lodash": "4.17.21",
|
||||
"npmlog": "7.0.1",
|
||||
"ora": "5.4.1",
|
||||
"package-changed": "3.0.0",
|
||||
"resolve-from": "5.0.0",
|
||||
"semver": "7.5.3",
|
||||
"semver": "7.5.4",
|
||||
"source-map-support": "0.5.21",
|
||||
"teen_process": "2.0.4",
|
||||
"type-fest": "3.11.1",
|
||||
"winston": "3.9.0",
|
||||
"type-fest": "3.13.1",
|
||||
"winston": "3.10.0",
|
||||
"wrap-ansi": "7.0.0",
|
||||
"yaml": "2.3.1"
|
||||
},
|
||||
|
||||
@@ -244,6 +244,26 @@ describe('FakeDriver via HTTP', function () {
|
||||
await driver.getSessions().should.eventually.be.empty;
|
||||
});
|
||||
|
||||
it('should not allow umbrella commands to prevent newCommandTimeout on inner driver', async function () {
|
||||
let localCaps = Object.assign(
|
||||
{
|
||||
'appium:newCommandTimeout': 0.25,
|
||||
},
|
||||
caps
|
||||
);
|
||||
let driver = await wdio({...wdOpts, capabilities: localCaps});
|
||||
should.exist(driver.sessionId);
|
||||
|
||||
// get the session list 6 times over 300ms. each request will be below the new command
|
||||
// timeout but since they are not received by the driver the session should still time out
|
||||
for (let i = 0; i < 6; i++) {
|
||||
await driver.getSessions();
|
||||
await B.delay(50);
|
||||
}
|
||||
await driver.getPageSource().should.eventually.be.rejectedWith(/terminated/);
|
||||
await driver.getSessions().should.eventually.be.empty;
|
||||
});
|
||||
|
||||
it('should accept valid W3C capabilities and start a W3C session', async function () {
|
||||
// Try with valid capabilities and check that it returns a session ID
|
||||
const w3cCaps = {
|
||||
|
||||
@@ -26,6 +26,7 @@ export function initMocks(sandbox = createSandbox()) {
|
||||
.returns({next: sandbox.stub().resolves({done: true})}),
|
||||
})
|
||||
),
|
||||
glob: /** @type {MockAppiumSupportFs['glob']} */ (sandbox.stub().resolves([])),
|
||||
mkdirp: /** @type {MockAppiumSupportFs['mkdirp']} */ (sandbox.stub().resolves()),
|
||||
readPackageJsonFrom: /** @type {MockAppiumSupportFs['readPackageJsonFrom']} */ (
|
||||
sandbox.stub().returns({version: APPIUM_VER, engines: {node: '>=12'}})
|
||||
@@ -166,6 +167,7 @@ export function initMocks(sandbox = createSandbox()) {
|
||||
* @property {SinonStubbedMember<SupportFs['readFile']>} readFile
|
||||
* @property {SinonStubbedMember<SupportFs['writeFile']>} writeFile
|
||||
* @property {SinonStubbedMember<SupportFs['walk']>} walk
|
||||
* @property {SinonStubbedMember<SupportFs['glob']>} glob
|
||||
* @property {SinonStubbedMember<SupportFs['mkdirp']>} mkdirp
|
||||
* @property {SinonStubbedMember<SupportFs['readPackageJsonFrom']>} readPackageJsonFrom
|
||||
* @property {SinonStubbedMember<SupportFs['findRoot']>} findRoot
|
||||
|
||||
@@ -232,6 +232,26 @@ describe('utils', function () {
|
||||
settings.should.eql({});
|
||||
caps.should.eql({});
|
||||
});
|
||||
it('should pull combined settings', function () {
|
||||
const caps = {
|
||||
platformName: 'foo',
|
||||
browserName: 'bar',
|
||||
'appium:settings[foo]': 'baz2',
|
||||
'appium:settings': {
|
||||
foo: 'baz',
|
||||
yolo: 'bar',
|
||||
},
|
||||
};
|
||||
const settings = pullSettings(caps);
|
||||
settings.should.eql({
|
||||
foo: 'baz2',
|
||||
yolo: 'bar',
|
||||
});
|
||||
caps.should.eql({
|
||||
platformName: 'foo',
|
||||
browserName: 'bar',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('inspect()', function () {
|
||||
|
||||
@@ -3,6 +3,30 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [9.3.18](https://github.com/appium/appium/compare/@appium/base-driver@9.3.17...@appium/base-driver@9.3.18) (2023-08-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **base-driver:** Fix possible NPE while cleaning up the state listener ([#19020](https://github.com/appium/appium/issues/19020)) ([53bfc68](https://github.com/appium/appium/commit/53bfc68eee5766ca8c6851c424c89d6b123d602e))
|
||||
* **base-driver:** Respect basic auth credentials if provided ([#19000](https://github.com/appium/appium/issues/19000)) ([ed8e83c](https://github.com/appium/appium/commit/ed8e83c76c5b660e619833515c2ea2ec29082e18))
|
||||
* **driver-test-support:** update dependency @types/lodash to v4.14.197 ([a080b72](https://github.com/appium/appium/commit/a080b729208b4e3c352456f0f230b63b0b7ee9ee))
|
||||
|
||||
|
||||
|
||||
## [9.3.17](https://github.com/appium/appium/compare/@appium/base-driver@9.3.16...@appium/base-driver@9.3.17) (2023-08-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **base-driver:** Tune responses caching logic ([#18922](https://github.com/appium/appium/issues/18922)) ([de5b55a](https://github.com/appium/appium/commit/de5b55ae90fefcce86962a48d5aceb73962e56b6))
|
||||
* **driver-test-support:** update definitelytyped ([c320e8a](https://github.com/appium/appium/commit/c320e8a1a61cb6d980d6d944ae47b60da97aa398))
|
||||
* **support:** update dependency glob to v10 ([#18490](https://github.com/appium/appium/issues/18490)) ([aaf31a5](https://github.com/appium/appium/commit/aaf31a577cb0b9cbe22646dcd888dc393a03aa11))
|
||||
* **test-support:** update dependency @colors/colors to v1.6.0 ([1358937](https://github.com/appium/appium/commit/1358937db2edf08ce1ebe3dff2f70ac6b07cd373))
|
||||
* **types:** update dependency type-fest to v3.13.1 ([fb34ab9](https://github.com/appium/appium/commit/fb34ab917216121d2b554677a12f07a03393d218))
|
||||
|
||||
|
||||
|
||||
## [9.3.16](https://github.com/appium/appium/compare/@appium/base-driver@9.3.15...@appium/base-driver@9.3.16) (2023-07-24)
|
||||
|
||||
|
||||
|
||||
@@ -293,8 +293,7 @@ export class DriverCore<const C extends Constraints, Settings extends StringReco
|
||||
`Potentially insecure feature '${name}' has not been ` +
|
||||
`enabled. If you want to enable this feature and accept ` +
|
||||
`the security ramifications, please do so by following ` +
|
||||
`the documented instructions at https://github.com/appium` +
|
||||
`/appium/blob/master/docs/en/writing-running-appium/security.md`
|
||||
`the documented instructions at http://appium.io/docs/en/2.0/guides/security/`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ function verifyAppExtension(app, supportedAppExtensions) {
|
||||
}
|
||||
|
||||
async function calculateFolderIntegrity(folderPath) {
|
||||
return (await fs.glob('**/*', {cwd: folderPath, strict: false, nosort: true})).length;
|
||||
return (await fs.glob('**/*', {cwd: folderPath})).length;
|
||||
}
|
||||
|
||||
async function calculateFileIntegrity(filePath) {
|
||||
@@ -362,12 +362,19 @@ async function configureApp(
|
||||
* @returns {Promise<RemoteAppData>}
|
||||
*/
|
||||
async function queryAppLink(appLink, reqHeaders) {
|
||||
const {href} = url.parse(appLink);
|
||||
const {href, auth} = url.parse(appLink);
|
||||
const axiosUrl = auth ? href.replace(`${auth}@`, '') : href;
|
||||
/** @type {import('axios').AxiosBasicCredentials|undefined} */
|
||||
const axiosAuth = auth ? {
|
||||
username: auth.substring(0, auth.indexOf(':')),
|
||||
password: auth.substring(auth.indexOf(':') + 1),
|
||||
} : undefined;
|
||||
/**
|
||||
* @type {import('axios').RawAxiosRequestConfig}
|
||||
*/
|
||||
const requestOpts = {
|
||||
url: href,
|
||||
url: axiosUrl,
|
||||
auth: axiosAuth,
|
||||
responseType: 'stream',
|
||||
timeout: APP_DOWNLOAD_TIMEOUT_MS,
|
||||
validateStatus: (status) =>
|
||||
@@ -382,7 +389,7 @@ async function queryAppLink(appLink, reqHeaders) {
|
||||
status,
|
||||
};
|
||||
} catch (err) {
|
||||
throw new Error(`Cannot download the app from ${href}: ${err.message}`);
|
||||
throw new Error(`Cannot download the app from ${axiosUrl}: ${err.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,7 +482,6 @@ async function unzipApp(zipPath, dstRoot, supportedAppExtensions) {
|
||||
const sortedBundleItems = (
|
||||
await fs.glob(globPattern, {
|
||||
cwd: tmpRoot,
|
||||
strict: false,
|
||||
// Get the top level match
|
||||
})
|
||||
).sort((a, b) => a.split(path.sep).length - b.split(path.sep).length);
|
||||
|
||||
@@ -1,34 +1,31 @@
|
||||
import log from './logger';
|
||||
import LRU from 'lru-cache';
|
||||
import {fs, util} from '@appium/support';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import _ from 'lodash';
|
||||
import {EventEmitter} from 'events';
|
||||
|
||||
const CACHE_SIZE = 1024;
|
||||
const IDEMPOTENT_RESPONSES = new LRU({
|
||||
max: CACHE_SIZE,
|
||||
max: 64,
|
||||
ttl: 30 * 60 * 1000,
|
||||
updateAgeOnGet: true,
|
||||
dispose(key, {response}) {
|
||||
if (response) {
|
||||
fs.rimrafSync(response);
|
||||
}
|
||||
},
|
||||
updateAgeOnHas: true,
|
||||
dispose: (key, {responseStateListener}) => {
|
||||
responseStateListener?.removeAllListeners();
|
||||
}
|
||||
});
|
||||
const MONITORED_METHODS = ['POST', 'PATCH'];
|
||||
const IDEMPOTENCY_KEY_HEADER = 'x-idempotency-key';
|
||||
|
||||
process.on('exit', () => {
|
||||
const resPaths = [...IDEMPOTENT_RESPONSES.values()].map(({response}) => response).filter(Boolean);
|
||||
for (const resPath of resPaths) {
|
||||
try {
|
||||
// Asynchronous calls are not supported in onExit handler
|
||||
fs.rimrafSync(resPath);
|
||||
} catch (ign) {}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} key
|
||||
* @param {import('express').Request} req
|
||||
* @param {import('express').Response} res
|
||||
*/
|
||||
function cacheResponse(key, req, res) {
|
||||
if (!res.socket) {
|
||||
return;
|
||||
}
|
||||
|
||||
const responseStateListener = new EventEmitter();
|
||||
IDEMPOTENT_RESPONSES.set(key, {
|
||||
method: req.method,
|
||||
@@ -36,33 +33,23 @@ function cacheResponse(key, req, res) {
|
||||
response: null,
|
||||
responseStateListener,
|
||||
});
|
||||
const tmpFile = path.resolve(os.tmpdir(), `${util.uuidV4()}.response`);
|
||||
const responseListener = fs.createWriteStream(tmpFile, {
|
||||
emitClose: true,
|
||||
});
|
||||
const originalSocketWriter = res.socket.write.bind(res.socket);
|
||||
let response = '';
|
||||
const patchedWriter = (chunk, encoding, next) => {
|
||||
if (responseListener.writable) {
|
||||
responseListener.write(chunk);
|
||||
if (_.isString(chunk)) {
|
||||
response += chunk;
|
||||
} else if (_.isFunction(chunk.toString)) {
|
||||
response += chunk.toString(_.isString(encoding) ? encoding : undefined);
|
||||
}
|
||||
return originalSocketWriter(chunk, encoding, next);
|
||||
};
|
||||
res.socket.write = patchedWriter;
|
||||
let writeError = null;
|
||||
let httpErrorMessage = null;
|
||||
let isResponseFullySent = false;
|
||||
responseListener.once('error', (e) => {
|
||||
writeError = e;
|
||||
});
|
||||
res.once('finish', () => {
|
||||
isResponseFullySent = true;
|
||||
responseListener.end();
|
||||
});
|
||||
res.once('error', (e) => { httpErrorMessage = e.message; });
|
||||
req.once('error', (e) => { httpErrorMessage = e.message; });
|
||||
res.once('finish', () => { isResponseFullySent = true; });
|
||||
res.once('close', () => {
|
||||
if (!isResponseFullySent) {
|
||||
responseListener.end();
|
||||
}
|
||||
});
|
||||
responseListener.once('close', () => {
|
||||
if (res.socket?.write === patchedWriter) {
|
||||
res.socket.write = originalSocketWriter;
|
||||
}
|
||||
@@ -70,35 +57,41 @@ function cacheResponse(key, req, res) {
|
||||
if (!IDEMPOTENT_RESPONSES.has(key)) {
|
||||
log.info(
|
||||
`Could not cache the response identified by '${key}'. ` +
|
||||
`Cache consistency has been damaged`
|
||||
`Cache consistency has been damaged`
|
||||
);
|
||||
return responseStateListener.emit('ready', null);
|
||||
}
|
||||
if (writeError) {
|
||||
log.info(`Could not cache the response identified by '${key}': ${writeError.message}`);
|
||||
} else if (httpErrorMessage) {
|
||||
log.info(`Could not cache the response identified by '${key}': ${httpErrorMessage}`);
|
||||
IDEMPOTENT_RESPONSES.delete(key);
|
||||
return responseStateListener.emit('ready', null);
|
||||
}
|
||||
if (!isResponseFullySent) {
|
||||
} else if (!isResponseFullySent) {
|
||||
log.info(
|
||||
`Could not cache the response identified by '${key}', ` +
|
||||
`because it has not been completed`
|
||||
`because it has not been completed`
|
||||
);
|
||||
log.info('Does the client terminate connections too early?');
|
||||
IDEMPOTENT_RESPONSES.delete(key);
|
||||
return responseStateListener.emit('ready', null);
|
||||
}
|
||||
|
||||
IDEMPOTENT_RESPONSES.get(key).response = tmpFile;
|
||||
responseStateListener.emit('ready', tmpFile);
|
||||
const value = IDEMPOTENT_RESPONSES.get(key);
|
||||
if (value) {
|
||||
value.response = Buffer.from(response, 'utf8');
|
||||
responseStateListener.emit('ready', value.response);
|
||||
} else {
|
||||
responseStateListener.emit('ready', null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('express').Request} req
|
||||
* @param {import('express').Response} res
|
||||
*/
|
||||
async function handleIdempotency(req, res, next) {
|
||||
const key = req.headers[IDEMPOTENCY_KEY_HEADER];
|
||||
if (!key) {
|
||||
const keyOrArr = req.headers[IDEMPOTENCY_KEY_HEADER];
|
||||
if (!keyOrArr) {
|
||||
return next();
|
||||
}
|
||||
|
||||
const key = _.isArray(keyOrArr) ? keyOrArr[0] : keyOrArr;
|
||||
if (!MONITORED_METHODS.includes(req.method)) {
|
||||
// GET, DELETE, etc. requests are idempotent by default
|
||||
// there is no need to cache them
|
||||
@@ -112,39 +105,32 @@ async function handleIdempotency(req, res, next) {
|
||||
}
|
||||
|
||||
const {
|
||||
method: storedMethod,
|
||||
path: storedPath,
|
||||
method,
|
||||
path,
|
||||
response,
|
||||
responseStateListener,
|
||||
} = IDEMPOTENT_RESPONSES.get(key);
|
||||
if (req.method !== storedMethod || req.path !== storedPath) {
|
||||
if (req.method !== method || req.path !== path) {
|
||||
log.warn(`Got two different requests with the same idempotency key '${key}'`);
|
||||
log.warn('Is the client generating idempotency keys properly?');
|
||||
return next();
|
||||
}
|
||||
|
||||
const rerouteCachedResponse = async (cachedResPath) => {
|
||||
if (!(await fs.exists(cachedResPath))) {
|
||||
IDEMPOTENT_RESPONSES.delete(key);
|
||||
log.warn(`Could not read the cached response identified by key '${key}'`);
|
||||
log.warn('The temporary storage is not accessible anymore');
|
||||
return next();
|
||||
}
|
||||
fs.createReadStream(cachedResPath).pipe(res.socket);
|
||||
};
|
||||
|
||||
if (response) {
|
||||
log.info(`The same request with the idempotency key '${key}' has been already processed`);
|
||||
log.info(`Rerouting its response to the current request`);
|
||||
await rerouteCachedResponse(response);
|
||||
if (!res.socket?.writable) {
|
||||
return next();
|
||||
}
|
||||
res.socket.write(response.toString('utf8'));
|
||||
} else {
|
||||
log.info(`The same request with the idempotency key '${key}' is being processed`);
|
||||
log.info(`Waiting for the response to be rerouted to the current request`);
|
||||
responseStateListener.once('ready', async (cachedResponsePath) => {
|
||||
if (!cachedResponsePath) {
|
||||
responseStateListener.once('ready', async (/** @type {Buffer?} */ cachedResponse) => {
|
||||
if (!cachedResponse || !res.socket?.writable) {
|
||||
return next();
|
||||
}
|
||||
await rerouteCachedResponse(cachedResponsePath);
|
||||
res.socket.write(cachedResponse.toString('utf8'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,6 +118,7 @@ function configureServer({
|
||||
} else {
|
||||
app.use(allowCrossDomainAsyncExecute(basePath));
|
||||
}
|
||||
// @ts-ignore
|
||||
app.use(handleIdempotency);
|
||||
app.use(fixPythonContentType(basePath));
|
||||
app.use(defaultToJSONContentType);
|
||||
|
||||
@@ -843,24 +843,43 @@ export class UnableToCaptureScreen extends ProtocolError {
|
||||
}
|
||||
}
|
||||
|
||||
function generateBadParametersMessage(requiredParams, actualParams) {
|
||||
const toArray = (/** @type {any} */ x) => _.isArray(x) ? x : [];
|
||||
|
||||
const requiredParamNames = toArray(requiredParams?.required);
|
||||
const actualParamNames = toArray(actualParams);
|
||||
const missingRequiredParamNames = _.difference(requiredParamNames, actualParamNames);
|
||||
/** @type {string[]} */
|
||||
const resultLines = [];
|
||||
resultLines.push(_.isEmpty(missingRequiredParamNames)
|
||||
// This should not happen
|
||||
? 'Some of the provided parameters are not known'
|
||||
: (`The following required parameter${missingRequiredParamNames.length === 1 ? ' is ' : 's are '}`
|
||||
+ `missing: ${JSON.stringify(missingRequiredParamNames)}`)
|
||||
);
|
||||
if (!_.isEmpty(requiredParamNames)) {
|
||||
resultLines.push(`Known required parameters are: ${JSON.stringify(requiredParamNames)}`);
|
||||
}
|
||||
const optionalParamNames = _.difference(toArray(requiredParams?.optional), ['sessionId', 'id']);
|
||||
if (!_.isEmpty(optionalParamNames)) {
|
||||
resultLines.push(`Known optional parameters are: ${JSON.stringify(optionalParamNames)}`);
|
||||
}
|
||||
resultLines.push(
|
||||
`You have provided${_.isEmpty(actualParamNames) ? ' none' : (': ' + JSON.stringify(actualParams))}`
|
||||
);
|
||||
return resultLines.join('\n');
|
||||
}
|
||||
|
||||
// Equivalent to W3C InvalidArgumentError
|
||||
export class BadParametersError extends ES6Error {
|
||||
static error() {
|
||||
return 'invalid argument';
|
||||
}
|
||||
constructor(requiredParams, actualParams, errMessage) {
|
||||
let message;
|
||||
if (!errMessage) {
|
||||
message =
|
||||
`Parameters were incorrect. We wanted ` +
|
||||
`${JSON.stringify(requiredParams)} and you ` +
|
||||
`sent ${JSON.stringify(actualParams)}`;
|
||||
} else {
|
||||
message = `Parameters were incorrect. You sent ${JSON.stringify(
|
||||
actualParams
|
||||
)}, ${errMessage}`;
|
||||
}
|
||||
super(message);
|
||||
super(errMessage
|
||||
? `Parameters were incorrect. You sent ${JSON.stringify(actualParams)}, ${errMessage}`
|
||||
: generateBadParametersMessage(requiredParams, actualParams)
|
||||
);
|
||||
this.w3cStatus = HTTPStatusCodes.BAD_REQUEST;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/base-driver",
|
||||
"version": "9.3.16",
|
||||
"version": "9.3.18",
|
||||
"description": "Base driver class for Appium drivers",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -44,13 +44,13 @@
|
||||
"test:types": "tsd"
|
||||
},
|
||||
"dependencies": {
|
||||
"@appium/support": "^4.1.3",
|
||||
"@appium/types": "^0.13.2",
|
||||
"@colors/colors": "1.5.0",
|
||||
"@appium/support": "^4.1.5",
|
||||
"@appium/types": "^0.13.3",
|
||||
"@colors/colors": "1.6.0",
|
||||
"@types/async-lock": "1.4.0",
|
||||
"@types/bluebird": "3.5.38",
|
||||
"@types/express": "4.17.17",
|
||||
"@types/lodash": "4.14.195",
|
||||
"@types/lodash": "4.14.197",
|
||||
"@types/method-override": "0.0.32",
|
||||
"@types/serve-favicon": "2.5.4",
|
||||
"async-lock": "1.4.0",
|
||||
@@ -67,7 +67,7 @@
|
||||
"morgan": "1.10.0",
|
||||
"serve-favicon": "2.5.0",
|
||||
"source-map-support": "0.5.21",
|
||||
"type-fest": "3.11.1",
|
||||
"type-fest": "3.13.1",
|
||||
"validate.js": "0.13.1"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -428,7 +428,7 @@ describe('Protocol', function () {
|
||||
status.should.equal(400);
|
||||
|
||||
const {error: w3cError, message, stacktrace} = data.value;
|
||||
message.should.match(/Parameters were incorrect/);
|
||||
message.should.match(/following required parameter/);
|
||||
stacktrace.should.match(/protocol.js/);
|
||||
w3cError.should.be.a.string;
|
||||
w3cError.should.equal(errors.InvalidArgumentError.error());
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.2.18](https://github.com/appium/appium/compare/@appium/base-plugin@2.2.17...@appium/base-plugin@2.2.18) (2023-08-21)
|
||||
|
||||
**Note:** Version bump only for package @appium/base-plugin
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.2.17](https://github.com/appium/appium/compare/@appium/base-plugin@2.2.16...@appium/base-plugin@2.2.17) (2023-08-17)
|
||||
|
||||
**Note:** Version bump only for package @appium/base-plugin
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.2.16](https://github.com/appium/appium/compare/@appium/base-plugin@2.2.15...@appium/base-plugin@2.2.16) (2023-07-24)
|
||||
|
||||
**Note:** Version bump only for package @appium/base-plugin
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/base-plugin",
|
||||
"version": "2.2.16",
|
||||
"version": "2.2.18",
|
||||
"description": "The base plugin used to create Appium 2.0 plugins",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -40,8 +40,8 @@
|
||||
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@appium/base-driver": "^9.3.16",
|
||||
"@appium/support": "^4.1.3"
|
||||
"@appium/base-driver": "^9.3.18",
|
||||
"@appium/support": "^4.1.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
|
||||
|
||||
@@ -3,6 +3,26 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.0.24](https://github.com/appium/appium/compare/@appium/doctor@2.0.23...@appium/doctor@2.0.24) (2023-08-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **doctor:** update dependency appium-adb to v9.14.5 ([d5f3a28](https://github.com/appium/appium/commit/d5f3a288c2497d4020b7eabc667814744e69ac48))
|
||||
|
||||
|
||||
|
||||
## [2.0.23](https://github.com/appium/appium/compare/@appium/doctor@2.0.22...@appium/doctor@2.0.23) (2023-08-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **doctor:** update dependency appium-adb to v9.14.4 ([#18844](https://github.com/appium/appium/issues/18844)) ([a9e86aa](https://github.com/appium/appium/commit/a9e86aabc657bf22df8b1c5f67ab93acc0ced934))
|
||||
* **doctor:** update dependency inquirer to v8.2.6 ([#18940](https://github.com/appium/appium/issues/18940)) ([a8cc551](https://github.com/appium/appium/commit/a8cc551210c31b014025f7c56b091163f4d15df1))
|
||||
* **test-support:** update dependency @colors/colors to v1.6.0 ([1358937](https://github.com/appium/appium/commit/1358937db2edf08ce1ebe3dff2f70ac6b07cd373))
|
||||
|
||||
|
||||
|
||||
## [2.0.22](https://github.com/appium/appium/compare/@appium/doctor@2.0.21...@appium/doctor@2.0.22) (2023-07-24)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/doctor",
|
||||
"version": "2.0.22",
|
||||
"version": "2.0.24",
|
||||
"description": "Test environment for fitness to run Appium",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -44,13 +44,13 @@
|
||||
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@appium/support": "^4.1.3",
|
||||
"@colors/colors": "1.5.0",
|
||||
"@appium/support": "^4.1.5",
|
||||
"@colors/colors": "1.6.0",
|
||||
"@types/bluebird": "3.5.38",
|
||||
"@types/teen_process": "2.0.0",
|
||||
"appium-adb": "9.11.7",
|
||||
"appium-adb": "9.14.5",
|
||||
"bluebird": "3.7.2",
|
||||
"inquirer": "8.2.5",
|
||||
"inquirer": "8.2.6",
|
||||
"lodash": "4.17.21",
|
||||
"source-map-support": "0.5.21",
|
||||
"teen_process": "2.0.4",
|
||||
|
||||
@@ -12,6 +12,7 @@ import * as tp from 'teen_process';
|
||||
import {withMocks, stubEnv} from '@appium/test-support';
|
||||
import B from 'bluebird';
|
||||
import {removeColors} from './helper';
|
||||
import {createSandbox} from 'sinon';
|
||||
|
||||
describe('android', function () {
|
||||
const apkAnalyzerFilename = system.isWindows() ? 'apkanalyzer.bat' : 'apkanalyzer';
|
||||
@@ -59,8 +60,17 @@ describe('android', function () {
|
||||
})
|
||||
);
|
||||
describe(
|
||||
'AndroidToolCheck',
|
||||
withMocks({adb}, (mocks) => {
|
||||
'AndroidToolCheck', function () {
|
||||
// withMocks won't work with ESM modules: https://github.com/sinonjs/sinon/issues/2530
|
||||
/** @type {sinon.SinonSandbox} */
|
||||
let sandbox;
|
||||
beforeEach(function () {
|
||||
sandbox = createSandbox();
|
||||
});
|
||||
afterEach(function () {
|
||||
sandbox.restore();
|
||||
});
|
||||
|
||||
stubEnv();
|
||||
const check = new AndroidToolCheck();
|
||||
it('autofix', function () {
|
||||
@@ -68,16 +78,13 @@ describe('android', function () {
|
||||
});
|
||||
it('diagnose - success', async function () {
|
||||
process.env.ANDROID_HOME = '/a/b/c/d';
|
||||
mocks.adb
|
||||
.expects('getAndroidBinaryPath')
|
||||
.exactly(check.tools.length)
|
||||
.returns(B.resolve('/path/to/binary'));
|
||||
sandbox.stub(adb, 'getAndroidBinaryPath')
|
||||
.get(() => sandbox.fake.resolves('/path/to/binary'));
|
||||
(await check.diagnose()).should.deep.equal({
|
||||
ok: true,
|
||||
optional: false,
|
||||
message: `adb, emulator, ${apkAnalyzerFilename} exist: /a/b/c/d`,
|
||||
});
|
||||
mocks.verify();
|
||||
});
|
||||
it('diagnose - failure - no ANDROID_HOME', async function () {
|
||||
delete process.env.ANDROID_HOME;
|
||||
@@ -87,17 +94,16 @@ describe('android', function () {
|
||||
optional: false,
|
||||
message: `adb, emulator, ${apkAnalyzerFilename} could not be found because ANDROID_HOME or ANDROID_SDK_ROOT is NOT set!`,
|
||||
});
|
||||
mocks.verify();
|
||||
});
|
||||
it('diagnose - failure - path not valid', async function () {
|
||||
process.env.ANDROID_HOME = '/a/b/c/d';
|
||||
mocks.adb.expects('getAndroidBinaryPath').exactly(check.tools.length).throws();
|
||||
sandbox.stub(adb, 'getAndroidBinaryPath')
|
||||
.get(() => sandbox.fake.throws());
|
||||
(await check.diagnose()).should.deep.equal({
|
||||
ok: false,
|
||||
optional: false,
|
||||
message: `adb, emulator, ${apkAnalyzerFilename} could NOT be found in /a/b/c/d!`,
|
||||
});
|
||||
mocks.verify();
|
||||
});
|
||||
it('fix - ANDROID_HOME', async function () {
|
||||
delete process.env.ANDROID_HOME;
|
||||
@@ -111,7 +117,7 @@ describe('android', function () {
|
||||
`Manually install adb, emulator, ${apkAnalyzerFilename} and add it to PATH. https://developer.android.com/studio#cmdline-tools and https://developer.android.com/studio/intro/update#sdk-manager may help to setup.`
|
||||
);
|
||||
});
|
||||
})
|
||||
}
|
||||
);
|
||||
|
||||
describe(
|
||||
|
||||
@@ -3,6 +3,24 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [0.4.7](https://github.com/appium/appium/compare/@appium/docutils@0.4.6...@appium/docutils@0.4.7) (2023-08-21)
|
||||
|
||||
**Note:** Version bump only for package @appium/docutils
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.4.6](https://github.com/appium/appium/compare/@appium/docutils@0.4.5...@appium/docutils@0.4.6) (2023-08-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **support:** update dependency semver to v7.5.4 ([03ddcdf](https://github.com/appium/appium/commit/03ddcdfcafbccf6698868a272e499cbdac41d791))
|
||||
* **types:** update dependency type-fest to v3.13.1 ([fb34ab9](https://github.com/appium/appium/commit/fb34ab917216121d2b554677a12f07a03393d218))
|
||||
|
||||
|
||||
|
||||
## [0.4.5](https://github.com/appium/appium/compare/@appium/docutils@0.4.4...@appium/docutils@0.4.5) (2023-07-24)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/docutils",
|
||||
"version": "0.4.5",
|
||||
"version": "0.4.7",
|
||||
"description": "Documentation generation utilities for Appium and related projects",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -49,9 +49,9 @@
|
||||
"start": "node ./build/lib/cli/index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@appium/support": "^4.1.3",
|
||||
"@appium/support": "^4.1.5",
|
||||
"@appium/tsconfig": "^0.3.0",
|
||||
"@appium/typedoc-plugin-appium": "^0.6.5",
|
||||
"@appium/typedoc-plugin-appium": "^0.6.6",
|
||||
"@sliphua/lilconfig-ts-loader": "3.2.2",
|
||||
"@types/which": "3.0.0",
|
||||
"chalk": "4.1.2",
|
||||
@@ -65,10 +65,10 @@
|
||||
"log-symbols": "4.1.0",
|
||||
"pkg-dir": "5.0.0",
|
||||
"read-pkg": "5.2.0",
|
||||
"semver": "7.5.3",
|
||||
"semver": "7.5.4",
|
||||
"source-map-support": "0.5.21",
|
||||
"teen_process": "2.0.4",
|
||||
"type-fest": "3.11.1",
|
||||
"type-fest": "3.13.1",
|
||||
"typedoc": "0.23.28",
|
||||
"typedoc-plugin-markdown": "3.14.0",
|
||||
"typedoc-plugin-resolve-crossmodule-references": "0.3.3",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
mkdocs==1.4.3
|
||||
mkdocs-material==9.1.18
|
||||
mkdocs==1.5.2
|
||||
mkdocs-material==9.1.21
|
||||
mkdocs-material-extensions==1.1.1
|
||||
mike==1.1.2
|
||||
|
||||
@@ -3,6 +3,26 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [0.4.13](https://github.com/appium/appium/compare/@appium/driver-test-support@0.4.12...@appium/driver-test-support@0.4.13) (2023-08-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **driver-test-support:** update dependency @types/lodash to v4.14.197 ([a080b72](https://github.com/appium/appium/commit/a080b729208b4e3c352456f0f230b63b0b7ee9ee))
|
||||
|
||||
|
||||
|
||||
## [0.4.12](https://github.com/appium/appium/compare/@appium/driver-test-support@0.4.11...@appium/driver-test-support@0.4.12) (2023-08-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **driver-test-support:** update definitelytyped ([c320e8a](https://github.com/appium/appium/commit/c320e8a1a61cb6d980d6d944ae47b60da97aa398))
|
||||
* **test-support:** update dependency sinon to v15.2.0 ([a21ae6a](https://github.com/appium/appium/commit/a21ae6ab2bcaba44ecdacae67076cf011b4e5ae8))
|
||||
* **types:** update dependency type-fest to v3.13.1 ([fb34ab9](https://github.com/appium/appium/commit/fb34ab917216121d2b554677a12f07a03393d218))
|
||||
|
||||
|
||||
|
||||
## [0.4.11](https://github.com/appium/appium/compare/@appium/driver-test-support@0.4.10...@appium/driver-test-support@0.4.11) (2023-07-24)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/driver-test-support",
|
||||
"version": "0.4.11",
|
||||
"version": "0.4.13",
|
||||
"description": "Test utilities for Appium drivers",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -41,18 +41,18 @@
|
||||
},
|
||||
"types": "./build/lib/index.d.ts",
|
||||
"dependencies": {
|
||||
"@appium/types": "^0.13.2",
|
||||
"@types/lodash": "4.14.195",
|
||||
"@appium/types": "^0.13.3",
|
||||
"@types/lodash": "4.14.197",
|
||||
"@types/stoppable": "1.1.1",
|
||||
"axios": "1.4.0",
|
||||
"bluebird": "3.7.2",
|
||||
"chai": "4.3.7",
|
||||
"get-port": "5.1.1",
|
||||
"lodash": "4.17.21",
|
||||
"sinon": "15.1.2",
|
||||
"sinon": "15.2.0",
|
||||
"source-map-support": "0.5.21",
|
||||
"stoppable": "1.1.0",
|
||||
"type-fest": "3.11.1"
|
||||
"type-fest": "3.13.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"appium": "^2.0.0-beta.43",
|
||||
|
||||
@@ -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.
|
||||
|
||||
## [3.0.16](https://github.com/appium/appium/compare/@appium/execute-driver-plugin@3.0.15...@appium/execute-driver-plugin@3.0.16) (2023-08-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **execute-driver-plugin:** update dependency webdriverio to v7.32.3 ([9a5c9ae](https://github.com/appium/appium/commit/9a5c9ae55c97ea3e5c604ecbc3f972480d091ba9))
|
||||
|
||||
|
||||
|
||||
## [3.0.15](https://github.com/appium/appium/compare/@appium/execute-driver-plugin@3.0.14...@appium/execute-driver-plugin@3.0.15) (2023-07-24)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/execute-driver-plugin",
|
||||
"version": "3.0.15",
|
||||
"version": "3.0.16",
|
||||
"description": "Plugin for batching and executing driver commands with Appiums",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -43,7 +43,7 @@
|
||||
"lodash": "4.17.21",
|
||||
"source-map-support": "0.5.21",
|
||||
"vm2": "3.9.19",
|
||||
"webdriverio": "7.32.0"
|
||||
"webdriverio": "7.32.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"appium": "^2.0.0-beta.35"
|
||||
|
||||
@@ -3,6 +3,24 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [5.2.8](https://github.com/appium/appium/compare/@appium/fake-driver@5.2.7...@appium/fake-driver@5.2.8) (2023-08-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **universal-xml-plugin:** update dependency xpath to v0.0.33 ([#18952](https://github.com/appium/appium/issues/18952)) ([f2cff24](https://github.com/appium/appium/commit/f2cff24685e96578f17549454de7b7931c13df83))
|
||||
|
||||
|
||||
|
||||
## [5.2.7](https://github.com/appium/appium/compare/@appium/fake-driver@5.2.6...@appium/fake-driver@5.2.7) (2023-08-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **universal-xml-plugin:** update dependency @xmldom/xmldom to v0.8.10 ([#18949](https://github.com/appium/appium/issues/18949)) ([12147d5](https://github.com/appium/appium/commit/12147d518fc3ac86b01c3401b9e462b5dca99ca4))
|
||||
|
||||
|
||||
|
||||
## [5.2.6](https://github.com/appium/appium/compare/@appium/fake-driver@5.2.5...@appium/fake-driver@5.2.6) (2023-07-03)
|
||||
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ const ContextsMixin: FakeDriverContextsMixin = {
|
||||
this.appModel.deactivateFrame();
|
||||
} else {
|
||||
const nodes = this.appModel.xpathQuery(`//iframe[@id="${frameId}"]`);
|
||||
if (!nodes.length) {
|
||||
if (!_.isArray(nodes) || _.isEmpty(nodes)) {
|
||||
throw new errors.NoSuchFrameError();
|
||||
}
|
||||
this.appModel.activateFrame(nodes[0]);
|
||||
|
||||
@@ -4,6 +4,7 @@ import path from 'path';
|
||||
import XMLDom from '@xmldom/xmldom';
|
||||
import xpath from 'xpath';
|
||||
import log from './logger';
|
||||
import _ from 'lodash';
|
||||
import {FakeElement} from './fake-element';
|
||||
|
||||
const SCREENSHOT = path.join(__dirname, 'screen.png');
|
||||
@@ -28,7 +29,7 @@ export class FakeApp {
|
||||
|
||||
get title() {
|
||||
let nodes = this.xpathQuery('//title');
|
||||
if (nodes.length < 1) {
|
||||
if (!_.isArray(nodes) || nodes.length < 1) {
|
||||
throw new Error('No title!');
|
||||
}
|
||||
const node = /** @type {Node} */ (nodes[0]);
|
||||
@@ -75,6 +76,11 @@ export class FakeApp {
|
||||
|
||||
setDims() {
|
||||
const nodes = this.xpathQuery('//app');
|
||||
if (!_.isArray(nodes)) {
|
||||
throw new Error(
|
||||
'Cannot fetch app dimensions because no corresponding node has benn found in the source'
|
||||
);
|
||||
}
|
||||
const app = new FakeElement(nodes[0], this);
|
||||
this._width = parseInt(app.nodeAttrs.width, 10);
|
||||
this._height = parseInt(app.nodeAttrs.height, 10);
|
||||
@@ -93,7 +99,8 @@ export class FakeApp {
|
||||
}
|
||||
|
||||
getWebviews() {
|
||||
return this.xpathQuery('//MockWebView/*[1]').map((n) => new FakeWebView(n));
|
||||
const nodes = this.xpathQuery('//MockWebView/*[1]');
|
||||
return _.isArray(nodes) ? nodes.map((n) => new FakeWebView(n)) : [];
|
||||
}
|
||||
|
||||
activateWebview(wv) {
|
||||
@@ -153,7 +160,7 @@ export class FakeApp {
|
||||
|
||||
showAlert(alertId) {
|
||||
let nodes = this.xpathQuery(`//alert[@id="${alertId}"]`);
|
||||
if (nodes.length < 1) {
|
||||
if (!_.isArray(nodes) || _.isEmpty(nodes)) {
|
||||
throw new Error(`Alert ${alertId} doesn't exist!`);
|
||||
}
|
||||
this.activeAlert = new FakeElement(nodes[0], this);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/fake-driver",
|
||||
"version": "5.2.6",
|
||||
"version": "5.2.8",
|
||||
"description": "Mock driver used internally by Appium for testing. Ignore",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -47,12 +47,12 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/bluebird": "3.5.38",
|
||||
"@xmldom/xmldom": "0.8.8",
|
||||
"@xmldom/xmldom": "0.8.10",
|
||||
"asyncbox": "2.9.4",
|
||||
"bluebird": "3.7.2",
|
||||
"lodash": "4.17.21",
|
||||
"source-map-support": "0.5.21",
|
||||
"xpath": "0.0.32"
|
||||
"xpath": "0.0.33"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"appium": "^2.0.0-beta.35"
|
||||
|
||||
@@ -131,7 +131,7 @@ function generalTests() {
|
||||
it('should throw an error if a required overload param is missing', async function () {
|
||||
await driver
|
||||
.executeScript('fake: addition', [{num3: 4}])
|
||||
.should.be.rejectedWith(/Parameters were incorrect/);
|
||||
.should.be.rejectedWith(/required parameters are missing/);
|
||||
});
|
||||
|
||||
it('should throw an error if sending in wrong types of params', async function () {
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [3.1.22](https://github.com/appium/appium/compare/@appium/fake-plugin@3.1.21...@appium/fake-plugin@3.1.22) (2023-08-21)
|
||||
|
||||
**Note:** Version bump only for package @appium/fake-plugin
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [3.1.21](https://github.com/appium/appium/compare/@appium/fake-plugin@3.1.20...@appium/fake-plugin@3.1.21) (2023-08-17)
|
||||
|
||||
**Note:** Version bump only for package @appium/fake-plugin
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [3.1.20](https://github.com/appium/appium/compare/@appium/fake-plugin@3.1.19...@appium/fake-plugin@3.1.20) (2023-07-24)
|
||||
|
||||
**Note:** Version bump only for package @appium/fake-plugin
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/fake-plugin",
|
||||
"version": "3.1.20",
|
||||
"version": "3.1.22",
|
||||
"description": "A fake Appium 2.0 plugin",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -39,8 +39,8 @@
|
||||
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@appium/base-plugin": "^2.2.16",
|
||||
"@appium/support": "^4.1.3",
|
||||
"@appium/base-plugin": "^2.2.18",
|
||||
"@appium/support": "^4.1.5",
|
||||
"@types/bluebird": "3.5.38",
|
||||
"bluebird": "3.7.2",
|
||||
"lodash": "4.17.21",
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.1.4](https://github.com/appium/appium/compare/@appium/images-plugin@2.1.3...@appium/images-plugin@2.1.4) (2023-08-21)
|
||||
|
||||
**Note:** Version bump only for package @appium/images-plugin
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.3](https://github.com/appium/appium/compare/@appium/images-plugin@2.1.2...@appium/images-plugin@2.1.3) (2023-08-17)
|
||||
|
||||
**Note:** Version bump only for package @appium/images-plugin
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.2](https://github.com/appium/appium/compare/@appium/images-plugin@2.1.1...@appium/images-plugin@2.1.2) (2023-06-14)
|
||||
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ assert File.size? 'find_result_visual.png'
|
||||
The image must have the same scale and look the same. However, you can add a scaling transformation beforehand.
|
||||
|
||||
official doc:
|
||||
https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/image-comparison.md
|
||||
https://github.com/appium/appium/blob/master/packages/images-plugin/docs/image-comparison.md
|
||||
OpenCV algorithm doc:
|
||||
https://docs.opencv.org/2.4/doc/tutorials/imgproc/histograms/template_matching/template_matching.html
|
||||
official sample code:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/images-plugin",
|
||||
"version": "2.1.2",
|
||||
"version": "2.1.4",
|
||||
"description": "Plugin for working with images and image elements in Appium",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -39,10 +39,10 @@
|
||||
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@appium/opencv": "^2.1.1",
|
||||
"@appium/opencv": "^2.1.3",
|
||||
"lodash": "4.17.21",
|
||||
"lru-cache": "7.18.3",
|
||||
"sharp": "0.32.1",
|
||||
"sharp": "0.32.5",
|
||||
"source-map-support": "0.5.21"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -3,6 +3,22 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.1.3](https://github.com/appium/appium/compare/@appium/opencv@2.1.2...@appium/opencv@2.1.3) (2023-08-21)
|
||||
|
||||
**Note:** Version bump only for package @appium/opencv
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.2](https://github.com/appium/appium/compare/@appium/opencv@2.1.1...@appium/opencv@2.1.2) (2023-08-17)
|
||||
|
||||
**Note:** Version bump only for package @appium/opencv
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.1.1](https://github.com/appium/appium/compare/@appium/opencv@2.1.0...@appium/opencv@2.1.1) (2023-06-14)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/opencv",
|
||||
"version": "2.1.1",
|
||||
"version": "2.1.3",
|
||||
"description": "OpenCV-related helper library",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -45,7 +45,7 @@
|
||||
"bluebird": "3.7.2",
|
||||
"lodash": "4.17.21",
|
||||
"opencv-bindings": "4.5.5",
|
||||
"sharp": "0.32.1",
|
||||
"sharp": "0.32.5",
|
||||
"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.20](https://github.com/appium/appium/compare/@appium/plugin-test-support@0.3.19...@appium/plugin-test-support@0.3.20) (2023-08-17)
|
||||
|
||||
**Note:** Version bump only for package @appium/plugin-test-support
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.3.19](https://github.com/appium/appium/compare/@appium/plugin-test-support@0.3.18...@appium/plugin-test-support@0.3.19) (2023-07-24)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/plugin-test-support",
|
||||
"version": "0.3.19",
|
||||
"version": "0.3.20",
|
||||
"description": "Testing utilities for Appium plugins",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -41,7 +41,7 @@
|
||||
"test:unit": "exit 0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@appium/types": "^0.13.2",
|
||||
"@appium/types": "^0.13.3",
|
||||
"get-port": "5.1.1",
|
||||
"log-symbols": "4.1.0",
|
||||
"source-map-support": "0.5.21",
|
||||
|
||||
@@ -3,6 +3,29 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [4.1.5](https://github.com/appium/appium/compare/@appium/support@4.1.4...@appium/support@4.1.5) (2023-08-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **support:** update dependency archiver to v5.3.2 ([e73e47d](https://github.com/appium/appium/commit/e73e47de18ff7e327a06584121e85756506ab21d))
|
||||
|
||||
|
||||
|
||||
## [4.1.4](https://github.com/appium/appium/compare/@appium/support@4.1.3...@appium/support@4.1.4) (2023-08-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **driver-test-support:** update definitelytyped ([c320e8a](https://github.com/appium/appium/commit/c320e8a1a61cb6d980d6d944ae47b60da97aa398))
|
||||
* **support:** update dependency glob to v10 ([#18490](https://github.com/appium/appium/issues/18490)) ([aaf31a5](https://github.com/appium/appium/commit/aaf31a577cb0b9cbe22646dcd888dc393a03aa11))
|
||||
* **support:** update dependency plist to v3.1.0 ([f9ba313](https://github.com/appium/appium/commit/f9ba31383ad2c97f8dc5999c8a28e6bc6345b192))
|
||||
* **support:** update dependency semver to v7.5.4 ([03ddcdf](https://github.com/appium/appium/commit/03ddcdfcafbccf6698868a272e499cbdac41d791))
|
||||
* **test-support:** update dependency @colors/colors to v1.6.0 ([1358937](https://github.com/appium/appium/commit/1358937db2edf08ce1ebe3dff2f70ac6b07cd373))
|
||||
* **types:** update dependency type-fest to v3.13.1 ([fb34ab9](https://github.com/appium/appium/commit/fb34ab917216121d2b554677a12f07a03393d218))
|
||||
|
||||
|
||||
|
||||
## [4.1.3](https://github.com/appium/appium/compare/@appium/support@4.1.2...@appium/support@4.1.3) (2023-07-24)
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import {
|
||||
rmSync,
|
||||
open,
|
||||
} from 'fs';
|
||||
import glob from 'glob';
|
||||
import { glob } from 'glob';
|
||||
import klaw from 'klaw';
|
||||
import _ from 'lodash';
|
||||
import mv from 'mv';
|
||||
@@ -158,7 +158,9 @@ const fs = {
|
||||
* Given a glob pattern, resolve with list of files matching that pattern
|
||||
* @see https://github.com/isaacs/node-glob
|
||||
*/
|
||||
glob: /** @type {(pattern: string, opts?: glob.IOptions) => B<string[]>} */ (B.promisify(glob)),
|
||||
glob: /** @type {(pattern: string, opts?: import('glob').GlobOptions) => B<string[]>} */ (
|
||||
(pattern, options) => B.resolve(options ? glob(pattern, options) : glob(pattern))
|
||||
),
|
||||
|
||||
/**
|
||||
* Sanitize a filename
|
||||
|
||||
@@ -138,6 +138,7 @@ class ZipExtractor {
|
||||
const openReadStream = B.promisify(this.zipfile.openReadStream.bind(this.zipfile));
|
||||
const readStream = await openReadStream(entry);
|
||||
if (isSymlink) {
|
||||
// @ts-ignore This typecast is ok
|
||||
const link = await getStream(readStream);
|
||||
await fs.symlink(link, dest);
|
||||
} else {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/support",
|
||||
"version": "4.1.3",
|
||||
"version": "4.1.5",
|
||||
"description": "Support libs used across appium packages",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -42,26 +42,25 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@appium/tsconfig": "^0.3.0",
|
||||
"@appium/types": "^0.13.2",
|
||||
"@colors/colors": "1.5.0",
|
||||
"@appium/types": "^0.13.3",
|
||||
"@colors/colors": "1.6.0",
|
||||
"@types/archiver": "5.3.2",
|
||||
"@types/base64-stream": "1.0.2",
|
||||
"@types/find-root": "1.1.2",
|
||||
"@types/glob": "8.1.0",
|
||||
"@types/jsftp": "2.1.2",
|
||||
"@types/klaw": "3.0.3",
|
||||
"@types/lockfile": "1.0.2",
|
||||
"@types/mv": "2.1.2",
|
||||
"@types/ncp": "2.0.5",
|
||||
"@types/npmlog": "4.1.4",
|
||||
"@types/pluralize": "0.0.29",
|
||||
"@types/pluralize": "0.0.30",
|
||||
"@types/semver": "7.5.0",
|
||||
"@types/shell-quote": "1.7.1",
|
||||
"@types/supports-color": "8.1.1",
|
||||
"@types/teen_process": "2.0.0",
|
||||
"@types/uuid": "9.0.2",
|
||||
"@types/which": "3.0.0",
|
||||
"archiver": "5.3.1",
|
||||
"archiver": "5.3.2",
|
||||
"axios": "1.4.0",
|
||||
"base64-stream": "1.0.0",
|
||||
"bluebird": "3.7.2",
|
||||
@@ -69,7 +68,7 @@
|
||||
"bplist-parser": "0.3.2",
|
||||
"form-data": "4.0.0",
|
||||
"get-stream": "6.0.1",
|
||||
"glob": "8.1.0",
|
||||
"glob": "10.3.3",
|
||||
"jsftp": "2.1.3",
|
||||
"klaw": "4.1.0",
|
||||
"lockfile": "1.0.4",
|
||||
@@ -81,23 +80,23 @@
|
||||
"npmlog": "7.0.1",
|
||||
"opencv-bindings": "4.5.5",
|
||||
"pkg-dir": "5.0.0",
|
||||
"plist": "3.0.6",
|
||||
"plist": "3.1.0",
|
||||
"pluralize": "8.0.0",
|
||||
"read-pkg": "5.2.0",
|
||||
"resolve-from": "5.0.0",
|
||||
"sanitize-filename": "1.6.3",
|
||||
"semver": "7.5.3",
|
||||
"semver": "7.5.4",
|
||||
"shell-quote": "1.8.1",
|
||||
"source-map-support": "0.5.21",
|
||||
"supports-color": "8.1.1",
|
||||
"teen_process": "2.0.4",
|
||||
"type-fest": "3.11.1",
|
||||
"type-fest": "3.13.1",
|
||||
"uuid": "9.0.0",
|
||||
"which": "3.0.1",
|
||||
"yauzl": "2.10.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"sharp": "0.32.1"
|
||||
"sharp": "0.32.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
|
||||
|
||||
@@ -3,6 +3,24 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [3.0.23](https://github.com/appium/appium/compare/@appium/test-support@3.0.22...@appium/test-support@3.0.23) (2023-08-21)
|
||||
|
||||
**Note:** Version bump only for package @appium/test-support
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [3.0.22](https://github.com/appium/appium/compare/@appium/test-support@3.0.21...@appium/test-support@3.0.22) (2023-08-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **test-support:** update dependency @colors/colors to v1.6.0 ([1358937](https://github.com/appium/appium/commit/1358937db2edf08ce1ebe3dff2f70ac6b07cd373))
|
||||
* **test-support:** update dependency sinon to v15.2.0 ([a21ae6a](https://github.com/appium/appium/commit/a21ae6ab2bcaba44ecdacae67076cf011b4e5ae8))
|
||||
|
||||
|
||||
|
||||
## [3.0.21](https://github.com/appium/appium/compare/@appium/test-support@3.0.20...@appium/test-support@3.0.21) (2023-07-24)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/test-support",
|
||||
"version": "3.0.21",
|
||||
"version": "3.0.23",
|
||||
"description": "A collection of test utilities used across Appium packages",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -45,12 +45,12 @@
|
||||
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@appium/support": "^4.1.3",
|
||||
"@colors/colors": "1.5.0",
|
||||
"@appium/support": "^4.1.5",
|
||||
"@colors/colors": "1.6.0",
|
||||
"bluebird": "3.7.2",
|
||||
"lodash": "4.17.21",
|
||||
"loud-rejection": "2.2.0",
|
||||
"sinon": "15.1.2",
|
||||
"sinon": "15.2.0",
|
||||
"source-map-support": "0.5.21"
|
||||
},
|
||||
"engines": {
|
||||
|
||||
@@ -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.
|
||||
|
||||
## [0.6.6](https://github.com/appium/appium/compare/@appium/typedoc-plugin-appium@0.6.5...@appium/typedoc-plugin-appium@0.6.6) (2023-08-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **typedoc-plugin-appium:** update dependency handlebars to v4.7.8 ([#18947](https://github.com/appium/appium/issues/18947)) ([a888e26](https://github.com/appium/appium/commit/a888e263317839cecbc2cb42e183d190e136624d))
|
||||
* **types:** update dependency type-fest to v3.13.1 ([fb34ab9](https://github.com/appium/appium/commit/fb34ab917216121d2b554677a12f07a03393d218))
|
||||
|
||||
|
||||
|
||||
## [0.6.5](https://github.com/appium/appium/compare/@appium/typedoc-plugin-appium@0.6.4...@appium/typedoc-plugin-appium@0.6.5) (2023-06-14)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/typedoc-plugin-appium",
|
||||
"version": "0.6.5",
|
||||
"version": "0.6.6",
|
||||
"description": "TypeDoc plugin for Appium & its extensions",
|
||||
"homepage": "https://appium.io",
|
||||
"license": "Apache-2.0",
|
||||
@@ -60,10 +60,10 @@
|
||||
"typescript": "^4.7.0 || ^5.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"handlebars": "4.7.7",
|
||||
"handlebars": "4.7.8",
|
||||
"lodash": "4.17.21",
|
||||
"pluralize": "8.0.0",
|
||||
"type-fest": "3.11.1"
|
||||
"type-fest": "3.13.1"
|
||||
},
|
||||
"gitHead": "8480a85ce2fa466360e0fb1a7f66628331907f02"
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
## [0.13.3](https://github.com/appium/appium/compare/@appium/types@0.13.2...@appium/types@0.13.3) (2023-08-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **types:** update dependency type-fest to v3.13.1 ([fb34ab9](https://github.com/appium/appium/commit/fb34ab917216121d2b554677a12f07a03393d218))
|
||||
|
||||
|
||||
|
||||
## [0.13.2](https://github.com/appium/appium/compare/@appium/types@0.13.1...@appium/types@0.13.2) (2023-07-03)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/types",
|
||||
"version": "0.13.2",
|
||||
"version": "0.13.3",
|
||||
"description": "Various type declarations used across Appium",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -43,7 +43,7 @@
|
||||
"@types/express": "4.17.17",
|
||||
"@types/npmlog": "4.1.4",
|
||||
"@types/ws": "8.5.5",
|
||||
"type-fest": "3.11.1"
|
||||
"type-fest": "3.13.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
|
||||
|
||||
@@ -3,6 +3,26 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [1.0.11](https://github.com/appium/appium-plugins/compare/@appium/universal-xml-plugin@1.0.10...@appium/universal-xml-plugin@1.0.11) (2023-08-21)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **universal-xml-plugin:** update dependency xpath to v0.0.33 ([#18952](https://github.com/appium/appium-plugins/issues/18952)) ([f2cff24](https://github.com/appium/appium-plugins/commit/f2cff24685e96578f17549454de7b7931c13df83))
|
||||
|
||||
|
||||
|
||||
## [1.0.10](https://github.com/appium/appium-plugins/compare/@appium/universal-xml-plugin@1.0.9...@appium/universal-xml-plugin@1.0.10) (2023-08-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **universal-xml-plugin:** actually export plugin ([#18985](https://github.com/appium/appium-plugins/issues/18985)) ([c933732](https://github.com/appium/appium-plugins/commit/c933732089a69658b864d9cf6b12c61b46619dd9))
|
||||
* **universal-xml-plugin:** update dependency @xmldom/xmldom to v0.8.10 ([#18949](https://github.com/appium/appium-plugins/issues/18949)) ([12147d5](https://github.com/appium/appium-plugins/commit/12147d518fc3ac86b01c3401b9e462b5dca99ca4))
|
||||
* **universal-xml-plugin:** update dependency fast-xml-parser to v4 ([#16781](https://github.com/appium/appium-plugins/issues/16781)) ([fc01fb9](https://github.com/appium/appium-plugins/commit/fc01fb958a4e22c8c56ba6daf5a0e8a48538c4aa))
|
||||
|
||||
|
||||
|
||||
## [1.0.9](https://github.com/appium/appium-plugins/compare/@appium/universal-xml-plugin@1.0.8...@appium/universal-xml-plugin@1.0.9) (2023-06-14)
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
const {main} = require('./build/lib');
|
||||
const {main, UniversalXMLPlugin} = require('./build/lib');
|
||||
|
||||
if (require.main === module) {
|
||||
main();
|
||||
}
|
||||
|
||||
export {UniversalXMLPlugin};
|
||||
|
||||
@@ -1,43 +1,60 @@
|
||||
import _ from 'lodash';
|
||||
import parser, {j2xParser} from 'fast-xml-parser';
|
||||
import {XMLParser, XMLBuilder} from 'fast-xml-parser';
|
||||
import NODE_MAP from './node-map';
|
||||
import {ATTR_MAP, REMOVE_ATTRS} from './attr-map';
|
||||
import TRANSFORMS from './transformers';
|
||||
|
||||
const PARSE_OPTS = {
|
||||
ignoreAttributes: false,
|
||||
arrayMode: true,
|
||||
};
|
||||
|
||||
const GEN_OPTS = {
|
||||
ignoreAttributes: false,
|
||||
arrayMode: true,
|
||||
format: true,
|
||||
};
|
||||
|
||||
export const ATTR_PREFIX = '@_';
|
||||
export const IDX_PATH_PREFIX = `${ATTR_PREFIX}indexPath`;
|
||||
export const IDX_PREFIX = `${ATTR_PREFIX}index`;
|
||||
|
||||
const isAttr = (k) => k.substring(0, 2) === ATTR_PREFIX;
|
||||
const isNode = (k) => !isAttr(k);
|
||||
const PARSE_OPTS = {
|
||||
ignoreAttributes: false,
|
||||
ignoreDeclaration: true,
|
||||
attributeNamePrefix: ATTR_PREFIX,
|
||||
isArray: (name, jPath, isLeafNode, isAttribute) => !isAttribute,
|
||||
};
|
||||
|
||||
const GEN_OPTS = {
|
||||
ignoreAttributes: false,
|
||||
attributeNamePrefix: ATTR_PREFIX,
|
||||
allowBooleanAttributes: true,
|
||||
suppressBooleanAttributes: false,
|
||||
format: true,
|
||||
};
|
||||
|
||||
const isAttr = (/** @type {string} */ k) => k.startsWith(ATTR_PREFIX);
|
||||
const isNode = (/** @type {string} */ k) => !isAttr(k);
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} xmlStr
|
||||
* @param {string} platform
|
||||
* @param {{metadata?: Object, addIndexPath?: boolean}} opts
|
||||
* @returns {{xml: string, unknowns: NodesAndAttributes}}
|
||||
*/
|
||||
export function transformSourceXml(xmlStr, platform, {metadata = {}, addIndexPath = false} = {}) {
|
||||
// first thing we want to do is modify the ios source root node, because it doesn't include the
|
||||
// necessary index attribute, so we add it if it's not there
|
||||
xmlStr = xmlStr.replace('<AppiumAUT>', '<AppiumAUT index="0">');
|
||||
const xmlObj = parser.parse(xmlStr, PARSE_OPTS);
|
||||
const xmlObj = new XMLParser(PARSE_OPTS).parse(xmlStr);
|
||||
const unknowns = transformNode(xmlObj, platform, {
|
||||
metadata,
|
||||
addIndexPath,
|
||||
parentPath: '',
|
||||
});
|
||||
const jParser = new j2xParser(GEN_OPTS);
|
||||
let transformedXml = jParser.parse(xmlObj).trim();
|
||||
let transformedXml = new XMLBuilder(GEN_OPTS).build(xmlObj).trim();
|
||||
transformedXml = `<?xml version="1.0" encoding="UTF-8"?>\n${transformedXml}`;
|
||||
return {xml: transformedXml, unknowns};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Object} nameMap
|
||||
* @param {string} name
|
||||
* @param {string} platform
|
||||
* @returns {string | null}
|
||||
*/
|
||||
function getUniversalName(nameMap, name, platform) {
|
||||
for (const translatedName of Object.keys(nameMap)) {
|
||||
const sourceNodes = nameMap[translatedName]?.[platform];
|
||||
@@ -51,14 +68,33 @@ function getUniversalName(nameMap, name, platform) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {any} nodeName
|
||||
* @param {string} platform
|
||||
* @returns {string?}
|
||||
*/
|
||||
export function getUniversalNodeName(nodeName, platform) {
|
||||
return getUniversalName(NODE_MAP, nodeName, platform);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} attrName
|
||||
* @param {string} platform
|
||||
* @returns {string?}
|
||||
*/
|
||||
export function getUniversalAttrName(attrName, platform) {
|
||||
return getUniversalName(ATTR_MAP, attrName, platform);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {any} nodeObj
|
||||
* @param {string} platform
|
||||
* @param {{metadata?: Object, addIndexPath?: boolean, parentPath?: string}} opts
|
||||
* @returns {NodesAndAttributes}
|
||||
*/
|
||||
export function transformNode(nodeObj, platform, {metadata, addIndexPath, parentPath}) {
|
||||
const unknownNodes = [];
|
||||
const unknownAttrs = [];
|
||||
@@ -103,6 +139,14 @@ export function transformNode(nodeObj, platform, {metadata, addIndexPath, parent
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {any} nodeObj
|
||||
* @param {string[]} childNodeNames
|
||||
* @param {string} platform
|
||||
* @param {{metadata?: Object, addIndexPath?: boolean, parentPath?: string}} opts
|
||||
* @returns {NodesAndAttributes}
|
||||
*/
|
||||
export function transformChildNodes(
|
||||
nodeObj,
|
||||
childNodeNames,
|
||||
@@ -144,6 +188,13 @@ export function transformChildNodes(
|
||||
return {nodes: unknownNodes, attrs: unknownAttrs};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {any} nodeObj
|
||||
* @param {string[]} attrs
|
||||
* @param {string} platform
|
||||
* @returns {string[]}
|
||||
*/
|
||||
export function transformAttrs(nodeObj, attrs, platform) {
|
||||
const unknownAttrs = [];
|
||||
for (const attr of attrs) {
|
||||
@@ -165,3 +216,7 @@ export function transformAttrs(nodeObj, attrs, platform) {
|
||||
}
|
||||
return unknownAttrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {{nodes: string[], attrs: string[]}} NodesAndAttributes
|
||||
*/
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {select as xpathQuery} from 'xpath';
|
||||
import {DOMParser} from '@xmldom/xmldom';
|
||||
import _ from 'lodash';
|
||||
|
||||
export function runQuery(query, xmlStr) {
|
||||
const dom = new DOMParser().parseFromString(xmlStr);
|
||||
@@ -7,8 +8,18 @@ export function runQuery(query, xmlStr) {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} query
|
||||
* @param {string} xmlStr
|
||||
* @param {boolean} multiple
|
||||
* @returns {string|null}
|
||||
*/
|
||||
export function transformQuery(query, xmlStr, multiple) {
|
||||
const nodes = runQuery(query, xmlStr);
|
||||
if (!_.isArray(nodes)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const newQueries = nodes.map((node) => {
|
||||
const indexPath = getNodeAttrVal(node, 'indexPath');
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/universal-xml-plugin",
|
||||
"version": "1.0.9",
|
||||
"version": "1.0.11",
|
||||
"description": "Appium plugin for making XML source and XPath queries the same across iOS and Android",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -37,11 +37,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/xmldom": "0.1.31",
|
||||
"@xmldom/xmldom": "0.8.8",
|
||||
"fast-xml-parser": "3.21.1",
|
||||
"@xmldom/xmldom": "0.8.10",
|
||||
"fast-xml-parser": "4.2.7",
|
||||
"lodash": "4.17.21",
|
||||
"source-map-support": "0.5.21",
|
||||
"xpath": "0.0.32"
|
||||
"xpath": "0.0.33"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"appium": "^2.0.0-beta.35"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import UniversalXMLPlugin from '../../lib/plugin';
|
||||
import {UniversalXMLPlugin} from '../..';
|
||||
import BaseDriver from 'appium/driver';
|
||||
import {XML_IOS, XML_ANDROID, XML_IOS_TRANSFORMED, XML_ANDROID_TRANSFORMED} from '../fixtures';
|
||||
import {runQuery, getNodeAttrVal} from '../../lib/xpath';
|
||||
|
||||
Reference in New Issue
Block a user