The peer dependency value is stored in the `extensions.yaml` manifest for each extension as `appiumVersion` (if present).
If the peer dependency is _not_ present, the user will be warned, but Appium will still try to load the extension (I have a feeling that most of the time, this will be fine). When warned, the user will receive information about available extension upgrades, if any.
This required some refactors in the `lib/extension/` dir. Extension validation was previously a synchronous process, but because we now (potentially) display information to the user about upgrades (which is async), validation must also be async. This means that the `ExtensionConfig` constructor (and the constructors of its subclasses) cannot run validation. Validation must happen after the config object is instantiated, which is handled in `loadExtensions()` of `lib/extension/index.js`. The constructor signatures have changed accordingly.
While extensions now soft-require a `peerDependencies.appium` field, in the monorepo, the value of this dependency is `file:../appium`. This is treated as a special case, and acts as if the dependency is just the current version of `appium` (as in its `package.json`). This is handled in `Manifest#addExtension()`.
To further support this, `appium` now exports `@appium/base-driver` as `driver`, `@appium/base-plugin` as `plugin`, and `@appium/support` as `support`. `tsconfig.json` files have changed in these affected packages.
In addition, a new reusable TS config file has been added for use with basic plugins.
# Conflicts:
# .eslintrc
# packages/appium/lib/extension/extension-config.js
# packages/appium/lib/extension/index.js
# packages/appium/lib/extension/manifest.js
# packages/appium/test/unit/extension/manifest.spec.js
# packages/appium/test/unit/extension/mocks.js
Moved the stuff in `test/setup-babel` into `test/setup` and then removed some cruft in the `test:*` scripts of each package referencing `test/setup-babel`
* chore: ban direct usage of sinon
Calling `sinon.stub()`, `sinon.mock()` etc., directly is error-prone. Care must be taken to explicitly restore any stub created.
Using a sandbox (via `sinon.createSandbox()`), you don't need to remember to restore everything you fiddled with.
To that end, I've converted all direct `sinon` calls into sandbox calls and **BANNED** direct usage of `sinon` via ESLint.
# Conflicts:
# .eslintrc
* test(base-driver): replace restricted sinon.spy() usage in server-specs.js
* test(support): formatting
This change removes `gulp` and replaces it with plain ol' `babel` and `mocha`.
## `appium`
- No gulp.
- `test/` has been re-organized. All test files now end in the extension `.spec.js`, which is a recognized convention and understood by editors/IDEs. The tests are further split into `unit` and `e2e` subdirs. This makes working with both `babel` and `mocha` easier.
- The tests are _not_ run against the transpiled code; code is now transpiled on-the-fly via `@babel/register`. This only affects `appium`.
- `commands-yml/validator.js` moved to `scripts/parse-yml-commands.js`. It has been rewritten as a CJS module. `commands-yml/` should not contain `.js` files.
- `test/setup.js` is a new test harness specific to Appium, which loads & configures `@babel/register`. Eventually, the contents of this file can be moved into the root monorepo's `test/setup.js`, but the rest of the packages do not need `@babel/register`, so we avoid the overhead.
## `@appium/gulp-plugins`
- Unfortunately, due to the new `npm test` strategy (see below), we cannot use the `nyan` reporter. Or rather, we _can_, but will not see the animation. So the reporter is now set to default to `spec`.
- Modified tests so they didn't overwrite the actual `build` dir with transpiled fixtures, which is what was happening. This was causing failures depending on the transpile/test order.
## All Packages
- All packages now have their own `build`, `test`, `test:e2e` and `dev` (just build + watch mode) npm scripts. This makes running a complete build easier, since each package can now provide its own appropriate command. This is _mostly_ just `gulp once` (where `gulp` was used before), except for `appium`, where `@babel/cli` is used directly.
- This is what happens when `npm test` is run from the monorepo (in order):
1. All packages are built (in parallel) by running `npm run build` in each folder (via `lerna`). See `pretest`
2. All code is linted directly via `eslint`.
3. All _unit tests_ are run w/ `npm test` in each folder, having assumed transpilation already occurred (if necessary).
- `npm run e2e-test` runs the `npm run test:e2e` in each folder. No transpilation occurs! Careful.
- All scripts are expected to live in `packages/*/scripts`, and this directory enforces CJS via ESLint. `postinstall.js` moved, as well as `check-npm-pack-files.js`. `generate-schema-declarations.mjs` moved from the root `scripts/` dir into `packages/appium/scripts/`; it's now CJS instead of ESM.
- I had profiled running various things with `lerna run --parallel`, but it turns out this is not faster. I'm not sure why, but I think it may have something to do with streaming STDOUT/STDERR, or potentially the overhead of running child processes outweighs the time it takes to actually run tests and builds.
- The behavior of `lerna run` now mimicks `lerna exec`, which was "run stuff in serial, streaming the output". The default behavior of `lerna run` is "run stuff in parallel, buffering the output". Buffered output sucks, and streaming the output from all tasks at once creates chaos. To override this behavior, you'll see `--parallel --concurrency=8 --prefix` for tasks that can truly be parallelized, like transpilation. The number 8 is the "maximum", and CI usually won't have more than 2 cores available anyway.
- When run in CI, Mocha runs with `--forbid-only`, which will fail if there's an `.only()` somewhere in the tests. Further, it forces color output.
## Etc.
- Updated Wallaby config, `.gitignore`, `.eslintignore`.
- Sorted `package.json` files
- Removed `watch` and `coverage` scripts which were broken anyway.
chore(appium): fix schema json path issues
- the path to the JSON schema is now correct: `lib/appium-config-schema.json`
- add `log-symbols` to devdeps for niceness. this is already a transitive dep
- add `npm start` script to run appium server
- add `npm run doctor` convenience script to run doctor
- renamed `clean` script to `reinstall`
- added new `clean` script to just clean
- updated the "appium from source" doc
this pkg is unique in that it does not use `gulp`, so for now we tell lerna to always ignore it when running `lerna exec` across packages. it has no tests, but it's marginally useful to lint the `index.js`, so we'll do that (see `lint` script in root `package.json`).
the canonical way to handle plugin deps in a sharable config is to use `peerDependencies`, so it now uses `peerDependencies` instead of `dependencies`. these peer deps are installed by the dependencies of `@appium-gulp-plugins`. see [docs](https://eslint.org/docs/developer-guide/shareable-configs#publishing-a-shareable-config)
our root `.eslintrc` depends upon `@appium/eslint-config-appium` (which is not an unusual situation). to pull this off in a monorepo, a cheat is to `file:` schema in the dependency specifier of the root `package.json`.
also tweaked `lerna.json` to _always_ run `bootstrap` with the `--no-ci` flag. lerna will attempt to use `npm ci` if `CI` env var is present, but for that to work, we must have `package-lock.json` under version control.
- all tests changed were needed because of path issues. I was unable to get the tests working in their entirety _without_ adding `@appium/fake-driver` to the monorepo--it would have required a separate `npm install` step in `appium-fake-driver` due to the lack of its `devDependencies` and `prepare` script--so I figured I might as well pull it in now.
- deduped `package.json` scripts somewhat
- updated ESLint configuration to include `@appium/fake-driver`'s rule override
- sorted the root `package.json` because fussy
- added `wd` as a dev dep because `@appium/fake-driver` needs it