Commit Graph
9503 Commits
Author SHA1 Message Date
Christopher Hiller 2fbd49fed4 feat(support): move npm module into support
- Altered strategy for determining `APPIUM_HOME` by using `npm ls` and reading `package.json` if that fails
- rename `isLocalAppiumInstalled` to `hasAppiumDependency` in `env` module
- no longer care about `peerDependencies`; we can add this later if necessary
- consume `pkg-dir` module
- remove `read-pkg-up`
- move `npm` module into `support` (which is the `feat` here, I guess)
- the `NPM` class no longer has internal state, so doesn't really need to be a class, but I didn't want to bother with that refactor.  the module exports the class `NPM` and an instance `npm`.  creating new instances of `NPM` are useless, but there's no guard against it.
- method signatures in `NPM` class have changed to generally accept a `cwd` string.  further, non-optional options have been moved out of an optional options object. 😄

feat(appium): remove NPM module (it went into @appium/support)

- Probably not a breaking change, but it certainly breaks a few things in `appium`, which I addressed.
- Updated for new `NPM` api
- fixed sandboxing issue in `cli-specs`
- update `mocks`
2022-03-09 14:50:45 -08:00
Christopher Hiller d89fb9b354 feat(appium): allow installation of extensions via npm
## BREAKING CHANGES

(potentially, anyway)

1. Installation of extensions via `appium` now treats `$APPIUM_HOME` _mostly_ like a project containing a `node_modules` subfolder, with extensions under that.  Previously, each extension would have its own folder, with a `node_modules` and empty `package.json`, and finally the extension.  The intent was to inhibit deduping and conflicts with any `package.json` files in ancestors of `$APPIUM_HOME`.  I showed this was unnecessary because the same thing can be accomplished via the flag `--global-style` for `npm install`.  Ultimately, this simplifies the directory structure of `$APPIUM_HOME`.
2. `$APPIUM_HOME/extensions.yaml` now lives at `$APPIUM_HOME/node_modules/.cache/appium/extensions.yaml`.  The `node_modules/.cache/<pkg-name>` convention is fairly common for packages having temporary files which need to persist while a module is installed (no more, no less).
3. If the _current working directory_ contains a `package.json` which has `appium` as any sort of (non-`file:`) dependency _or_ `$CWD/node_modules/appium` is a resolvable module, `APPIUM_HOME` defaults to `cwd`.
4. "Install" and "link" lockfiles (see `lib/cli/npm`) have also moved from `$APPIUM_HOME` to `$APPIUM_HOME/node_modules/.cache/appium`.
5. The `runExtensionCommand()` function in the `cli/extension` module no longer accepts a `type` parameter, which can be derived from the `configObject` parameter anyway (redundant)
6. Loading of extensions (i.e. reading `extensions.yaml`) has been moved into its own function, `loadExtensions()` in `extension/index.js`.
7. `getActivePlugins` and `getActiveDrivers` have been moved here from `lib/main`.  Changed the signatures of these, since they don't actually need the entire `ParsedArgs` object.
8. `ext-config-io` module, which handles reading/writing `extensions.yaml` has been moved to `extension/manifest.js`.
9. The `installPath` property in `extensions.yaml` has been removed and is unneeded due to 1.
10. `read()` has been removed from `extension-config` and its subclasses.
11. Moved `ReadonlyMap` from `utils` to `schema/schema` module.  Probably so I didn't have to stub it in a test.
12. Moved `rootDir` from `utils` to `config`.
13. Removed `drivers` module; moved `findMatchingDriver` to `DriverConfig#findMatchingDriver`.  Removed `AppiumDriver#_findMatchingDriver`; calls `DriverConfig#findMatchingDriver` directly instead.
14. Removed `plugins` module; its contents now live in `constants`.
15. Dynamic determination of `APPIUM_HOME` now happens in the `env.resolveAppiumHome()` method of `@appium/support` (introduced in a previous commit).  It should not happen anywhere else, because it will be wrong.
16. Because the `lib` dir was becoming rather unwieldy, I moved modules associated with extension loading and config into an `extension` subdir
17. `getParser()` in `cli/parser` is no longer async; the async stuff it was doing moved into `loadExtensions()`.  `getParser()` can be used without calling `loadExtensions()` first (no extensions will be loaded)

## Summary

This enables installation of extensions via `npm`; e.g., `npm install appium-xcuitest-driver -D`.  Because `appium` usually manages the `extensions.yaml` (the "manifest"), this is not possible when installing modules via other means.  To handle this situation, if we have an `appium`-dep-containing `package.json` in `APPIUM_HOME`, a hash is taken of the `package.json`.  This hash is checked at runtime; if it has changed, `appium` will scan `node_modules` (_not_ `package.json`; we only care about extensions that are _actually installed_, which is different from how we handle an `appium` dep) for extensions, and the hash will be updated.  Extensions are defined as "modules having a `package.json` which contains an `appium` field which is an object of a particular shape".  When these are found, they are appended to `extensions.yaml`.  In theory, this allows a user to use `appium` _or_ `npm` (at their convenience) to manage extensions.

See the "when appium is a dependency" suite in `test/cli/cli-e2e-specs.js` for more context.

## Notes

- Added a `constants` module, which provides a centralized place for various constants.  This makes finding constants less cognitively demanding. 🙂  You may not like this; if you don't, the constants can be moved to more appropriate places.
- Added `extension/package-changed` module which is used to determine if a `package.json` has changed
- Many types are added/changed throughout.  See especially `extension/manifest` for many type definitions involving the shape of `extensions.yaml` and the `appium` prop of extensions' `package.json`.
- Reorganized some tests based on structure of `lib`.
- Split `extension-config-specs.js` into `driver-config-specs.js` and `plugin-config-specs.js`.
- Many refactors in now-fully-typed `cli-e2e-specs`; introduced some more helpers in `test/cli/cli-helpers.js` and used these.  Makes calling out to the `appium` executable from E2E tests a little easier.
- Introduced `test/extension/mocks` for DRY mocks, since many of the unit tests here now use the same ones.
- Consolidated fixtures into `test/fixtures`. Fixtures can always be found via the `resolveFixture()` method of `test/helpers.js`.

## TODO (before this lands)

- Instead of using `$CWD` for `APPIUM_HOME` if `appium` is a dep, we probably want to use `find-pkg-up` or something.  This should be okay, since if we find a `package.json` and `appium` _isn't_ a dep, we will just be using the default `APPIUM_HOME`.
- We _may_ also need to search `package.json` for known extensions, since it's possible to use them standalone.  However, I'm not sure if this use case needs `APPIUM_HOME` at all?

chore: vscode stuff

- change default build task to `dev`, which just transpiles in the background
- updated `test - current file` launch config for better debugging

chore(appium): peer review refactors

- The old class name of `Manifest` used to be `ExtConfigIO`, but I forgot to update these variable names.  `io` is now `manifest`, wherever used
- Created a more clear separation between the `create()` and `getInstance()` static methods of `DriverConfig`/`PluginConfig`.  `create()` should _only_ be used for instantiation, and `getInstance()` should _only_ be used if we have already instantiated the object with an associated `Manifest`. `create()` now _throws_ if the `Manifest` already has an association in place.  The reason this is split into two functions instead of just using `_.memoize()` is because of the options in the second parameter (`extData`, `logFn`), which would require the _same configuration object_ in order to return the already-created instance.  This is not a problem in `Manifest`, where the factory only accepts a single parameter.
- The `_instances` static method of `PluginConfig`/`DriverConfig` is now a `WeakMap`, keyed on a `Manifest` instance instead of the `appiumHome` string. This makes the relationship between them more explicit.
- Fixed some formatting
- Fixed type issues in schema tests, `grid-register` and its tests
- Made the constructor of `Manifest` private, created a memoized static method `getInstance()`; removed `getManifestInstance()` export.
- Refactored `let`-destructuring to the fancy new syntax I learned from @mykola-mokhnach
- Explained the meaning of `CONFIG_DATA_DRIVER_KEY` and `CONFIG_DATA_PLUGIN_KEY` in `manifest` module
- Replaced unnecessary use of `null` with `undefined` in `Manifest` class
- Removed runtime type check from `packageDidChange()`
- Had some fun renaming `ReadonlyMap` in `schema` module
2022-03-09 14:50:45 -08:00
Christopher Hiller 37e7b8266c chore: update wallaby & vscode configs 2022-03-09 14:50:45 -08:00
Christopher Hiller 4ef3323d1a feat(support): add env module
- `env` module exposes functions for determining `APPIUM_HOME`, where various files should live, etc., by examining the runtime environment
- fixed some functions in `fs` which unnecessarily used `this` (which prevented dereferencing)
- added `walk()` to `fs` which just exposes `klaw` (since `walkDir` has very limited behavior). this enables `walk()` to be used as an async iterator, which is handy.
- fixed a bunch of types in the `util` module. involved some actual code changes, but the original code only worked by chance.
- removed `strict` option from `util.coerceVersion()`, since the option isn't actually used anywhere.  this should be considered a breaking change if some module somewhere _else_ uses it and we consider it a public API.  I'm pretty sure that's not the case, so.
2022-03-09 14:50:45 -08:00
Christopher Hiller 1b29920485 fix(fake-driver): create cjs executable entry point
This driver wasn't working properly when used directly
2022-03-09 14:50:45 -08:00
Christopher Hiller 1954021af9 chore: typescript updates
- Upgrade TS to `next` tag.  It's "safe" to use using bleeding-edge TS here since we don't actually use it to compile anything
- Add a bunch of missing types: `find-root`, `klaw`, `lockfile`, `mv`, `ncp`, `rimraf`
2022-03-09 14:50:45 -08:00
Christopher Hiller 891d601ee7 chore(gulp-plugins): add test env for babel
When `BABEL_ENV=test` we should get better sourcemaps
2022-03-09 14:50:45 -08:00
Mykola Mokhnach 493c48d190 feat: Add a missing route for element shadow root (#16538) 2022-03-09 18:51:41 +01:00
Mykola Mokhnach 16b2e8f14b chore: Switch @dabh/colors to @colors/colors (#16539) 2022-03-09 18:51:24 +01:00
Jonathan Lipps 5abf852046 fix(appium): make sure logsink init happens first since it patches npmlog globally (fix #16519) 2022-03-08 07:29:27 -08:00
Kazuaki MatsuoandJonathan Lipps 9e41fc210e docs: update drivers (#16522)
* docs: update drivers

* use table

* merge the table

* merge the table

* simplify

* Apply suggestions from code review

Co-authored-by: Jonathan Lipps <jlipps@gmail.com>

Co-authored-by: Jonathan Lipps <jlipps@gmail.com>
2022-03-08 12:56:27 +09:00
Kazuaki MatsuoandChristopher Hiller ad08384e53 docs: merge docs from 1 to 2 (#16505)
* docs: merge docs from 1 to 2

* revert 2.0 docs

* update

* update from current master

* remove duplications

* tweak a bit

* Apply suggestions from code review

Co-authored-by: Christopher Hiller <boneskull@boneskull.com>

* Update docs/README.md

Co-authored-by: Christopher Hiller <boneskull@boneskull.com>

* Update docs/en/about-appium/getting-started.md

Co-authored-by: Christopher Hiller <boneskull@boneskull.com>

* Update docs/README.md

Co-authored-by: Christopher Hiller <boneskull@boneskull.com>

* Update docs/README.md

Co-authored-by: Christopher Hiller <boneskull@boneskull.com>

Co-authored-by: Christopher Hiller <boneskull@boneskull.com>
2022-03-04 16:22:44 +09:00
Christopher Hiller 2e15c85f44 chore(appium): remove ios-webkit-debug-proxy-launcher; closes #16486 2022-02-24 14:29:05 -08:00
Renovate Bot 2ed1fa8abc chore(): update dependency lint-staged to v12 2022-02-24 14:28:30 -08:00
Mykola Mokhnach 3c7ac49478 refactor(base-driver): Tune the logic for the destination logger extraction (#16488) 2022-02-23 11:11:41 +01:00
Mykola Mokhnach 83493941ee refactor: Make loggers connected to the particular driver instances (#16478) 2022-02-23 07:49:42 +01:00
Mykola Mokhnach a8315f3f87 fix(appium): Increase the default limit of process listeners (#16471) 2022-02-18 21:08:48 +01:00
Christopher Hiller 79772d7a4f test(base-driver): replace direct calls to sinon with a sandbox
This is safer, because test failures can happen due to lack of isolation and order in which tests are executed
2022-02-17 11:52:52 -08:00
Mykola Mokhnach 1165269644 fix: Update property name after lru-cache package bump (#16446) 2022-02-14 11:22:52 +01:00
Mykola Mokhnach 632b75227c chore(base-driver): Bump lru-cache (#16431) 2022-02-10 08:27:05 +01:00
Kazuaki Matsuo 5aae1ae8a7 fix: remove BASEDRIVER_HANDLED_SETTINGS (#16368) 2022-02-09 17:41:50 +01:00
Mykola Mokhnach a881ae992a feat(base-driver): Add the size validation of the passed settings objects (#16420) 2022-02-09 08:09:25 +01:00
Mykola Mokhnach ed50a38657 refactor: Allow any of createSession arguments to be W3C capabilities object (#16408) 2022-02-07 15:27:55 +01:00
Jonathan Lipps 42f4a2de2d Publish
- appium@2.0.0-beta.25
 - @appium/base-driver@8.2.4
 - @appium/doctor@1.16.9
 - @appium/fake-driver@3.2.4
 - @appium/opencv@1.0.1
 - @appium/support@2.55.4
 - @appium/test-support@1.3.11
@appium/base-driver@8.2.4 @appium/doctor@1.16.9 @appium/fake-driver@3.2.4 @appium/opencv@1.0.1 @appium/support@2.55.4 @appium/test-support@1.3.11 appium@2.0.0-beta.25
2022-01-21 12:07:01 -08:00
Jonathan Lipps 555b93bf55 refactor!(support): move opencv related functionality into its own package 2022-01-21 08:52:36 -08:00
Jonathan Lipps 9bb88e0ac8 fix!(support): migrate to opencv-bindings and away from opencv4nodejs 2022-01-21 08:52:36 -08:00
Christopher Hiller 7470ed00b2 fix(appium): make show-config more right
`--show-config` was not able to distinguish between defaults and values provided on the CLI.  now it does.  `--show-config` now displays (in this order):

1. any settings from the defaults (across Appium and any extensions)
2. any settings specified in config files
3. any settings specified on the CLI
4. the final merged configuration

Ref: #16340
2022-01-19 16:10:10 -08:00
Christopher Hiller eac88e5038 chore(appium): fix some formatting problems
- syntax highlighting can get weird with object literal types in docstrings; they need spaces
- ensure eslint doesn't try to lint `.d.ts` files
2022-01-19 16:10:10 -08:00
Jonathan Lipps ca90a11813 Publish
- appium@2.0.0-beta.24
 - @appium/base-driver@8.2.3
 - @appium/doctor@1.16.8
 - @appium/eslint-config-appium@5.0.1
 - @appium/fake-driver@3.2.3
 - @appium/gulp-plugins@6.0.1
 - @appium/support@2.55.3
 - @appium/test-support@1.3.10
@appium/base-driver@8.2.3 @appium/doctor@1.16.8 @appium/eslint-config-appium@5.0.1 @appium/fake-driver@3.2.3 @appium/gulp-plugins@6.0.1 @appium/support@2.55.3 @appium/test-support@1.3.10 appium@2.0.0-beta.24
2022-01-11 13:04:16 -08:00
Jonathan Lipps 7d8d547fbd fix(support): allow @u4/opencv4nodejs in addition to the old one, and promote it in doctor instead 2022-01-11 12:56:05 -08:00
Mykola Mokhnach 40a6f054dc fix: Switch colors package to a non-compomised repository (#16317) 2022-01-11 06:45:13 +01:00
Mykola Mokhnach d69fc6002c refactor(base-driver): Make configureApp helper more flexible (#16168) 2021-12-15 09:51:00 +01:00
Christopher Hiller af96879cfd feat(appium): add --show-config (#16207)
* feat(appium): rename --show-config to --show-build-info

* feat(appium): add --show-config

This adds a new CLI flag: `--show-config`.  When called, this will dump the values of a) arguments to the `init()` function of `main.js` _or_ args passed thru CLI, b) any config pulled from a config file, and c) the defaults as defined in schemas.

Each section is separated, and `undefined` values are omitted.

Instead of a JSON blob, the output just uses `console.dir()`.

To make this work, some refactors were needed:

- Use of `store_true` "action" for `argparse` in are now `store_const` with `const: true` because `store_true` sets the value to `false` if the flag is not present.  This essentially assigns the default value of the flag (`false`) before it should; default values must come from the schemas.
- Along those lines, removed default values from the "extra" boolean args in `args.js`
- The CLI parser now ignores `undefined` values of arguments

Other:

- Created some types for extension classes and added the `server` prop to `AppiumDriver`.
- Enabled TS checks on `lib/config.js` (where `showConfig()` lives) and `test/config-specs.js`
- Removed unnecessary call to `validate()` in `preflightChecks()`; CLI arguments are validated individually (defined in `lib/schema/cli-args.js`) and the config file is validated separately (defined in `lib/config-file.js`).
- Add more types to `main.js`; rewrite `getServerUpdaters` in lodashese for fun (which I am happy to revert)
- Fix missing type aliases in `test/cli/cli-helpers.js`
- Misc types/refactors in `config-specs.js`
- Update parser tests to reflect that `undefined` values and empty objects are eliminated from the parsed arguments

Notes:

- The `showBuildInfo()` test in `config-specs.js` (which is ostensibly a unit test) forks `git` and also seems to require network connectivity, at least on my box. This stuff should be stubbed out or moved into an E2E test.

Resolves #15672

* chore(appium): remove unused options in `toParserArgs()`
2021-12-14 11:47:10 -08:00
Kazuaki Matsuo 9a85a41b9e fix(base-driver): follow W3C capabilities more strictly (#16193)
* fix(base-driver): strict capabilities to follow W3C spec more strictly

* fix typo

* just leave a warning message
2021-12-12 01:49:20 +09:00
Renovate Bot bc86e2800e chore(): update dependency @types/chai to v4.3.0 2021-12-08 10:48:48 +00:00
Renovate Bot 25087c3ee0 chore(gulp-plugins): update dependency @types/node to v16.11.12 2021-12-07 11:30:18 +00:00
Christopher Hiller ab9e2458ee chore: add workflow_dispatch event trigger
update install script URL.
2021-12-03 11:53:22 -08:00
Christopher Hiller fa453a18db chore: restrict FOSSA workflow
This PR moves the FOSSA check from the Node workflow to its own.  It won't run if the API key secret is not present (which would be true when running PRs from forks).

In addition, the check

1. will only run on changes to any `package.json` in the monorepo
2. runs `fossa test` to fail upon failure (previously it would only fail upon _error_)
2021-12-03 11:53:22 -08:00
Christopher Hiller e074fee89f fix(appium): disallow unsupported schemas
Some theoretical schemas are not in any sort of shape Appium can use, so we now catch them as soon as possible (at the registration phase).

- adds  type guard
- adds
2021-12-03 11:47:43 -08:00
Christopher Hiller 20d95e4531 fix(appium): correctly apply extension defaults
Extensions were not correctly receiving the default values as specified in their schemas.  For example, in `xcuitest` driver, the `wdaLocalPort` option has a default value of `8100`, but this value would never make it to the driver.

The root cause was that `getDefaultsForSchema()` returns a _flattened_ object (which is useful for displaying to users as part of `getNonDefaultServerArgs()`), but by the time defaults should get assigned to parsed arguments in `main.js`, the parsed arguments object has already been expanded to a deeply-nested, non-flattened object.  So `"driver.driverName.argName": "value"` would be set in the args, but  not `{"driver": {"driverName": {"argName": "value"}}}`.  Furthermore, the properties of `cliArgs` are not prefixed with `<extType>.<extName>.`, but are just the arg name itself (which makes sense).

To address this, two main changes:

1. `getDefaultsForSchema(flatten = true)` (renamed from `getDefaultsFromSchema()`) now accepts a `flatten` flag, which will return a flat object using `<extType>.<extName>.`-style prefixes. This is useful (and less computationally intensive) for comparing defaults across the whole of Appium and its extensions.  This is _not_ useful when merging defaults into the parsed arguments object, however, as that object will be deeply-nested.  If `flatten` is `false`, a deeply-nested object will be returned, which is consumed by the `main` module when post-processing parsed CLI arguments and config file values.
2. Added `getDefaultsForExtension(extType, extName)` which acts like `getDefaultsForSchema(flatten = true)` _but_ only returns defaults for a particular extension _and_ strips the leading prefixes.  This is used by `assignCliArgsToExtension` in the `AppiumDriver` class.

Other changes:

1. `ArgSpec` now keeps a `rawDest` property which is like `dest` w/o the prefixes.
2. Make more types
3. Re-organize `driver-specs` unit test somewhat, and update to reflect changes.
2021-12-03 11:25:34 -08:00
Renovate Bot 86e5dc304e chore(): update dependency type-fest to v2.8.0 2021-12-02 10:50:37 +00:00
Jonathan Lipps 7b3893a362 fix(appium): fix incorrect handling of delete session with regard to plugin driver assignment
also take the opportunity to constantize a few more strings
2021-12-01 09:42:25 -08:00
Jonathan Lipps f51094157d chore(appium): make some appium plugins available via short name 2021-12-01 09:28:28 -08:00
Renovate Bot 0db3ec49f8 chore(gulp-plugins): update dependency yargs to v17.3.0 2021-12-01 15:51:46 +00:00
Renovate Bot 62f1894838 chore(gulp-plugins): update dependency eslint-plugin-promise to v5.2.0 2021-12-01 14:01:28 +00:00
Renovate Bot eafd06fa5a chore(): update dependency type-fest to v2.7.0 2021-12-01 12:27:28 +00:00
Renovate Bot 80e77e2681 chore(doctor): update dependency appium-adb to v8.17.0 2021-12-01 10:33:54 +00:00
Mykola Mokhnach e947204351 chore(fake-driver): Bump xmldom version (#16182) 2021-11-30 21:43:40 +01:00
Renovate Bot 1e4c3e6f6d chore(gulp-plugins): update dependency @types/node to v16.11.11 2021-11-30 10:23:02 +00:00
Mykola Mokhnach 07887b7c18 refactor(base-driver): Always assume the returned responses are in W3C format (#16175) 2021-11-29 22:55:48 +01:00