mirror of
https://github.com/appium/appium.git
synced 2026-11-03 07:34:36 +08:00
Compare commits
33
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4a816efeb | ||
|
|
93bddb4c73 | ||
|
|
8627d75a47 | ||
|
|
45cd43488c | ||
|
|
c85b89ecbe | ||
|
|
1f9a625f00 | ||
|
|
b9ef676b73 | ||
|
|
66459e991e | ||
|
|
5a70d7ce78 | ||
|
|
611a63f0ae | ||
|
|
e4863778c7 | ||
|
|
0ff735598a | ||
|
|
5d705851f2 | ||
|
|
6ba5c52e98 | ||
|
|
a314166585 | ||
|
|
fe96af91f2 | ||
|
|
52ae548ddc | ||
|
|
9214c15d58 | ||
|
|
11406e4879 | ||
|
|
640e0ae30f | ||
|
|
6245022be9 | ||
|
|
91abd5b598 | ||
|
|
78bc0926db | ||
|
|
59e4367cc8 | ||
|
|
c7d9a456d8 | ||
|
|
e8590c77e7 | ||
|
|
6ae86bd5c7 | ||
|
|
a9a6b834bc | ||
|
|
297f4995f8 | ||
|
|
f42374eb6d | ||
|
|
d6c70f2f52 | ||
|
|
e35bc50454 | ||
|
|
63e28a014c |
@@ -50,7 +50,7 @@ jobs:
|
||||
node-version: [14.x, 16.x, 18.x]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3
|
||||
- name: Use Node.js ${{ matrix.node-version }}
|
||||
uses: actions/setup-node@64ed1c7eab4cce3362f8c340dee64e5eaeef8f7c # v3
|
||||
with:
|
||||
@@ -70,7 +70,7 @@ jobs:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3
|
||||
- name: Install dependencies
|
||||
uses: bahmutov/npm-install@1a235c31658a322a3b024444759650ee6345c26d # tag=v1
|
||||
with:
|
||||
@@ -78,7 +78,3 @@ jobs:
|
||||
install-command: npm ci
|
||||
- name: ESLint
|
||||
run: npm run lint:ci
|
||||
- name: Validate Renovate Config
|
||||
uses: rinchsan/renovate-config-validator@1ea1e8514f6a33fdd71c40b0a5fa3512b9e7b936 # tag=v0
|
||||
with:
|
||||
pattern: '{.renovaterc.json,renovate/default.json}'
|
||||
|
||||
@@ -12,7 +12,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3
|
||||
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3
|
||||
|
||||
- name: Cleanup
|
||||
run: |
|
||||
|
||||
+16
-11
@@ -1,7 +1,21 @@
|
||||
name: Build Docs
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
pull_request:
|
||||
paths:
|
||||
- '**/typedoc.json'
|
||||
- '**/tsconfig*.json'
|
||||
- '**/package*.json'
|
||||
- '**/*mkdocs*.ya?ml'
|
||||
- 'packages/docutils/requirements.txt'
|
||||
- 'packages/*/README.md'
|
||||
- 'packages/*/docs/**'
|
||||
- 'packages/*/**/*.ts'
|
||||
- 'packages/*/**/*.js'
|
||||
- '.github/workflows/docs.yml' # this file
|
||||
- '!**/test/**'
|
||||
- '!**/sample-code/**'
|
||||
push:
|
||||
paths:
|
||||
- '**/typedoc.json'
|
||||
- '**/tsconfig*.json'
|
||||
@@ -16,16 +30,12 @@ on:
|
||||
- '!**/test/**'
|
||||
- '!**/sample-code/**'
|
||||
|
||||
branches: [master]
|
||||
|
||||
concurrency: preview-${{ github.ref }}
|
||||
|
||||
jobs:
|
||||
docs:
|
||||
name: Docs
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3
|
||||
- name: Install dependencies (Node.js)
|
||||
uses: bahmutov/npm-install@1a235c31658a322a3b024444759650ee6345c26d # tag=v1
|
||||
with:
|
||||
@@ -39,8 +49,3 @@ jobs:
|
||||
git config --local user.name "github-actions[bot]"
|
||||
- name: Build Docs
|
||||
run: npm run docs:preview
|
||||
- name: Deploy Preview
|
||||
uses: rossjrw/pr-preview-action@2a652922e9b9c53e7e5ea62fa38da744de09043c # v1
|
||||
with:
|
||||
source-dir: ./packages/appium/docs/site
|
||||
custom-url: 'appium.github.io/appium'
|
||||
|
||||
@@ -11,7 +11,7 @@ jobs:
|
||||
name: Run FOSSA Analysis
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8f4b7f84864484a7bf31766abe9204da3cbe65b3 # v3
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3
|
||||
with:
|
||||
ref: master
|
||||
- name: Install dependencies
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
name: Validate Renovate Configs
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/renovate.yml' # this file
|
||||
- '.renovaterc.json'
|
||||
- 'renovate/default.json'
|
||||
pull_request:
|
||||
paths:
|
||||
- '.github/workflows/renovate.yml' # this file
|
||||
- '.renovaterc.json'
|
||||
- 'renovate/default.json'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
renovate:
|
||||
name: Check Renovate Configs
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3
|
||||
- name: Validate Renovate Config
|
||||
uses: rinchsan/renovate-config-validator@1ea1e8514f6a33fdd71c40b0a5fa3512b9e7b936 # tag=v0
|
||||
with:
|
||||
pattern: '{.renovaterc.json,renovate/default.json}'
|
||||
+17
-5
@@ -17,9 +17,12 @@ module.exports = (wallaby) => {
|
||||
},
|
||||
files: [
|
||||
'./packages/*/build/**/*',
|
||||
'./packages/*/lib/**/*.{js,ts}',
|
||||
'./packages/*/test/**/*helper*.{js,ts}',
|
||||
'./packages/*/test/**/*mock*.{js,ts}',
|
||||
'./packages/*/lib/**/*.js',
|
||||
'./packages/*/lib/**/*.ts',
|
||||
'./packages/*/test/**/*helper*.js',
|
||||
'./packages/*/test/**/*helper*.ts',
|
||||
'./packages/*/test/**/*mock*.js',
|
||||
'./packages/*/test/**/*mock*.ts',
|
||||
'./packages/*/package.json',
|
||||
'./packages/*/tsconfig*.json',
|
||||
'./packages/*/test/**/fixture?(s)/**/*',
|
||||
@@ -43,12 +46,21 @@ module.exports = (wallaby) => {
|
||||
instrument: false,
|
||||
pattern: './packages/typedoc-plugin-appium/lib/theme/resources/**',
|
||||
},
|
||||
{
|
||||
instrument: false,
|
||||
pattern: './packages/*/test/**/__snapshots__/**/*',
|
||||
},
|
||||
'!./packages/*/test/**/*-specs.js',
|
||||
'!./packages/*/test/**/*.e2e.spec.{js,ts}',
|
||||
'!./packages/*/test/**/*.e2e.spec.js',
|
||||
'!./packages/*/test/**/*.e2e.spec.ts',
|
||||
'!**/local_appium_home/**',
|
||||
],
|
||||
testFramework: 'mocha',
|
||||
tests: ['./packages/*/test/unit/**/*.spec.{js,ts}', '!**/local_appium_home/**'],
|
||||
tests: [
|
||||
'./packages/*/test/unit/**/*.spec.js',
|
||||
'./packages/*/test/unit/**/*.spec.ts',
|
||||
'!**/local_appium_home/**',
|
||||
],
|
||||
workers: {
|
||||
// restart: true,
|
||||
},
|
||||
|
||||
@@ -13,16 +13,16 @@ Appium is an open-source, cross-platform test automation tool for native,
|
||||
hybrid, mobile web and desktop apps. Initially created to automate iOS and Android mobile
|
||||
applications Appium has grown to a full-featured platform that provides [WebDriver](https://www.w3.org/TR/webdriver/)-based automation possibilities for the whole set of different mobile and desktop platforms.
|
||||
See the full list of
|
||||
[officially-supported](https://appium.github.io/appium/docs/en/latest/ecosystem/#drivers) and
|
||||
[third-party](https://appium.github.io/appium/docs/en/latest/ecosystem/#other-drivers) drivers for more details.
|
||||
[officially-supported](https://appium.io/docs/en/latest/ecosystem/#drivers) and
|
||||
[third-party](https://appium.io/docs/en/latest/ecosystem/#other-drivers) drivers for more details.
|
||||
|
||||
:bangbang: Major documentation revision in progress
|
||||
|
||||
:bangbang: Appium core team does not maintain Appium 1.x anymore since the 1st of January 2022. All recent versions of officially supported platform drivers are not compatible to Appium 1.x anymore, and require Appium 2 to run. [Please read the migration guide from 1.x to 2.0](https://appium.github.io/appium/docs/en/latest/guides/migrating-1-to-2/) to manage the Appium server.
|
||||
:bangbang: Appium core team does not maintain Appium 1.x anymore since the 1st of January 2022. All recent versions of officially supported platform drivers are not compatible to Appium 1.x anymore, and require Appium 2 to run. [Please read the migration guide from 1.x to 2.0](https://appium.io/docs/en/latest/guides/migrating-1-to-2/) to manage the Appium server.
|
||||
|
||||
Appium is in the final stages of a major revision (to version 2.0). As such, the documentation
|
||||
found around the web may not be correct. The current Appium 2.0 documentation is very much in
|
||||
progress. Currently, it can be found [here](https://appium.github.io/appium/docs/en/latest/).
|
||||
progress. Currently, it can be found [here](https://appium.io/docs/en/latest/).
|
||||
|
||||
### Requirements
|
||||
|
||||
@@ -71,8 +71,8 @@ appium driver uninstall xcuitest
|
||||
```
|
||||
|
||||
You can find a full list of
|
||||
[officially-supported](https://appium.github.io/appium/docs/en/latest/ecosystem/#drivers) and
|
||||
[third-party](https://appium.github.io/appium/docs/en/latest/ecosystem/#other-drivers) drivers at
|
||||
[officially-supported](https://appium.io/docs/en/latest/ecosystem/#drivers) and
|
||||
[third-party](https://appium.io/docs/en/latest/ecosystem/#other-drivers) drivers at
|
||||
the current Appium 2.0 documentation.
|
||||
|
||||
### Plugins
|
||||
@@ -104,8 +104,8 @@ appium server --use-plugins=device-farm,images
|
||||
```
|
||||
|
||||
You can find a full list of
|
||||
[officially-supported](https://appium.github.io/appium/docs/en/latest/ecosystem/#plugins) and
|
||||
[third-party](https://appium.github.io/appium/docs/en/latest/ecosystem/#other-plugins) plugins at
|
||||
[officially-supported](https://appium.io/docs/en/latest/ecosystem/#plugins) and
|
||||
[third-party](https://appium.io/docs/en/latest/ecosystem/#other-plugins) plugins at
|
||||
the current Appium 2.0 documentation.
|
||||
|
||||
|
||||
@@ -169,11 +169,11 @@ Java/Kotlin. Appium opens up the possibility of true cross-platform native app
|
||||
automation, for mobile and beyond. Finally!
|
||||
|
||||
If you're new to Appium or want a more comprehensive description of what this is all
|
||||
about, please read our [Intro to Appium](https://appium.github.io/appium/docs/en/latest/intro/).
|
||||
about, please read our [Intro to Appium](https://appium.io/docs/en/latest/intro/).
|
||||
|
||||
### Quickstart
|
||||
|
||||
Check out our [Quickstart](https://appium.github.io/appium/docs/en/latest/quickstart/) guide
|
||||
Check out our [Quickstart](https://appium.io/docs/en/latest/quickstart/) guide
|
||||
to get going with Appium.
|
||||
|
||||
There is also a sample code that contains [many examples of tests in a variety
|
||||
@@ -181,7 +181,7 @@ of different languages](https://github.com/appium/appium/tree/1.x/sample-code)!
|
||||
|
||||
### Documentation
|
||||
|
||||
For prettily-rendered docs, please visit [Appium Documentation](https://appium.github.io/appium).
|
||||
For prettily-rendered docs, please visit [Appium Documentation](https://appium.io).
|
||||
You can always find the full list of Appium doc pages at [Appium's GitHub
|
||||
Repo](https://github.com/appium/appium/tree/master/packages/appium/docs) as well.
|
||||
|
||||
@@ -196,7 +196,7 @@ Interested in where Appium is heading in the future? Check out the [Roadmap](ROA
|
||||
|
||||
### Project History, Credits & Inspiration
|
||||
|
||||
* [History](https://appium.github.io/appium/docs/en/latest/intro/history/)
|
||||
* [History](https://appium.io/docs/en/latest/intro/history/)
|
||||
|
||||
### User Forums
|
||||
|
||||
|
||||
+9
-8
@@ -1,6 +1,13 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/lerna",
|
||||
"changelogPreset": "conventional-changelog-conventionalcommits",
|
||||
"command": {
|
||||
"add": {
|
||||
"exact": true
|
||||
},
|
||||
"publish": {
|
||||
"message": "chore: publish"
|
||||
},
|
||||
"run": {
|
||||
"concurrency": 8
|
||||
},
|
||||
@@ -10,16 +17,10 @@
|
||||
"version": {
|
||||
"allowBranch": "master"
|
||||
}
|
||||
},
|
||||
"add": {
|
||||
"exact": true
|
||||
},
|
||||
"publish": {
|
||||
"message": "chore: publish"
|
||||
}
|
||||
},
|
||||
"ignoreChanges": ["**/test/**", "**/*.md"],
|
||||
"version": "independent",
|
||||
"useNx": false,
|
||||
"useWorkspaces": true,
|
||||
"useNx": false
|
||||
"version": "independent"
|
||||
}
|
||||
|
||||
Generated
+2219
-181
File diff suppressed because it is too large
Load Diff
+8
-6
@@ -85,8 +85,8 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@colors/colors": "1.5.0",
|
||||
"@commitlint/cli": "17.5.1",
|
||||
"@commitlint/config-conventional": "17.4.4",
|
||||
"@commitlint/cli": "17.6.1",
|
||||
"@commitlint/config-conventional": "17.6.1",
|
||||
"@tsconfig/node14": "1.0.3",
|
||||
"@types/chai": "4.3.4",
|
||||
"@types/chai-as-promised": "7.1.5",
|
||||
@@ -94,17 +94,18 @@
|
||||
"@types/mocha": "10.0.1",
|
||||
"@types/node": "18.15.11",
|
||||
"@types/semver": "7.3.13",
|
||||
"@types/sinon": "10.0.13",
|
||||
"@types/sinon": "10.0.14",
|
||||
"@types/sinon-chai": "3.2.9",
|
||||
"@types/teen_process": "2.0.0",
|
||||
"@types/ws": "8.5.4",
|
||||
"@types/yargs": "17.0.24",
|
||||
"@typescript-eslint/eslint-plugin": "5.57.1",
|
||||
"@typescript-eslint/parser": "5.57.1",
|
||||
"@typescript-eslint/eslint-plugin": "5.58.0",
|
||||
"@typescript-eslint/parser": "5.58.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.38.0",
|
||||
"eslint-config-prettier": "8.8.0",
|
||||
@@ -122,10 +123,11 @@
|
||||
"lerna": "6.6.1",
|
||||
"lint-staged": "13.2.1",
|
||||
"log-symbols": "4.1.0",
|
||||
"midnight-smoker": "2.0.1",
|
||||
"midnight-smoker": "2.0.3",
|
||||
"mjpeg-consumer": "2.0.0",
|
||||
"mjpeg-server": "0.3.1",
|
||||
"mocha": "10.2.0",
|
||||
"mocha-chai-jest-snapshot": "1.1.4",
|
||||
"npm-run-all": "4.1.5",
|
||||
"prettier": "2.8.7",
|
||||
"rewiremock": "3.14.5",
|
||||
|
||||
@@ -3,6 +3,39 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.0.0-beta.66](https://github.com/appium/appium/compare/appium@2.0.0-beta.65...appium@2.0.0-beta.66) (2023-04-20)
|
||||
|
||||
**Note:** Version bump only for package appium
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.0.0-beta.65](https://github.com/appium/appium/compare/appium@2.0.0-beta.64...appium@2.0.0-beta.65) (2023-04-18)
|
||||
|
||||
**Note:** Version bump only for package appium
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.0.0-beta.64](https://github.com/appium/appium/compare/appium@2.0.0-beta.63...appium@2.0.0-beta.64) (2023-04-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **support:** update dependency semver to v7.4.0 ([6ae86bd](https://github.com/appium/appium/commit/6ae86bd5c7be879a4d8852951d73eb2f68128df3))
|
||||
|
||||
|
||||
|
||||
## [2.0.0-beta.63](https://github.com/appium/appium/compare/appium@2.0.0-beta.62...appium@2.0.0-beta.63) (2023-04-12)
|
||||
|
||||
**Note:** Version bump only for package appium
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# [2.0.0-beta.62](https://github.com/appium/appium/compare/appium@2.0.0-beta.61...appium@2.0.0-beta.62) (2023-04-10)
|
||||
|
||||
|
||||
|
||||
+12
-12
@@ -13,16 +13,16 @@ Appium is an open-source, cross-platform test automation tool for native,
|
||||
hybrid, mobile web and desktop apps. Initially created to automate iOS and Android mobile
|
||||
applications Appium has grown to a full-featured platform that provides [WebDriver](https://www.w3.org/TR/webdriver/)-based automation possibilities for the whole set of different mobile and desktop platforms.
|
||||
See the full list of
|
||||
[officially-supported](https://appium.github.io/appium/docs/en/latest/ecosystem/#drivers) and
|
||||
[third-party](https://appium.github.io/appium/docs/en/latest/ecosystem/#other-drivers) drivers for more details.
|
||||
[officially-supported](https://appium.io/docs/en/latest/ecosystem/#drivers) and
|
||||
[third-party](https://appium.io/docs/en/latest/ecosystem/#other-drivers) drivers for more details.
|
||||
|
||||
:bangbang: Major documentation revision in progress
|
||||
|
||||
:bangbang: Appium core team does not maintain Appium 1.x anymore since the 1st of January 2022. All recent versions of officially supported platform drivers are not compatible to Appium 1.x anymore, and require Appium 2 to run. [Please read the migration guide from 1.x to 2.0](https://appium.github.io/appium/docs/en/latest/guides/migrating-1-to-2/) to manage the Appium server.
|
||||
:bangbang: Appium core team does not maintain Appium 1.x anymore since the 1st of January 2022. All recent versions of officially supported platform drivers are not compatible to Appium 1.x anymore, and require Appium 2 to run. [Please read the migration guide from 1.x to 2.0](https://appium.io/docs/en/latest/guides/migrating-1-to-2/) to manage the Appium server.
|
||||
|
||||
Appium is in the final stages of a major revision (to version 2.0). As such, the documentation
|
||||
found around the web may not be correct. The current Appium 2.0 documentation is very much in
|
||||
progress. Currently, it can be found [here](https://appium.github.io/appium/docs/en/latest/).
|
||||
progress. Currently, it can be found [here](https://appium.io/docs/en/latest/).
|
||||
|
||||
### Requirements
|
||||
|
||||
@@ -71,8 +71,8 @@ appium driver uninstall xcuitest
|
||||
```
|
||||
|
||||
You can find a full list of
|
||||
[officially-supported](https://appium.github.io/appium/docs/en/latest/ecosystem/#drivers) and
|
||||
[third-party](https://appium.github.io/appium/docs/en/latest/ecosystem/#other-drivers) drivers at
|
||||
[officially-supported](https://appium.io/docs/en/latest/ecosystem/#drivers) and
|
||||
[third-party](https://appium.io/docs/en/latest/ecosystem/#other-drivers) drivers at
|
||||
the current Appium 2.0 documentation.
|
||||
|
||||
### Plugins
|
||||
@@ -104,8 +104,8 @@ appium server --use-plugins=device-farm,images
|
||||
```
|
||||
|
||||
You can find a full list of
|
||||
[officially-supported](https://appium.github.io/appium/docs/en/latest/ecosystem/#plugins) and
|
||||
[third-party](https://appium.github.io/appium/docs/en/latest/ecosystem/#other-plugins) plugins at
|
||||
[officially-supported](https://appium.io/docs/en/latest/ecosystem/#plugins) and
|
||||
[third-party](https://appium.io/docs/en/latest/ecosystem/#other-plugins) plugins at
|
||||
the current Appium 2.0 documentation.
|
||||
|
||||
|
||||
@@ -169,11 +169,11 @@ Java/Kotlin. Appium opens up the possibility of true cross-platform native app
|
||||
automation, for mobile and beyond. Finally!
|
||||
|
||||
If you're new to Appium or want a more comprehensive description of what this is all
|
||||
about, please read our [Intro to Appium](https://appium.github.io/appium/docs/en/latest/intro/).
|
||||
about, please read our [Intro to Appium](https://appium.io/docs/en/latest/intro/).
|
||||
|
||||
### Quickstart
|
||||
|
||||
Check out our [Quickstart](https://appium.github.io/appium/docs/en/latest/quickstart/) guide
|
||||
Check out our [Quickstart](https://appium.io/docs/en/latest/quickstart/) guide
|
||||
to get going with Appium.
|
||||
|
||||
There is also a sample code that contains [many examples of tests in a variety
|
||||
@@ -181,7 +181,7 @@ of different languages](https://github.com/appium/appium/tree/1.x/sample-code)!
|
||||
|
||||
### Documentation
|
||||
|
||||
For prettily-rendered docs, please visit [Appium Documentation](https://appium.github.io/appium).
|
||||
For prettily-rendered docs, please visit [Appium Documentation](https://appium.io).
|
||||
You can always find the full list of Appium doc pages at [Appium's GitHub
|
||||
Repo](https://github.com/appium/appium/tree/master/packages/appium/docs) as well.
|
||||
|
||||
@@ -196,7 +196,7 @@ Interested in where Appium is heading in the future? Check out the [Roadmap](ROA
|
||||
|
||||
### Project History, Credits & Inspiration
|
||||
|
||||
* [History](https://appium.github.io/appium/docs/en/latest/intro/history/)
|
||||
* [History](https://appium.io/docs/en/latest/intro/history/)
|
||||
|
||||
### User Forums
|
||||
|
||||
|
||||
@@ -22,11 +22,11 @@ extra:
|
||||
link: https://twitter.com/AppiumDevs
|
||||
alternate:
|
||||
- name: English
|
||||
link: /appium/docs/en/
|
||||
link: /docs/en/
|
||||
lang: en
|
||||
- name: 日本
|
||||
link: /appium/docs/ja/
|
||||
link: /docs/ja/
|
||||
lang: ja
|
||||
- name: 中文简体
|
||||
link: /appium/docs/zh/
|
||||
link: /docs/zh/
|
||||
lang: zh
|
||||
|
||||
@@ -64,7 +64,7 @@ the Appium client depends on) since that is what you will use as your primary in
|
||||
|[Appium Java client](https://github.com/appium/java-client)|Java|Appium Team|
|
||||
|[Appium Python client](https://github.com/appium/python-client)|Python|Appium Team|
|
||||
|[Appium Ruby Core client](https://github.com/appium/ruby_lib_core) (Recommended)<br>[Appium Ruby client](https://github.com/appium/ruby_lib)|Ruby|Appium Team|
|
||||
|[WebDriverIO](https://webdriver.io)|Node.js|Community|
|
||||
|[WebDriverIO](https://webdriver.io)<br>[Nightwatch](https://nightwatchjs.org/)|Node.js|Community|
|
||||
|[Appium .NET client](https://github.com/appium/dotnet-client)|C#|Appium Team*|
|
||||
|[RobotFramework](https://github.com/serhatbolsu/robotframework-appiumlibrary)|DSL|Community|
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
INHERIT: ./base-mkdocs.yml
|
||||
site_url: https://appium.github.io/appium/docs/en
|
||||
site_url: https://appium.io/docs/en
|
||||
edit_uri: edit/master/packages/appium/docs/en
|
||||
site_description: The Appium automation project documentation
|
||||
docs_dir: en
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
INHERIT: ./base-mkdocs.yml
|
||||
site_url: https://appium.github.io/appium/docs/ja
|
||||
site_url: https://appium.io/docs/ja
|
||||
edit_uri: edit/master/packages/appium/docs/ja
|
||||
site_description: The Appium automation project documentation
|
||||
docs_dir: ja
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
INHERIT: ./base-mkdocs.yml
|
||||
site_url: https://appium.github.io/appium/docs/zh
|
||||
site_url: https://appium.io/docs/zh
|
||||
edit_uri: edit/master/packages/appium/docs/zh
|
||||
site_description: The Appium automation project documentation
|
||||
docs_dir: zh
|
||||
|
||||
@@ -424,7 +424,7 @@ class ExtensionCliCommand {
|
||||
* @param {ExtensionArgs} args
|
||||
* @returns {string}
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
getPostInstallText(args) {
|
||||
throw this._createFatalError('Must be implemented in final class');
|
||||
}
|
||||
@@ -505,7 +505,7 @@ class ExtensionCliCommand {
|
||||
* @param {ExtMetadata<ExtType>} extMetadata - the data in the "appium" field of `package.json` for an extension
|
||||
* @param {string} installSpec - Extension name/spec
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
validateExtensionFields(extMetadata, installSpec) {
|
||||
throw this._createFatalError('Must be implemented in final class');
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@ export class ExtensionConfig {
|
||||
* @param {ExtName<ExtType>} extName
|
||||
* @returns {Promise<string[]>}
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars,require-await
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
async getConfigWarnings(extManifest, extName) {
|
||||
return [];
|
||||
}
|
||||
@@ -421,7 +421,7 @@ export class ExtensionConfig {
|
||||
* @param {ExtName<ExtType>} extName - Extension name (from manifest)
|
||||
* @returns {ExtManifestProblem[]}
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
getGenericConfigProblems(extManifest, extName) {
|
||||
const {version, pkgName, mainClass} = extManifest;
|
||||
const problems = [];
|
||||
@@ -456,7 +456,7 @@ export class ExtensionConfig {
|
||||
* @param {ExtName<ExtType>} extName
|
||||
* @returns {ExtManifestProblem[]}
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
getConfigProblems(extManifest, extName) {
|
||||
// shoud override this method if special validation is necessary for this extension type
|
||||
return [];
|
||||
@@ -509,7 +509,7 @@ export class ExtensionConfig {
|
||||
* @param {ExtName<ExtType>[]} [activeNames]
|
||||
* @returns {void}
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
print(activeNames) {
|
||||
if (_.isEmpty(this.installedExtensions)) {
|
||||
log.info(
|
||||
@@ -534,7 +534,7 @@ export class ExtensionConfig {
|
||||
* @returns {string}
|
||||
* @abstract
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
extensionDesc(extName, extManifest) {
|
||||
throw new Error('This must be implemented in a subclass');
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import {init as logsinkInit} from './logsink'; // this import needs to come first since it sets up global npmlog
|
||||
import logger from './logger'; // logger needs to remain second
|
||||
import {routeConfiguringFunction as makeRouter, server as baseServer} from '@appium/base-driver';
|
||||
import {logger as logFactory, util, env} from '@appium/support';
|
||||
import {logger as logFactory, util, env, fs} from '@appium/support';
|
||||
import {asyncify} from 'asyncbox';
|
||||
import _ from 'lodash';
|
||||
import {AppiumDriver} from './appium';
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
isPluginCommandArgs,
|
||||
isServerCommandArgs,
|
||||
} from './utils';
|
||||
import os from 'node:os';
|
||||
|
||||
const {resolveAppiumHome} = env;
|
||||
|
||||
@@ -138,6 +139,52 @@ function getExtraMethodMap(driverClasses, pluginClasses) {
|
||||
{}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares and validates appium home path folder
|
||||
*
|
||||
* @param {string} name The name of the appium home source (needed for error messages)
|
||||
* @param {string} appiumHome The actual value to be verified
|
||||
* @returns {Promise<string>} Same appiumHome value
|
||||
* @throws {Error} If the validation has failed
|
||||
*/
|
||||
async function prepareAppiumHome(name, appiumHome) {
|
||||
let stat;
|
||||
try {
|
||||
stat = await fs.stat(appiumHome);
|
||||
} catch (e) {
|
||||
let err = e;
|
||||
if (e.code === 'ENOENT') {
|
||||
try {
|
||||
await fs.mkdir(appiumHome, {recursive: true});
|
||||
return appiumHome;
|
||||
} catch (e1) {
|
||||
err = e1;
|
||||
}
|
||||
}
|
||||
throw new Error(
|
||||
`The path '${appiumHome}' provided in the ${name} must point ` +
|
||||
`to a valid folder writeable for the current user account '${os.userInfo().username}'. ` +
|
||||
`Original error: ${err.message}`
|
||||
);
|
||||
}
|
||||
if (!stat.isDirectory()) {
|
||||
throw new Error(
|
||||
`The path '${appiumHome}' provided in the ${name} must point to a valid folder`
|
||||
);
|
||||
}
|
||||
try {
|
||||
await fs.access(appiumHome, fs.constants.W_OK);
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
`The folder path '${appiumHome}' provided in the ${name} must be ` +
|
||||
`writeable for the current user account '${os.userInfo().username}. ` +
|
||||
`Original error: ${e.message}`
|
||||
);
|
||||
}
|
||||
return appiumHome;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes Appium, but does not start the server.
|
||||
*
|
||||
@@ -157,6 +204,13 @@ function getExtraMethodMap(driverClasses, pluginClasses) {
|
||||
*/
|
||||
async function init(args) {
|
||||
const appiumHome = args?.appiumHome ?? (await resolveAppiumHome());
|
||||
let appiumHomeSourceName = 'autodetected appium home path';
|
||||
if (!_.isNil(args?.appiumHome)) {
|
||||
appiumHomeSourceName = 'appiumHome config value';
|
||||
} else if (process.env.APPIUM_HOME) {
|
||||
appiumHomeSourceName = 'APPIUM_HOME environment variable';
|
||||
}
|
||||
await prepareAppiumHome(appiumHomeSourceName, appiumHome);
|
||||
|
||||
adjustNodePath();
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ export class RoachHotelMap extends Map {
|
||||
/**
|
||||
* @param {K} key
|
||||
*/
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
delete(key) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "appium",
|
||||
"version": "2.0.0-beta.62",
|
||||
"version": "2.0.0-beta.66",
|
||||
"description": "Automation for Apps.",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -60,12 +60,12 @@
|
||||
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@appium/base-driver": "^9.3.6",
|
||||
"@appium/base-plugin": "^2.2.6",
|
||||
"@appium/docutils": "^0.3.5",
|
||||
"@appium/base-driver": "^9.3.7",
|
||||
"@appium/base-plugin": "^2.2.7",
|
||||
"@appium/docutils": "^0.3.9",
|
||||
"@appium/schema": "^0.2.6",
|
||||
"@appium/support": "^3.1.10",
|
||||
"@appium/types": "^0.10.4",
|
||||
"@appium/support": "^3.1.11",
|
||||
"@appium/types": "^0.11.0",
|
||||
"@sidvind/better-ajv-errors": "2.1.0",
|
||||
"@types/argparse": "2.0.10",
|
||||
"@types/bluebird": "3.5.38",
|
||||
@@ -89,7 +89,7 @@
|
||||
"ora": "5.4.1",
|
||||
"package-changed": "3.0.0",
|
||||
"resolve-from": "5.0.0",
|
||||
"semver": "7.3.8",
|
||||
"semver": "7.4.0",
|
||||
"source-map-support": "0.5.21",
|
||||
"teen_process": "2.0.2",
|
||||
"type-fest": "3.8.0",
|
||||
|
||||
@@ -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.
|
||||
|
||||
## [9.3.7](https://github.com/appium/appium/compare/@appium/base-driver@9.3.6...@appium/base-driver@9.3.7) (2023-04-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **basedriver:** allow arbitrary session data to be returned by getSession ([6245022](https://github.com/appium/appium/commit/6245022be953b69acad70d0a4c877bc65eed2d3a))
|
||||
|
||||
|
||||
|
||||
## [9.3.6](https://github.com/appium/appium/compare/@appium/base-driver@9.3.5...@appium/base-driver@9.3.6) (2023-04-10)
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import './event';
|
||||
import './find';
|
||||
import './log';
|
||||
import './session';
|
||||
import './settings';
|
||||
import './timeout';
|
||||
import './execute';
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
import {Constraints, ISessionCommands, MultiSessionData, SingularSessionData} from '@appium/types';
|
||||
import {BaseDriver} from '../driver';
|
||||
import {mixin} from './mixin';
|
||||
|
||||
declare module '../driver' {
|
||||
interface BaseDriver<
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
C extends Constraints
|
||||
> extends ISessionCommands {}
|
||||
}
|
||||
|
||||
const SessionCommands: ISessionCommands = {
|
||||
async getSessions<C extends Constraints>(this: BaseDriver<C>) {
|
||||
const ret: MultiSessionData<C>[] = [];
|
||||
|
||||
if (this.sessionId) {
|
||||
ret.push({
|
||||
id: this.sessionId,
|
||||
capabilities: this.caps,
|
||||
});
|
||||
}
|
||||
|
||||
return ret;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns capabilities for the session and event history (if applicable)
|
||||
*/
|
||||
async getSession<C extends Constraints>(this: BaseDriver<C>) {
|
||||
return <SingularSessionData<C>>(
|
||||
(this.caps.eventTimings ? {...this.caps, events: this.eventHistory} : this.caps)
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
mixin(SessionCommands);
|
||||
@@ -17,7 +17,9 @@ import {
|
||||
DriverCaps,
|
||||
DriverData,
|
||||
DriverOpts,
|
||||
MultiSessionData,
|
||||
ServerArgs,
|
||||
SingularSessionData,
|
||||
StringRecord,
|
||||
W3CDriverCaps,
|
||||
} from '@appium/types';
|
||||
@@ -31,7 +33,8 @@ const ON_UNEXPECTED_SHUTDOWN_EVENT = 'onUnexpectedShutdown';
|
||||
export class BaseDriver<
|
||||
C extends Constraints,
|
||||
CArgs extends StringRecord = StringRecord,
|
||||
Settings extends StringRecord = StringRecord
|
||||
Settings extends StringRecord = StringRecord,
|
||||
SessionData extends StringRecord = StringRecord
|
||||
>
|
||||
extends DriverCore<C, Settings>
|
||||
implements Driver<C, CArgs>
|
||||
@@ -310,6 +313,25 @@ export class BaseDriver<
|
||||
|
||||
return [this.sessionId, caps];
|
||||
}
|
||||
async getSessions() {
|
||||
const ret: MultiSessionData<C>[] = [];
|
||||
|
||||
if (this.sessionId) {
|
||||
ret.push({
|
||||
id: this.sessionId,
|
||||
capabilities: this.caps,
|
||||
});
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns capabilities for the session and event history (if applicable)
|
||||
*/
|
||||
async getSession() {
|
||||
return this.caps.eventTimings ? {...this.caps, events: this.eventHistory} : this.caps;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
async deleteSession(sessionId?: string | null) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/base-driver",
|
||||
"version": "9.3.6",
|
||||
"version": "9.3.7",
|
||||
"description": "Base driver class for Appium drivers",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -44,8 +44,8 @@
|
||||
"test:types": "tsd"
|
||||
},
|
||||
"dependencies": {
|
||||
"@appium/support": "^3.1.10",
|
||||
"@appium/types": "^0.10.4",
|
||||
"@appium/support": "^3.1.11",
|
||||
"@appium/types": "^0.11.0",
|
||||
"@colors/colors": "1.5.0",
|
||||
"@types/async-lock": "1.4.0",
|
||||
"@types/bluebird": "3.5.38",
|
||||
|
||||
@@ -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.2.7](https://github.com/appium/appium/compare/@appium/base-plugin@2.2.6...@appium/base-plugin@2.2.7) (2023-04-14)
|
||||
|
||||
**Note:** Version bump only for package @appium/base-plugin
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.2.6](https://github.com/appium/appium/compare/@appium/base-plugin@2.2.5...@appium/base-plugin@2.2.6) (2023-04-10)
|
||||
|
||||
**Note:** Version bump only for package @appium/base-plugin
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# Appium Base Plugin
|
||||
|
||||
The base class used to create Appium plugins. This plugin should not be installed directly as it does nothing. Instead, you extend this plugin when creating your *own* Appium plugins. Check out the [Building Plugins](https://appium.github.io/appium/docs/en/latest/ecosystem/build-plugins/) to learn how to make use of this base class to develop Appium plugins.
|
||||
The base class used to create Appium plugins. This plugin should not be installed directly as it does nothing. Instead, you extend this plugin when creating your *own* Appium plugins. Check out the [Building Plugins](https://appium.io/docs/en/latest/ecosystem/build-plugins/) to learn how to make use of this base class to develop Appium plugins.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/base-plugin",
|
||||
"version": "2.2.6",
|
||||
"version": "2.2.7",
|
||||
"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.6",
|
||||
"@appium/support": "^3.1.10"
|
||||
"@appium/base-driver": "^9.3.7",
|
||||
"@appium/support": "^3.1.11"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.17.0 || ^16.13.0 || >=18.0.0",
|
||||
|
||||
@@ -3,6 +3,23 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [2.0.14](https://github.com/appium/appium/compare/@appium/doctor@2.0.13...@appium/doctor@2.0.14) (2023-04-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **doctor:** update dependency appium-adb to v9.11.1 ([45cd434](https://github.com/appium/appium/commit/45cd43488ce3e7a3c32864912d8fb104934f90d8))
|
||||
|
||||
|
||||
|
||||
## [2.0.13](https://github.com/appium/appium/compare/@appium/doctor@2.0.12...@appium/doctor@2.0.13) (2023-04-14)
|
||||
|
||||
**Note:** Version bump only for package @appium/doctor
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [2.0.12](https://github.com/appium/appium/compare/@appium/doctor@2.0.11...@appium/doctor@2.0.12) (2023-04-10)
|
||||
|
||||
**Note:** Version bump only for package @appium/doctor
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/doctor",
|
||||
"version": "2.0.12",
|
||||
"version": "2.0.14",
|
||||
"description": "Test environment for fitness to run Appium",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -44,11 +44,11 @@
|
||||
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
|
||||
},
|
||||
"dependencies": {
|
||||
"@appium/support": "^3.1.10",
|
||||
"@appium/support": "^3.1.11",
|
||||
"@colors/colors": "1.5.0",
|
||||
"@types/bluebird": "3.5.38",
|
||||
"@types/teen_process": "2.0.0",
|
||||
"appium-adb": "9.11.0",
|
||||
"appium-adb": "9.11.1",
|
||||
"bluebird": "3.7.2",
|
||||
"inquirer": "8.2.5",
|
||||
"lodash": "4.17.21",
|
||||
|
||||
@@ -3,6 +3,40 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [0.3.9](https://github.com/appium/appium/compare/@appium/docutils@0.3.8...@appium/docutils@0.3.9) (2023-04-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **docutils:** do not bail when no site_dir found ([c85b89e](https://github.com/appium/appium/commit/c85b89ecbe28f2fd720d73fca7cd11f283eb9a0a))
|
||||
|
||||
|
||||
|
||||
## [0.3.8](https://github.com/appium/appium/compare/@appium/docutils@0.3.7...@appium/docutils@0.3.8) (2023-04-18)
|
||||
|
||||
**Note:** Version bump only for package @appium/docutils
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.3.7](https://github.com/appium/appium/compare/@appium/docutils@0.3.6...@appium/docutils@0.3.7) (2023-04-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **support:** update dependency semver to v7.4.0 ([6ae86bd](https://github.com/appium/appium/commit/6ae86bd5c7be879a4d8852951d73eb2f68128df3))
|
||||
|
||||
|
||||
|
||||
## [0.3.6](https://github.com/appium/appium/compare/@appium/docutils@0.3.5...@appium/docutils@0.3.6) (2023-04-12)
|
||||
|
||||
**Note:** Version bump only for package @appium/docutils
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.3.5](https://github.com/appium/appium/compare/@appium/docutils@0.3.4...@appium/docutils@0.3.5) (2023-04-10)
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
import path from 'node:path';
|
||||
import {exec, TeenProcessExecOptions} from 'teen_process';
|
||||
import {NAME_BIN, NAME_MKDOCS_YML, NAME_THEME} from '../constants';
|
||||
import {DEFAULT_SITE_DIR, NAME_BIN, NAME_MKDOCS_YML, NAME_THEME} from '../constants';
|
||||
import {DocutilsError} from '../error';
|
||||
import {findMkDocsYml, readMkDocsYml, whichMkDocs} from '../fs';
|
||||
import {getLogger} from '../logger';
|
||||
@@ -80,17 +80,26 @@ export async function buildSite({
|
||||
// unsure about how SIGHUP is handled here
|
||||
await doServe(mkdocsArgs, serveOpts);
|
||||
} else {
|
||||
log.info('Building site into %s (%dms)');
|
||||
log.info('Building site...');
|
||||
await doBuild(mkdocsArgs, execOpts);
|
||||
let relSiteDir;
|
||||
if (siteDir) {
|
||||
relSiteDir = relative(cwd, siteDir);
|
||||
} else {
|
||||
({site_dir: siteDir} = await readMkDocsYml(mkDocsYmlPath));
|
||||
log.debug('Found site_dir %s', siteDir);
|
||||
relSiteDir = relative(path.dirname(mkDocsYmlPath), siteDir!);
|
||||
if (siteDir) {
|
||||
log.debug('Found site_dir %s', siteDir);
|
||||
relSiteDir = relative(path.dirname(mkDocsYmlPath), siteDir);
|
||||
} else {
|
||||
log.warn(
|
||||
'No site_dir specified in args or %s; using default site_dir: %s',
|
||||
NAME_MKDOCS_YML,
|
||||
DEFAULT_SITE_DIR
|
||||
);
|
||||
relSiteDir = relative(cwd, DEFAULT_SITE_DIR);
|
||||
}
|
||||
}
|
||||
log.success('Finnished building site into %s (%dms)', relSiteDir, stop());
|
||||
log.success('Finished building site into %s (%dms)', relSiteDir, stop());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -153,3 +153,8 @@ export const LogLevelMap = {
|
||||
* Default site nav header text
|
||||
*/
|
||||
export const DEFAULT_NAV_HEADER = 'Reference';
|
||||
|
||||
/**
|
||||
* If the user does not specify a site directory _and_ the `mkdocs.yml` doesn't either, use this dir.
|
||||
*/
|
||||
export const DEFAULT_SITE_DIR = 'site';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/docutils",
|
||||
"version": "0.3.5",
|
||||
"version": "0.3.9",
|
||||
"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": "^3.1.10",
|
||||
"@appium/support": "^3.1.11",
|
||||
"@appium/tsconfig": "^0.3.0",
|
||||
"@appium/typedoc-plugin-appium": "^0.6.1",
|
||||
"@appium/typedoc-plugin-appium": "^0.6.3",
|
||||
"@sliphua/lilconfig-ts-loader": "3.2.2",
|
||||
"chalk": "4.1.2",
|
||||
"consola": "2.15.3",
|
||||
@@ -64,7 +64,7 @@
|
||||
"log-symbols": "4.1.0",
|
||||
"pkg-dir": "5.0.0",
|
||||
"read-pkg": "5.2.0",
|
||||
"semver": "7.3.8",
|
||||
"semver": "7.4.0",
|
||||
"source-map-support": "0.5.21",
|
||||
"teen_process": "2.0.2",
|
||||
"type-fest": "3.8.0",
|
||||
|
||||
@@ -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.4.5](https://github.com/appium/appium/compare/@appium/driver-test-support@0.4.4...@appium/driver-test-support@0.4.5) (2023-04-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **driver-test-support:** update dependency @types/lodash to v4.14.194 ([78bc092](https://github.com/appium/appium/commit/78bc0926db83f586db4683b008737b6254ec6ebe))
|
||||
|
||||
|
||||
|
||||
## [0.4.4](https://github.com/appium/appium/compare/@appium/driver-test-support@0.4.3...@appium/driver-test-support@0.4.4) (2023-04-10)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/driver-test-support",
|
||||
"version": "0.4.4",
|
||||
"version": "0.4.5",
|
||||
"description": "Test utilities for Appium drivers",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -41,8 +41,8 @@
|
||||
},
|
||||
"types": "./build/lib/index.d.ts",
|
||||
"dependencies": {
|
||||
"@appium/types": "^0.10.4",
|
||||
"@types/lodash": "4.14.192",
|
||||
"@appium/types": "^0.11.0",
|
||||
"@types/lodash": "4.14.194",
|
||||
"@types/stoppable": "1.1.1",
|
||||
"axios": "1.3.5",
|
||||
"bluebird": "3.7.2",
|
||||
|
||||
@@ -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.12](https://github.com/appium/appium/compare/@appium/execute-driver-plugin@3.0.11...@appium/execute-driver-plugin@3.0.12) (2023-04-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **execute-driver-plugin:** update dependency vm2 to v3.9.16 ([d6c70f2](https://github.com/appium/appium/commit/d6c70f2f526af4d91e6c2de940bbfa3208a7ffa4))
|
||||
|
||||
|
||||
|
||||
## [3.0.11](https://github.com/appium/appium/compare/@appium/execute-driver-plugin@3.0.10...@appium/execute-driver-plugin@3.0.11) (2023-04-10)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/execute-driver-plugin",
|
||||
"version": "3.0.11",
|
||||
"version": "3.0.12",
|
||||
"description": "Plugin for batching and executing driver commands with Appiums",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -42,7 +42,7 @@
|
||||
"bluebird": "3.7.2",
|
||||
"lodash": "4.17.21",
|
||||
"source-map-support": "0.5.21",
|
||||
"vm2": "3.9.15",
|
||||
"vm2": "3.9.16",
|
||||
"webdriverio": "7.30.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
@@ -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.11](https://github.com/appium/appium/compare/@appium/fake-plugin@3.1.10...@appium/fake-plugin@3.1.11) (2023-04-14)
|
||||
|
||||
**Note:** Version bump only for package @appium/fake-plugin
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [3.1.10](https://github.com/appium/appium/compare/@appium/fake-plugin@3.1.9...@appium/fake-plugin@3.1.10) (2023-04-10)
|
||||
|
||||
**Note:** Version bump only for package @appium/fake-plugin
|
||||
|
||||
@@ -59,7 +59,7 @@ class FakePlugin extends BasePlugin {
|
||||
FakePlugin._unexpectedData = null;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars,require-await
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars,require-await
|
||||
static async updateServer(expressApp, httpServer, cliArgs) {
|
||||
expressApp.all('/fake', FakePlugin.fakeRoute);
|
||||
expressApp.all('/unexpected', FakePlugin.unexpectedData);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/fake-plugin",
|
||||
"version": "3.1.10",
|
||||
"version": "3.1.11",
|
||||
"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.6",
|
||||
"@appium/support": "^3.1.10",
|
||||
"@appium/base-plugin": "^2.2.7",
|
||||
"@appium/support": "^3.1.11",
|
||||
"@types/bluebird": "3.5.38",
|
||||
"bluebird": "3.7.2",
|
||||
"lodash": "4.17.21",
|
||||
|
||||
@@ -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.13](https://github.com/appium/appium/compare/@appium/plugin-test-support@0.3.12...@appium/plugin-test-support@0.3.13) (2023-04-14)
|
||||
|
||||
**Note:** Version bump only for package @appium/plugin-test-support
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [0.3.12](https://github.com/appium/appium/compare/@appium/plugin-test-support@0.3.11...@appium/plugin-test-support@0.3.12) (2023-04-10)
|
||||
|
||||
**Note:** Version bump only for package @appium/plugin-test-support
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/plugin-test-support",
|
||||
"version": "0.3.12",
|
||||
"version": "0.3.13",
|
||||
"description": "Testing utilities for Appium plugins",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -41,7 +41,7 @@
|
||||
"test:unit": "exit 0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@appium/types": "^0.10.4",
|
||||
"@appium/types": "^0.11.0",
|
||||
"get-port": "5.1.1",
|
||||
"log-symbols": "4.1.0",
|
||||
"source-map-support": "0.5.21",
|
||||
|
||||
@@ -3,6 +3,23 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [0.3.0](https://github.com/appium/appium/compare/@appium/strongbox@0.2.0...@appium/strongbox@0.3.0) (2023-04-20)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* **strongbox:** The signature for an `ItemCtor` has changed. The second parameter is now a type extending `Strongbox` instead of a `container` string. This allows for deeper integration between a custom `Item` implementation and a custom `Strongbox` implementation. Further, a custom `container` now must be an absolute path after it's been slugified.
|
||||
|
||||
- The `Strongbox.clearAll()` method now accepts a `force` param which, if `true`, will rimraf the entire container.
|
||||
- Added two methods to the `Strongbox` class which can be overridden to accept custom options, apply defaults to those options, then validate and/or transform them.
|
||||
- Added nearly-complete unit test coverage and added E2E coverage of the `BaseItem` implementation.
|
||||
|
||||
### Features
|
||||
|
||||
* **strongbox:** allow rimraf of entire container ([93bddb4](https://github.com/appium/appium/commit/93bddb4c73ab16fffda09909786074b9e5f2b7e5))
|
||||
|
||||
|
||||
|
||||
# 0.2.0 (2023-04-10)
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {mkdir, readFile, unlink, writeFile} from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import type {Item, ItemEncoding, Value} from '.';
|
||||
import type {Item, ItemEncoding, Strongbox, Value} from '.';
|
||||
import {slugify} from './util';
|
||||
|
||||
/**
|
||||
@@ -9,17 +9,20 @@ import {slugify} from './util';
|
||||
* @remarks This class is not intended to be instantiated directly
|
||||
* @typeParam T - Type of data stored in the `Item`
|
||||
*/
|
||||
export class BaseItem<T extends Value> implements Item<T> {
|
||||
export class BaseItem<T extends Value, U extends Strongbox = Strongbox> implements Item<T> {
|
||||
/**
|
||||
* {@inheritdoc Item.value}
|
||||
*/
|
||||
protected _value?: T | undefined;
|
||||
|
||||
/**
|
||||
* Parent Strongbox instance
|
||||
*/
|
||||
public readonly container: string;
|
||||
/**
|
||||
* Unique slugified identifier
|
||||
*/
|
||||
public readonly id: string;
|
||||
|
||||
/**
|
||||
* {@inheritdoc Item.value}
|
||||
*/
|
||||
@@ -28,16 +31,16 @@ export class BaseItem<T extends Value> implements Item<T> {
|
||||
/**
|
||||
* Slugifies the name
|
||||
* @param name Name of instance
|
||||
* @param container Slugified name of container
|
||||
* @param parent Parent Strongbox
|
||||
* @param encoding Defaults to `utf8`
|
||||
*/
|
||||
constructor(
|
||||
public readonly name: string,
|
||||
public readonly container: string,
|
||||
parent: U,
|
||||
public readonly encoding: ItemEncoding = 'utf8'
|
||||
) {
|
||||
this.id = path.join(container, slugify(name));
|
||||
|
||||
this.container = parent.container;
|
||||
this.id = path.join(this.container, slugify(name));
|
||||
Object.defineProperties(this, {
|
||||
value: {
|
||||
get() {
|
||||
@@ -52,6 +55,20 @@ export class BaseItem<T extends Value> implements Item<T> {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc Item.clear}
|
||||
*/
|
||||
public async clear(): Promise<void> {
|
||||
try {
|
||||
await unlink(this.id);
|
||||
this._value = undefined;
|
||||
} catch (e) {
|
||||
if ((e as NodeJS.ErrnoException).code !== 'ENOENT') {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc Item.read}
|
||||
*/
|
||||
@@ -78,18 +95,4 @@ export class BaseItem<T extends Value> implements Item<T> {
|
||||
this._value = value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc Item.clear}
|
||||
*/
|
||||
public async clear(): Promise<void> {
|
||||
try {
|
||||
await unlink(this.id);
|
||||
this._value = undefined;
|
||||
} catch (e) {
|
||||
if ((e as NodeJS.ErrnoException).code !== 'ENOENT') {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+102
-58
@@ -1,7 +1,8 @@
|
||||
import envPaths from 'env-paths';
|
||||
import {rm} from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import {BaseItem} from './base-item';
|
||||
import {slugify, slugifyPath} from './util';
|
||||
import {slugify} from './util';
|
||||
|
||||
/**
|
||||
* Valid file encodings.
|
||||
@@ -34,7 +35,17 @@ export interface Item<T extends Value> {
|
||||
* Name of item
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* Last known value (stored in memory)
|
||||
*
|
||||
* @remarks A custom {@linkcode Item} meant to handle very large files should probably not implement this.
|
||||
*/
|
||||
value?: T | undefined;
|
||||
|
||||
/**
|
||||
* Deletes the item.
|
||||
*/
|
||||
clear(): Promise<void>;
|
||||
/**
|
||||
* Reads value
|
||||
*/
|
||||
@@ -44,18 +55,6 @@ export interface Item<T extends Value> {
|
||||
* @param value New value
|
||||
*/
|
||||
write(value: T): Promise<void>;
|
||||
|
||||
/**
|
||||
* Deletes the item.
|
||||
*/
|
||||
clear(): Promise<void>;
|
||||
|
||||
/**
|
||||
* Last known value (stored in memory)
|
||||
*
|
||||
* @remarks A custom {@linkcode Item} meant to handle very large files should probably not implement this.
|
||||
*/
|
||||
value?: T | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,6 +86,8 @@ function isEncoding(value: any): value is ItemEncoding {
|
||||
}
|
||||
|
||||
/**
|
||||
* Default container suffix if no explicit container is provided.
|
||||
*
|
||||
* @see {@linkcode StrongboxOpts}
|
||||
*/
|
||||
export const DEFAULT_SUFFIX = 'strongbox';
|
||||
@@ -94,62 +95,58 @@ export const DEFAULT_SUFFIX = 'strongbox';
|
||||
/**
|
||||
* A constructor function which instantiates a {@linkcode Item}.
|
||||
*/
|
||||
export type ItemCtor<T extends Value> = new (
|
||||
name: string,
|
||||
container: string,
|
||||
encoding?: ItemEncoding
|
||||
) => Item<T>;
|
||||
export type ItemCtor<
|
||||
T extends Value,
|
||||
U extends StrongboxOpts = StrongboxOpts,
|
||||
V extends Strongbox<U> = Strongbox<U>
|
||||
> = new (name: string, parent: V, encoding?: ItemEncoding) => Item<T>;
|
||||
|
||||
/**
|
||||
* Main entry point for use of this module
|
||||
*
|
||||
* Manages multiple {@linkcode Item}s.
|
||||
*/
|
||||
export class Strongbox {
|
||||
export class Strongbox<Options extends StrongboxOpts = StrongboxOpts> {
|
||||
/**
|
||||
* Default {@linkcode ItemCtor} to use when creating new {@linkcode Item}s
|
||||
*/
|
||||
protected defaultItemCtor: ItemCtor<any>;
|
||||
/**
|
||||
* Slugified name of this instance; corresponds to the directory name.
|
||||
*
|
||||
* If `dir` is provided, this value is unused.
|
||||
* If `suffix` is provided, then this will be the parent directory of `suffix`.
|
||||
*/
|
||||
public readonly id: string;
|
||||
|
||||
/**
|
||||
* Override the directory of this container.
|
||||
*
|
||||
* If this is present, both `suffix` and `containerId` are unused.
|
||||
*/
|
||||
public readonly container: string;
|
||||
|
||||
/**
|
||||
* Store of known {@linkcode Item}s
|
||||
* @internal
|
||||
*/
|
||||
protected items: Map<string, WeakRef<Item<any>>>;
|
||||
|
||||
/**
|
||||
* Override the directory of this container.
|
||||
*
|
||||
* If this is present, `suffix` is ignored.
|
||||
*/
|
||||
public readonly container: string;
|
||||
/**
|
||||
* Slugified name of this instance; corresponds to the directory name.
|
||||
*
|
||||
* If `dir` is provided, this value is unused.
|
||||
* If `suffix` is provided, then this will be the parent directory of `suffix`.
|
||||
*/
|
||||
public readonly id: string;
|
||||
public readonly suffix: string;
|
||||
|
||||
/**
|
||||
* Slugifies the name & determines the directory
|
||||
* @param name Name of instance
|
||||
* @param opts Options
|
||||
*/
|
||||
protected constructor(
|
||||
public readonly name: string,
|
||||
{
|
||||
container,
|
||||
suffix = DEFAULT_SUFFIX,
|
||||
defaultItemCtor: defaultCtor = BaseItem,
|
||||
}: StrongboxOpts = {}
|
||||
) {
|
||||
protected constructor(public readonly name: string, opts: Partial<Options> = {}) {
|
||||
this.id = slugify(name);
|
||||
this.defaultItemCtor = defaultCtor;
|
||||
|
||||
let newOpts = this.setDefaultOptions(opts);
|
||||
newOpts = this.checkOptions(newOpts);
|
||||
|
||||
this.defaultItemCtor = newOpts.defaultItemCtor;
|
||||
this.container = newOpts.container;
|
||||
this.suffix = newOpts.suffix;
|
||||
this.items = new Map();
|
||||
this.container = container
|
||||
? slugifyPath(container)
|
||||
: path.join(envPaths(this.id).data, slugify(suffix));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,10 +155,26 @@ export class Strongbox {
|
||||
* @param opts Options
|
||||
* @returns New instance
|
||||
*/
|
||||
public static create(name: string, opts?: StrongboxOpts) {
|
||||
public static create<Options extends StrongboxOpts = StrongboxOpts>(
|
||||
name: string,
|
||||
opts?: Partial<Options>
|
||||
) {
|
||||
return new Strongbox(name, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears _all_ items.
|
||||
*
|
||||
* @param force - If `true`, will rimraf the container. Otherwise, will only delete individual items.
|
||||
*/
|
||||
public async clearAll(force = false): Promise<void> {
|
||||
const items = [...this.items.values()].map((ref) => ref.deref()).filter(Boolean) as Item<any>[];
|
||||
await Promise.all(items.map((item) => item.clear()));
|
||||
if (force) {
|
||||
await rm(this.container, {recursive: true});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@linkcode Item}.
|
||||
*
|
||||
@@ -188,7 +201,7 @@ export class Strongbox {
|
||||
}
|
||||
const item = new (encodingOrCtor ?? (this.defaultItemCtor as ItemCtor<T>))(
|
||||
name,
|
||||
this.container,
|
||||
this,
|
||||
encoding
|
||||
);
|
||||
if (this.items.has(item.id)) {
|
||||
@@ -250,11 +263,40 @@ export class Strongbox {
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears _all_ items, as well as the container.
|
||||
* Performs runtime validation (and optionally transformation) of options.
|
||||
*
|
||||
* Should not set defaults.
|
||||
*
|
||||
* The default implementation slugifies any custom container name and suffix.
|
||||
*
|
||||
* Subclasses should override this method to perform additional validation as needed.
|
||||
* @param opts - Options
|
||||
*/
|
||||
public async clearAll(): Promise<void> {
|
||||
const items = [...this.items.values()].map((ref) => ref.deref()).filter(Boolean) as Item<any>[];
|
||||
await Promise.all(items.map((item) => item.clear()));
|
||||
protected checkOptions(opts: Options): Options {
|
||||
opts.suffix = slugify(opts.suffix);
|
||||
if (opts.container) {
|
||||
opts.container = opts.container.split(path.sep).map(slugify).join(path.sep);
|
||||
if (!path.isAbsolute(opts.container)) {
|
||||
throw new TypeError(`container slug ${opts.container} must be an absolute path`);
|
||||
}
|
||||
} else {
|
||||
opts.container = path.join(envPaths(this.id).data, opts.suffix);
|
||||
}
|
||||
return opts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets defaults for options.
|
||||
*
|
||||
* Subclasses should override as necessary.
|
||||
* @param opts Options
|
||||
* @returns Options with defaults applied
|
||||
*/
|
||||
protected setDefaultOptions(opts: Partial<Options> = {}): Options {
|
||||
const newOpts = opts as Options;
|
||||
newOpts.suffix = opts.suffix ?? DEFAULT_SUFFIX;
|
||||
newOpts.defaultItemCtor = opts.defaultItemCtor ?? BaseItem;
|
||||
return newOpts;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,24 +304,26 @@ export class Strongbox {
|
||||
* Options for {@linkcode strongbox}
|
||||
*/
|
||||
export interface StrongboxOpts {
|
||||
/**
|
||||
* Override default container, which is chosen according to environment.
|
||||
*
|
||||
* This must be a writable path.
|
||||
*/
|
||||
container: string;
|
||||
/**
|
||||
* Default {@linkcode Item} constructor.
|
||||
*
|
||||
* Unless a constructor is specified when calling {@linkcode Strongbox.createItem} or {@linkcode Strongbox.createItemWithValue}, this will be used.
|
||||
* @defaultValue BaseItem
|
||||
*/
|
||||
defaultItemCtor?: ItemCtor<any>;
|
||||
/**
|
||||
* Override default container, which is chosen according to environment
|
||||
*/
|
||||
container?: string;
|
||||
defaultItemCtor: ItemCtor<any>;
|
||||
/**
|
||||
* Extra subdir to append to the auto-generated file directory hierarchy.
|
||||
*
|
||||
* This is ignored if `container` is provided.
|
||||
* @defaultValue 'strongbox'
|
||||
*/
|
||||
suffix?: string;
|
||||
suffix: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,3 @@ import slug from 'slugify';
|
||||
export function slugify(value: string) {
|
||||
return slug(value, {lower: true});
|
||||
}
|
||||
|
||||
export function slugifyPath(filepath: string) {
|
||||
return filepath.split(path.sep).map(slugify).join(path.sep);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/strongbox",
|
||||
"version": "0.2.0",
|
||||
"version": "0.3.0",
|
||||
"description": "Persistent storage for Appium extensions",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -37,7 +37,8 @@
|
||||
"test": "run-p test:unit test:types",
|
||||
"test:smoke": "node .",
|
||||
"test:unit": "mocha \"test/unit/**/*.spec.ts\"",
|
||||
"test:types": "tsd"
|
||||
"test:types": "tsd",
|
||||
"test:e2e": "mocha -t 20s \"test/e2e/**/*.e2e.spec.ts\""
|
||||
},
|
||||
"dependencies": {
|
||||
"env-paths": "2.2.1",
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
import {readFile} from 'node:fs/promises';
|
||||
import {Item, Strongbox, strongbox} from '../../lib';
|
||||
|
||||
const {expect} = chai;
|
||||
|
||||
describe('@appium/strongbox', function () {
|
||||
describe('default behavior', function () {
|
||||
let box: Strongbox;
|
||||
|
||||
beforeEach(function () {
|
||||
box = strongbox('test');
|
||||
});
|
||||
|
||||
afterEach(async function () {
|
||||
await box.clearAll(true);
|
||||
});
|
||||
|
||||
describe('when creating an Item with a value', function () {
|
||||
let item: Item<string>;
|
||||
|
||||
beforeEach(async function () {
|
||||
item = await box.createItemWithValue('test', 'value');
|
||||
});
|
||||
|
||||
it('should write the value to the filesystem', async function () {
|
||||
await expect(readFile(item.id, 'utf8')).to.eventually.equal('value');
|
||||
});
|
||||
|
||||
it('should set the value property', async function () {
|
||||
expect(item.value).to.equal('value');
|
||||
});
|
||||
|
||||
describe('when writing a new value', function () {
|
||||
beforeEach(async function () {
|
||||
await item.write('new value');
|
||||
});
|
||||
|
||||
it('should write the value to the filesystem', async function () {
|
||||
await expect(readFile(item.id, 'utf8')).to.eventually.equal('new value');
|
||||
});
|
||||
|
||||
it('should set the value property', async function () {
|
||||
expect(item.value).to.equal('new value');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when clearing the item', function () {
|
||||
beforeEach(async function () {
|
||||
await item.clear();
|
||||
});
|
||||
|
||||
it('should remove the item from the filesystem', async function () {
|
||||
await expect(readFile(item.id, 'utf8')).to.be.rejectedWith('ENOENT');
|
||||
});
|
||||
|
||||
it('should set the value property to undefined', async function () {
|
||||
expect(item.value).to.be.undefined;
|
||||
});
|
||||
|
||||
describe('when attempting to read it again', function () {
|
||||
it('should resolve w/ undefined', async function () {
|
||||
await expect(item.read()).to.eventually.be.undefined;
|
||||
});
|
||||
|
||||
it('should set the value property to undefined', async function () {
|
||||
expect(item.value).to.be.undefined;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,7 +1,7 @@
|
||||
import {expectAssignable, expectNotAssignable} from 'tsd';
|
||||
import {Item, BaseItem, Value} from '../..';
|
||||
import {Item, BaseItem, Value, strongbox} from '../..';
|
||||
|
||||
expectAssignable<Item<string>>(new BaseItem('foo', 'some-container'));
|
||||
expectAssignable<Item<string>>(new BaseItem('foo', strongbox('foo')));
|
||||
|
||||
expectNotAssignable<Value>(1);
|
||||
expectAssignable<Value>('foo');
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
import path from 'node:path';
|
||||
import rewiremock from 'rewiremock/node';
|
||||
import {createSandbox, SinonSandbox, SinonStubbedMember} from 'sinon';
|
||||
import type fs from 'node:fs/promises';
|
||||
import {Item, Strongbox} from '../../lib';
|
||||
|
||||
const {expect} = chai;
|
||||
type MockFs = {
|
||||
[K in keyof typeof fs]: SinonStubbedMember<(typeof fs)[K]>;
|
||||
};
|
||||
|
||||
describe('Strongbox', function () {
|
||||
let sandbox: SinonSandbox;
|
||||
let MockFs: MockFs = {} as any;
|
||||
const DATA_DIR = '/some/dir';
|
||||
// note to self: looks like this is safe to do before the rewiremock.proxy call
|
||||
let BaseItem: typeof import('../../lib/base-item').BaseItem;
|
||||
|
||||
beforeEach(function () {
|
||||
sandbox = createSandbox();
|
||||
({BaseItem} = rewiremock.proxy(
|
||||
() => require('../../lib'),
|
||||
(r) => ({
|
||||
// all of these props are async functions
|
||||
'node:fs/promises': r
|
||||
.mockThrough((prop) => {
|
||||
MockFs = {...MockFs, [prop]: sandbox.stub().resolves()};
|
||||
return MockFs[prop as keyof typeof fs];
|
||||
})
|
||||
.dynamic(), // this allows us to change the mock behavior on-the-fly
|
||||
'env-paths': sandbox.stub().returns({data: DATA_DIR}),
|
||||
})
|
||||
));
|
||||
});
|
||||
|
||||
describe('BaseItem', function () {
|
||||
describe('constructor', function () {
|
||||
it('should set the id property based on the parent container', function () {
|
||||
const item = new BaseItem('foo', {container: DATA_DIR} as Strongbox);
|
||||
expect(item.id).to.equal(path.join(DATA_DIR, 'foo'));
|
||||
});
|
||||
});
|
||||
|
||||
describe('method', function () {
|
||||
let item: Item<string>;
|
||||
|
||||
beforeEach(function () {
|
||||
item = new BaseItem('foo', {container: DATA_DIR} as Strongbox);
|
||||
});
|
||||
describe('clear()', function () {
|
||||
it('should remove the item from the filesystem', async function () {
|
||||
await item.clear();
|
||||
expect(MockFs.unlink).to.have.been.calledWith(item.id);
|
||||
});
|
||||
|
||||
describe('if the item does not exist', function () {
|
||||
beforeEach(function () {
|
||||
MockFs.unlink.rejects({code: 'ENOENT'});
|
||||
});
|
||||
it('should not reject', async function () {
|
||||
await expect(item.clear()).to.not.be.rejected;
|
||||
});
|
||||
});
|
||||
|
||||
describe('if something else goes wrong', function () {
|
||||
beforeEach(function () {
|
||||
MockFs.unlink.rejects(new Error('ugh'));
|
||||
});
|
||||
it('should reject', async function () {
|
||||
await expect(item.clear()).to.be.rejectedWith(Error, 'ugh');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('read()', function () {
|
||||
beforeEach(function () {
|
||||
MockFs.readFile.resolves('skunk');
|
||||
});
|
||||
it('should read the item from the fileystem', function () {
|
||||
expect(item.read()).to.eventually.equal('skunk');
|
||||
});
|
||||
|
||||
it('should set the item value to the read value', async function () {
|
||||
await item.read();
|
||||
expect(item.value).to.equal('skunk');
|
||||
});
|
||||
});
|
||||
|
||||
describe('write()', function () {
|
||||
beforeEach(async function () {
|
||||
await item.write('bar');
|
||||
});
|
||||
|
||||
it('should write the new item value to the filesystem', async function () {
|
||||
expect(MockFs.writeFile).to.have.been.calledWith(item.id, 'bar');
|
||||
});
|
||||
|
||||
it('should create the container', function () {
|
||||
expect(MockFs.mkdir).to.have.been.calledWith(path.dirname(item.id), {recursive: true});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
import path from 'node:path';
|
||||
import rewiremock from 'rewiremock/node';
|
||||
import type {Strongbox as TStrongbox, StrongboxOpts} from '../../lib';
|
||||
import type {Strongbox as TStrongbox, StrongboxOpts, Item, Value} from '../../lib';
|
||||
import {createSandbox, SinonSandbox, SinonStubbedMember} from 'sinon';
|
||||
import type fs from 'node:fs/promises';
|
||||
|
||||
@@ -10,7 +10,7 @@ type MockFs = {
|
||||
};
|
||||
|
||||
describe('Strongbox', function () {
|
||||
let strongbox: (name: string, opts?: StrongboxOpts) => TStrongbox;
|
||||
let strongbox: (name: string, opts?: Partial<StrongboxOpts>) => TStrongbox;
|
||||
let Strongbox: new (name: string, opts?: StrongboxOpts) => TStrongbox;
|
||||
let sandbox: SinonSandbox;
|
||||
let DEFAULT_SUFFIX: string;
|
||||
@@ -20,16 +20,19 @@ describe('Strongbox', function () {
|
||||
|
||||
beforeEach(function () {
|
||||
sandbox = createSandbox();
|
||||
({strongbox, DEFAULT_SUFFIX, Strongbox} = rewiremock.proxy(() => require('../../lib'), (r) => ({
|
||||
// all of these props are async functions
|
||||
'node:fs/promises': r
|
||||
.mockThrough((prop) => {
|
||||
MockFs = {...MockFs, [prop]: sandbox.stub().resolves()};
|
||||
return MockFs[prop as keyof typeof fs];
|
||||
})
|
||||
.dynamic(), // this allows us to change the mock behavior on-the-fly
|
||||
'env-paths': sandbox.stub().returns({data: DATA_DIR}),
|
||||
})));
|
||||
({strongbox, DEFAULT_SUFFIX, Strongbox} = rewiremock.proxy(
|
||||
() => require('../../lib'),
|
||||
(r) => ({
|
||||
// all of these props are async functions
|
||||
'node:fs/promises': r
|
||||
.mockThrough((prop) => {
|
||||
MockFs = {...MockFs, [prop]: sandbox.stub().resolves()};
|
||||
return MockFs[prop as keyof typeof fs];
|
||||
})
|
||||
.dynamic(), // this allows us to change the mock behavior on-the-fly
|
||||
'env-paths': sandbox.stub().returns({data: DATA_DIR}),
|
||||
})
|
||||
));
|
||||
});
|
||||
|
||||
describe('static method', function () {
|
||||
@@ -38,6 +41,29 @@ describe('Strongbox', function () {
|
||||
const box = strongbox('test');
|
||||
expect(box).to.be.an.instanceOf(Strongbox);
|
||||
});
|
||||
|
||||
describe('when provided an absolute container path', function () {
|
||||
it('should use the provided container path', function () {
|
||||
expect(strongbox('test', {container: '/somewhere/else'}).container).to.equal(
|
||||
'/somewhere/else'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when provided a relative container path', function () {
|
||||
it('should throw an error', function () {
|
||||
expect(() => strongbox('test', {container: 'somewhere/else'})).to.throw(
|
||||
TypeError,
|
||||
'container slug somewhere/else must be an absolute path'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when provided a suffix', function () {
|
||||
it('should use the provided suffix', function () {
|
||||
expect(strongbox('test', {suffix: 'mooo'}).suffix).to.equal('mooo');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,8 +77,13 @@ describe('Strongbox', function () {
|
||||
describe('createItem()', function () {
|
||||
describe('when a Item with the same id does not exist', function () {
|
||||
describe('when the file does not exist', function () {
|
||||
let item: Item<Value>;
|
||||
|
||||
beforeEach(async function () {
|
||||
item = await box.createItem('SLUG test');
|
||||
});
|
||||
|
||||
it('should create an empty Item', async function () {
|
||||
const item = await box.createItem('SLUG test');
|
||||
expect(item).to.eql({
|
||||
id: '/some/dir/strongbox/slug-test',
|
||||
name: 'SLUG test',
|
||||
@@ -61,6 +92,10 @@ describe('Strongbox', function () {
|
||||
container: '/some/dir/strongbox',
|
||||
});
|
||||
});
|
||||
|
||||
it('should slugify the id', function () {
|
||||
expect(item.id).to.equal('/some/dir/strongbox/slug-test');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the file exists', function () {
|
||||
@@ -79,6 +114,15 @@ describe('Strongbox', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when attempting to read the file throws a non-ENOENT error', function () {
|
||||
beforeEach(function () {
|
||||
MockFs.readFile.rejects(new Error('ETOOMANYGOATS'));
|
||||
});
|
||||
it('should reject', async function () {
|
||||
await expect(box.createItem('SLUG test')).to.be.rejectedWith(Error, 'ETOOMANYGOATS');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when a value is written to the Item', function () {
|
||||
it('should write a string value to the underlying file', async function () {
|
||||
const item = await box.createItem('test');
|
||||
@@ -108,6 +152,13 @@ describe('Strongbox', function () {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the second parameter is a valid encoding', function () {
|
||||
it('should create the empty Item with the proper encoding', async function () {
|
||||
const item = await box.createItem('test', 'base64');
|
||||
expect(item.encoding).to.equal('base64');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('clearAll()', function () {
|
||||
@@ -147,6 +198,28 @@ describe('Strongbox', function () {
|
||||
'value'
|
||||
);
|
||||
});
|
||||
|
||||
describe('when the third parameter is a valid encoding', function () {
|
||||
it('should create the Item with the given value and proper encoding', async function () {
|
||||
const item = await box.createItemWithValue('test', 'value', 'base64');
|
||||
expect(item.encoding).to.equal('base64');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getItem()', function () {
|
||||
describe('when there is no known Item with the given id', function () {
|
||||
it('should return undefined', function () {
|
||||
expect(box.getItem('test')).to.be.undefined;
|
||||
});
|
||||
});
|
||||
|
||||
describe('when there is a known Item with the given id', function () {
|
||||
it('should return the Item', async function () {
|
||||
const item = await box.createItem('test');
|
||||
expect(box.getItem(item.id)).to.equal(item);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
## [3.1.11](https://github.com/appium/appium/compare/@appium/support@3.1.10...@appium/support@3.1.11) (2023-04-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **support:** prevent s3 presigned post request failing in http upload ([#18519](https://github.com/appium/appium/issues/18519)) ([59e4367](https://github.com/appium/appium/commit/59e4367cc832ced431259b476dc3c20775595e37))
|
||||
* **support:** update dependency semver to v7.4.0 ([6ae86bd](https://github.com/appium/appium/commit/6ae86bd5c7be879a4d8852951d73eb2f68128df3))
|
||||
|
||||
|
||||
|
||||
## [3.1.10](https://github.com/appium/appium/compare/@appium/support@3.1.9...@appium/support@3.1.10) (2023-04-10)
|
||||
|
||||
|
||||
|
||||
@@ -70,7 +70,6 @@ async function uploadFileToHttp(
|
||||
}
|
||||
if (fileFieldName) {
|
||||
const form = new FormData();
|
||||
form.append(fileFieldName, localFileStream);
|
||||
if (formFields) {
|
||||
let pairs = [];
|
||||
if (_.isArray(formFields)) {
|
||||
@@ -84,6 +83,7 @@ async function uploadFileToHttp(
|
||||
}
|
||||
}
|
||||
}
|
||||
form.append(fileFieldName, localFileStream); // AWS S3 POST upload requires this to be the last field
|
||||
requestOpts.headers = {
|
||||
...(_.isPlainObject(headers) ? headers : {}),
|
||||
...form.getHeaders(),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/support",
|
||||
"version": "3.1.10",
|
||||
"version": "3.1.11",
|
||||
"description": "Support libs used across appium packages",
|
||||
"keywords": [
|
||||
"automation",
|
||||
@@ -42,7 +42,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@appium/tsconfig": "^0.3.0",
|
||||
"@appium/types": "^0.10.4",
|
||||
"@appium/types": "^0.11.0",
|
||||
"@colors/colors": "1.5.0",
|
||||
"@types/archiver": "5.3.2",
|
||||
"@types/base64-stream": "1.0.2",
|
||||
@@ -90,7 +90,7 @@
|
||||
"resolve-from": "5.0.0",
|
||||
"rimraf": "3.0.2",
|
||||
"sanitize-filename": "1.6.3",
|
||||
"semver": "7.3.8",
|
||||
"semver": "7.4.0",
|
||||
"shell-quote": "1.8.1",
|
||||
"source-map-support": "0.5.21",
|
||||
"supports-color": "8.1.1",
|
||||
|
||||
@@ -16,7 +16,10 @@ describe('#net', function () {
|
||||
describe('downloadFile()', function () {
|
||||
it('should download file into the target folder', async function () {
|
||||
const dstPath = path.join(tmpRoot, 'download.tmp');
|
||||
await downloadFile('https://appium.io/ico/apple-touch-icon-114x114-precomposed.png', dstPath);
|
||||
await downloadFile(
|
||||
'https://appium.io/docs/en/2.0/assets/images/appium-logo-white.png',
|
||||
dstPath
|
||||
);
|
||||
await fs.exists(dstPath).should.eventually.be.true;
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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.13](https://github.com/appium/appium/compare/@appium/test-support@3.0.12...@appium/test-support@3.0.13) (2023-04-14)
|
||||
|
||||
**Note:** Version bump only for package @appium/test-support
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## [3.0.12](https://github.com/appium/appium/compare/@appium/test-support@3.0.11...@appium/test-support@3.0.12) (2023-04-10)
|
||||
|
||||
**Note:** Version bump only for package @appium/test-support
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/test-support",
|
||||
"version": "3.0.12",
|
||||
"version": "3.0.13",
|
||||
"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": "^3.1.10",
|
||||
"@appium/support": "^3.1.11",
|
||||
"@colors/colors": "1.5.0",
|
||||
"bluebird": "3.7.2",
|
||||
"lodash": "4.17.21",
|
||||
|
||||
@@ -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.6.3](https://github.com/appium/appium/compare/@appium/typedoc-plugin-appium@0.6.2...@appium/typedoc-plugin-appium@0.6.3) (2023-04-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **typedoc-plugin-appium:** fix parameter display for execute methods ([5a70d7c](https://github.com/appium/appium/commit/5a70d7ce78ce12ef8b9209a2a17c52b02ac0fc80))
|
||||
|
||||
|
||||
|
||||
## [0.6.2](https://github.com/appium/appium/compare/@appium/typedoc-plugin-appium@0.6.1...@appium/typedoc-plugin-appium@0.6.2) (2023-04-12)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **typedoc-plugin-appium:** restrict peer deps ([63e28a0](https://github.com/appium/appium/commit/63e28a014cf9af8bba9595d83f513bfb7026ae9a))
|
||||
|
||||
|
||||
|
||||
## [0.6.1](https://github.com/appium/appium/compare/@appium/typedoc-plugin-appium@0.6.0...@appium/typedoc-plugin-appium@0.6.1) (2023-04-10)
|
||||
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ import _ from 'lodash';
|
||||
import {Context, DeclarationReflection, ReflectionKind} from 'typedoc';
|
||||
import {
|
||||
isCommandPropDeclarationReflection,
|
||||
isExecMethodDefParamsPropDeclarationReflection,
|
||||
isHTTPMethodDeclarationReflection,
|
||||
isMethodDefParamsPropDeclarationReflection,
|
||||
isRoutePropDeclarationReflection,
|
||||
} from '../guards';
|
||||
import {AppiumPluginLogger} from '../logger';
|
||||
@@ -134,7 +134,7 @@ export function convertMethodMap({
|
||||
|
||||
const payloadParamsProp = findChildByGuard(
|
||||
httpMethodProp,
|
||||
isExecMethodDefParamsPropDeclarationReflection
|
||||
isMethodDefParamsPropDeclarationReflection
|
||||
);
|
||||
|
||||
const requiredParams = convertRequiredCommandParams(payloadParamsProp);
|
||||
|
||||
@@ -238,7 +238,7 @@ export function isExecMethodData(value: any): value is ExecMethodData {
|
||||
export function isMethodDefParamsPropDeclarationReflection(
|
||||
value: any
|
||||
): value is MethodDefParamsPropDeclarationReflection {
|
||||
return isReflectionWithReflectedType(value) && value.name === NAME_PARAMS;
|
||||
return isReflectionWithReflectedType(value) && value.name === NAME_PAYLOAD_PARAMS;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -248,7 +248,7 @@ export function isMethodDefParamsPropDeclarationReflection(
|
||||
export function isExecMethodDefParamsPropDeclarationReflection(
|
||||
value: any
|
||||
): value is ExecMethodDefParamsPropDeclarationReflection {
|
||||
return isReflectionWithReflectedType(value) && value.name === NAME_PAYLOAD_PARAMS;
|
||||
return isReflectionWithReflectedType(value) && value.name === NAME_PARAMS;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
{{/with}}
|
||||
|
||||
{{else}}
|
||||
{{! the required/optional parameters bits are fallbacks }}
|
||||
{{#if hasRequiredParams}}
|
||||
|
||||
##### Required Parameters
|
||||
@@ -53,8 +54,8 @@
|
||||
|
||||
<!-- END:EXAMPLE -->
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
<!-- END:EXAMPLES -->
|
||||
{{/if}}
|
||||
{{#if signature}}
|
||||
|
||||
#### Response
|
||||
|
||||
@@ -3,35 +3,93 @@
|
||||
### {{#ifNamedAnchors}} <a id="{{anchor}}" name="{{this.anchor}}"></a> {{/ifNamedAnchors}}Script: `{{name}}`
|
||||
|
||||
{{#if hasComment}}
|
||||
|
||||
{{> comment}}
|
||||
|
||||
<!-- comment source: {{commentSource}} -->
|
||||
{{/if}}
|
||||
|
||||
#### Route
|
||||
|
||||
`{{httpMethod}} {{route}}`
|
||||
|
||||
{{#if hasRequiredParams}}
|
||||
{{#if parameters}}
|
||||
|
||||
#### Required Parameters
|
||||
#### Parameters
|
||||
|
||||
{{#with parameters}}
|
||||
|
||||
{{{parameterTable}}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{else}}
|
||||
{{! the required/optional parameters bits are fallbacks }}
|
||||
{{#if hasRequiredParams}}
|
||||
|
||||
##### Required Parameters
|
||||
|
||||
{{#each requiredParams}}
|
||||
|
||||
- `{{this}}`
|
||||
|
||||
{{/each}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if hasOptionalParams}}
|
||||
|
||||
#### Optional Parameters
|
||||
##### Optional Parameters
|
||||
|
||||
{{#each optionalParams}}
|
||||
- `{{this}}`
|
||||
{{/each}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{#if hasExample}}
|
||||
#### {{pluralize 'Example' examples.length}}
|
||||
|
||||
<!-- BEGIN:EXAMPLES -->
|
||||
{{#each examples}}
|
||||
##### {{lang}}
|
||||
<!-- BEGIN:EXAMPLE lang={{lang}} -->
|
||||
|
||||
{{{text}}}
|
||||
|
||||
<!-- END:EXAMPLE -->
|
||||
{{/each}}
|
||||
<!-- END:EXAMPLES -->
|
||||
{{/if}}
|
||||
{{#if signature}}
|
||||
|
||||
#### Response
|
||||
|
||||
{{#with signature}}
|
||||
|
||||
{{#with type}}
|
||||
|
||||
{{{type 'all'}}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{#with comment}}
|
||||
|
||||
{{{returns this}}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{#with type}}
|
||||
|
||||
{{#if declaration.signatures}}
|
||||
|
||||
{{#each declaration.signatures}}
|
||||
|
||||
{{> member.signature showSources=false }}
|
||||
|
||||
{{/each}}
|
||||
|
||||
{{/if}}
|
||||
|
||||
{{/with}}
|
||||
|
||||
{{/with}}
|
||||
{{/if}}
|
||||
{{/unless}}
|
||||
|
||||
@@ -5,12 +5,17 @@
|
||||
|
||||
import _ from 'lodash';
|
||||
import {DeclarationReflection} from 'typedoc';
|
||||
import {isCallSignatureReflection} from './guards';
|
||||
import {isCallSignatureReflection, isReflectionWithReflectedType} from './guards';
|
||||
|
||||
/**
|
||||
* Loops through signatures of the command's method declaration and returns the first that is a
|
||||
* `CallSignatureReflection` (if any). This is what we think of when we think "function signature"
|
||||
* This also works on DeclarationReflections that have a reflected type; in other words, some value that is the type of a function, but is not a function itself (such as a property assigned to a function).
|
||||
*/
|
||||
export const findCallSignature = _.memoize((refl?: DeclarationReflection) =>
|
||||
refl?.getAllSignatures()?.find(isCallSignatureReflection)
|
||||
export const findCallSignature = _.memoize(
|
||||
(refl?: DeclarationReflection) =>
|
||||
refl?.getAllSignatures()?.find(isCallSignatureReflection) ??
|
||||
(isReflectionWithReflectedType(refl)
|
||||
? refl.type.declaration.getAllSignatures()?.find(isCallSignatureReflection)
|
||||
: undefined)
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/typedoc-plugin-appium",
|
||||
"version": "0.6.1",
|
||||
"version": "0.6.3",
|
||||
"description": "TypeDoc plugin for Appium & its extensions",
|
||||
"homepage": "https://appium.io",
|
||||
"license": "Apache-2.0",
|
||||
@@ -26,7 +26,7 @@
|
||||
"build": "cpy lib/theme/resources build",
|
||||
"clean": "npx rimraf build",
|
||||
"test": "run-s test:unit",
|
||||
"test:e2e": "mocha --timeout 20s \"test/e2e/index.e2e.spec.ts\" && mocha --timeout 20s \"test/e2e/converter/builtin-external-driver.e2e.spec.ts\" && mocha --timeout 20s \"test/e2e/converter/builtin-method-map.e2e.spec.ts\" && mocha --timeout 20s \"test/e2e/converter/converter.e2e.spec.ts\" && mocha --timeout 20s \"test/e2e/converter/external.e2e.spec.ts\"",
|
||||
"test:e2e": "mocha --timeout 20s \"test/e2e/index.e2e.spec.ts\" && mocha --timeout 20s \"test/e2e/converter/builtin-external-driver.e2e.spec.ts\" && mocha --timeout 20s \"test/e2e/converter/builtin-method-map.e2e.spec.ts\" && mocha --timeout 20s \"test/e2e/converter/converter.e2e.spec.ts\" && mocha --timeout 20s \"test/e2e/converter/external.e2e.spec.ts\" && mocha --timeout 20s \"test/e2e/theme/output.e2e.spec.ts\"",
|
||||
"test:smoke": "node ./index.js",
|
||||
"test:unit": "mocha --timeout 2s \"test/unit/**/*.spec.ts\""
|
||||
},
|
||||
@@ -54,8 +54,8 @@
|
||||
},
|
||||
"peerDependencies": {
|
||||
"appium": "^2.0.0-beta.48",
|
||||
"typedoc": "^0.23.14",
|
||||
"typedoc-plugin-markdown": "^3.14.0",
|
||||
"typedoc": "~0.23.14",
|
||||
"typedoc-plugin-markdown": "3.14.0",
|
||||
"typedoc-plugin-resolve-crossmodule-references": "~0.3.3",
|
||||
"typescript": "^4.7.0 || ^5.0.0"
|
||||
},
|
||||
|
||||
@@ -10,8 +10,8 @@ import {
|
||||
TSConfigReader,
|
||||
TypeDocOptions,
|
||||
} from 'typedoc';
|
||||
import {THEME_NAME} from '../../lib';
|
||||
import {BaseConverter} from '../../lib/converter';
|
||||
import {THEME_NAME, setup} from '../../lib';
|
||||
import {BaseConverter, NAME_BUILTIN_COMMAND_MODULE, NAME_TYPES_MODULE} from '../../lib/converter';
|
||||
import {AppiumPluginLogger} from '../../lib/logger';
|
||||
|
||||
const {expect} = chai;
|
||||
@@ -175,3 +175,13 @@ export interface InitConverterOptions<Args extends readonly any[] = any[]>
|
||||
type ConverterConstructor<T, C extends BaseConverter<T>, Args extends readonly any[] = any[]> =
|
||||
| Constructor<C, [Context, AppiumPluginLogger, ...Args]>
|
||||
| Constructor<C, [Context, AppiumPluginLogger]>;
|
||||
|
||||
/**
|
||||
* Creates a new TypeDoc application and/or resets it
|
||||
*/
|
||||
export function reset({
|
||||
entryPoints = [NAME_TYPES_MODULE, NAME_FAKE_DRIVER_MODULE, NAME_BUILTIN_COMMAND_MODULE],
|
||||
...opts
|
||||
}: Partial<TypeDocOptions> = {}): Application {
|
||||
return setup(initAppForPkgs({entryPoints, ...opts}));
|
||||
}
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
import _ from 'lodash';
|
||||
import {
|
||||
Application,
|
||||
Context,
|
||||
DeclarationReflection,
|
||||
ProjectReflection,
|
||||
ReflectionKind,
|
||||
TypeDocOptions,
|
||||
} from 'typedoc';
|
||||
import {convert, ConvertResult, postProcess, PostProcessResult, setup} from '../../lib';
|
||||
import {Context, DeclarationReflection, ProjectReflection, ReflectionKind} from 'typedoc';
|
||||
import {convert, ConvertResult, postProcess, PostProcessResult} from '../../lib';
|
||||
import {NAME_BUILTIN_COMMAND_MODULE, NAME_TYPES_MODULE} from '../../lib/converter';
|
||||
import {AppiumPluginReflectionKind, CommandReflection, ExtensionReflection} from '../../lib/model';
|
||||
import {initAppForPkgs, NAME_FAKE_DRIVER_MODULE} from './helpers';
|
||||
import {reset} from './helpers';
|
||||
|
||||
const {expect} = chai;
|
||||
|
||||
@@ -34,16 +27,6 @@ describe('@appium/typedoc-plugin-appium', function () {
|
||||
*/
|
||||
let extensionReflections!: ExtensionReflection[];
|
||||
|
||||
/**
|
||||
* Creates a new TypeDoc application and/or resets it
|
||||
*/
|
||||
function reset({
|
||||
entryPoints = [NAME_TYPES_MODULE, NAME_FAKE_DRIVER_MODULE, NAME_BUILTIN_COMMAND_MODULE],
|
||||
...opts
|
||||
}: Partial<TypeDocOptions> = {}): Application {
|
||||
return setup(initAppForPkgs({entryPoints, ...opts}));
|
||||
}
|
||||
|
||||
describe('convert()', function () {
|
||||
describe('when "theme" is not "markdown" or "appium"', function () {
|
||||
it('should do nothing', async function () {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,49 @@
|
||||
import path from 'node:path';
|
||||
import {tempDir, fs} from 'appium/support';
|
||||
import {jestSnapshotPlugin} from 'mocha-chai-jest-snapshot';
|
||||
import {convert} from '../../../lib';
|
||||
import {reset} from '../helpers';
|
||||
|
||||
chai.use(jestSnapshotPlugin());
|
||||
|
||||
const {expect} = chai;
|
||||
|
||||
describe('@appium/typedoc-plugin-appium', function () {
|
||||
let tmpDir: string;
|
||||
before(async function () {
|
||||
const app = reset({
|
||||
plugin: ['typedoc-plugin-markdown', 'typedoc-plugin-crossmodule-references'],
|
||||
});
|
||||
const promise = convert(app);
|
||||
const project = app.convert();
|
||||
await promise;
|
||||
expect(project).to.exist;
|
||||
tmpDir = await tempDir.openDir();
|
||||
await app.generateDocs(project!, tmpDir);
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
await fs.rimraf(tmpDir);
|
||||
});
|
||||
|
||||
describe('theme', function () {
|
||||
describe('command output', function () {
|
||||
it('should generate expected markdown', async function () {
|
||||
const baseDriverMd = await fs.readFile(
|
||||
path.join(tmpDir, 'commands', 'base-driver.md'),
|
||||
'utf8'
|
||||
);
|
||||
expect(baseDriverMd).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
describe('execute method output', function () {
|
||||
it('should generate expected markdown', async function () {
|
||||
const fakeDriverMd = await fs.readFile(
|
||||
path.join(tmpDir, 'commands', 'fake-driver.md'),
|
||||
'utf8'
|
||||
);
|
||||
expect(fakeDriverMd).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -3,6 +3,23 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||
|
||||
## [0.11.0](https://github.com/appium/appium/compare/@appium/types@0.10.4...@appium/types@0.11.0) (2023-04-14)
|
||||
|
||||
|
||||
### ⚠ BREAKING CHANGES
|
||||
|
||||
* **types:** `Driver.proxyCommand` now returns `Promise<unknown>` by default. In strict mode, this forces an extension calling `this.proxyCommand()` to explicitly type the return value (because it's unknown!).
|
||||
|
||||
Otherwise, this concerns the `SingularSessionData` type and the function which returns it (`getSession()`). `Driver` now accepts a type param to add arbitrary properties to the value returned by `getSession()`--as this is in-line with `XCUITestDriver` is doing. This param is provided as the new optional second type param to `SingularSessionData`.
|
||||
|
||||
Further, it removes the `ISessionCommands` interface, because I didn't understand how to write it such that an isolated implementation could use the type parameter from the class it belongs to. This is probably doable, but seems icky, and I didn't want to fight with it. It's easier to just move the implementation into the class itself, which is what will happen in `BaseDriver` (see next changeset).
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **types:** driver-specific session data now allowed ([91abd5b](https://github.com/appium/appium/commit/91abd5b598dd55e8d7fd12d2e683703aa8ac290a))
|
||||
|
||||
|
||||
|
||||
## [0.10.4](https://github.com/appium/appium/compare/@appium/types@0.10.3...@appium/types@0.10.4) (2023-04-10)
|
||||
|
||||
|
||||
|
||||
@@ -157,22 +157,6 @@ export interface IEventCommands {
|
||||
getLogEvents(type?: string | string[]): Promise<EventHistory | Record<string, number>>;
|
||||
}
|
||||
|
||||
export interface ISessionCommands {
|
||||
/**
|
||||
* Get data for all sessions running on an Appium server
|
||||
*
|
||||
* @returns A list of session data objects
|
||||
*/
|
||||
getSessions(): Promise<MultiSessionData[]>;
|
||||
|
||||
/**
|
||||
* Get the data for the current session
|
||||
*
|
||||
* @returns A session data object
|
||||
*/
|
||||
getSession<C extends Constraints>(): Promise<SingularSessionData<C>>;
|
||||
}
|
||||
|
||||
export interface IExecuteCommands {
|
||||
/**
|
||||
* Call an `Execute Method` by its name with the given arguments. This method will check that the
|
||||
@@ -197,10 +181,20 @@ export interface MultiSessionData<C extends Constraints = Constraints> {
|
||||
capabilities: DriverCaps<C>;
|
||||
}
|
||||
|
||||
export type SingularSessionData<C extends Constraints = Constraints> = DriverCaps<C> & {
|
||||
/**
|
||||
* Data returned by {@linkcode ISessionCommands.getSession}.
|
||||
*
|
||||
* @typeParam C - The driver's constraints
|
||||
* @typeParam T - Any extra data the driver stuffs in here
|
||||
* @privateRemarks The content of this object looks implementation-specific and in practice is not well-defined. It's _possible_ to fully type this in the future.
|
||||
*/
|
||||
export type SingularSessionData<
|
||||
C extends Constraints = Constraints,
|
||||
T extends StringRecord = StringRecord
|
||||
> = DriverCaps<C> & {
|
||||
events?: EventHistory;
|
||||
error?: string;
|
||||
};
|
||||
} & T;
|
||||
|
||||
export interface IFindCommands {
|
||||
/**
|
||||
@@ -411,7 +405,8 @@ export type DefaultDeleteSessionResult = void;
|
||||
export interface ISessionHandler<
|
||||
C extends Constraints = Constraints,
|
||||
CreateResult = DefaultCreateSessionResult<C>,
|
||||
DeleteResult = DefaultDeleteSessionResult
|
||||
DeleteResult = DefaultDeleteSessionResult,
|
||||
SessionData extends StringRecord = StringRecord
|
||||
> {
|
||||
/**
|
||||
* Start a new automation session
|
||||
@@ -445,6 +440,20 @@ export interface ISessionHandler<
|
||||
* @param driverData - the driver data for other currently-running sessions
|
||||
*/
|
||||
deleteSession(sessionId?: string, driverData?: DriverData[]): Promise<DeleteResult>;
|
||||
|
||||
/**
|
||||
* Get data for all sessions running on an Appium server
|
||||
*
|
||||
* @returns A list of session data objects
|
||||
*/
|
||||
getSessions(): Promise<MultiSessionData[]>;
|
||||
|
||||
/**
|
||||
* Get the data for the current session
|
||||
*
|
||||
* @returns A session data object
|
||||
*/
|
||||
getSession(): Promise<SingularSessionData<C, SessionData>>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -675,15 +684,15 @@ export interface Driver<
|
||||
CArgs extends StringRecord = StringRecord,
|
||||
Settings extends StringRecord = StringRecord,
|
||||
CreateResult = DefaultCreateSessionResult<C>,
|
||||
DeleteResult = DefaultDeleteSessionResult
|
||||
> extends ISessionCommands,
|
||||
ILogCommands,
|
||||
DeleteResult = DefaultDeleteSessionResult,
|
||||
SessionData extends StringRecord = StringRecord
|
||||
> extends ILogCommands,
|
||||
IFindCommands,
|
||||
ISettingsCommands<Settings>,
|
||||
ITimeoutCommands,
|
||||
IEventCommands,
|
||||
IExecuteCommands,
|
||||
ISessionHandler<C, CreateResult, DeleteResult>,
|
||||
ISessionHandler<C, CreateResult, DeleteResult, SessionData>,
|
||||
Core<C, Settings> {
|
||||
/**
|
||||
* The set of command line arguments set for this driver
|
||||
@@ -1992,14 +2001,19 @@ export interface ExternalDriver<C extends Constraints = Constraints, Ctx = strin
|
||||
/**
|
||||
* Proxy a command to a connected WebDriver server
|
||||
*
|
||||
* @typeParam T - the type of the return value
|
||||
* @typeParam TReq - the type of the incoming body
|
||||
* @typeParam TRes - the type of the return value
|
||||
* @param url - the incoming URL
|
||||
* @param method - the incoming HTTP method
|
||||
* @param body - the incoming HTTP body
|
||||
*
|
||||
* @returns The return value of the proxied command
|
||||
*/
|
||||
proxyCommand?<T = any>(url: string, method: HTTPMethod, body?: string): Promise<T>;
|
||||
proxyCommand?<TReq = any, TRes = unknown>(
|
||||
url: string,
|
||||
method: HTTPMethod,
|
||||
body?: TReq
|
||||
): Promise<TRes>;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@appium/types",
|
||||
"version": "0.10.4",
|
||||
"version": "0.11.0",
|
||||
"description": "Various type declarations used across Appium",
|
||||
"keywords": [
|
||||
"automation",
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
},
|
||||
{
|
||||
"extends": ["packages:eslint"],
|
||||
"matchPackageNames": ["@appium/eslint-config-appium"],
|
||||
"matchPackagePrefixes": ["@appium/eslint-config-appium"],
|
||||
"groupName": "ESLint-related packages",
|
||||
"groupSlug": "eslint"
|
||||
},
|
||||
@@ -58,7 +58,8 @@
|
||||
},
|
||||
{
|
||||
"matchPackagePrefixes": ["@appium/"],
|
||||
"excludePackageNames": ["@appium/eslint-config-appium"],
|
||||
"excludePackageNames": ["@appium/eslint-config-appium", "@appium/eslint-config-appium-ts"],
|
||||
"matchPackageNames": "appium",
|
||||
"groupName": "Appium-related packages",
|
||||
"groupSlug": "appium"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user