From e05b4cf9894f29ed3e387e68ccd430627078de75 Mon Sep 17 00:00:00 2001 From: Vinayak Kulkarni <19776877+vinayakkulkarni@users.noreply.github.com> Date: Wed, 22 Jul 2020 21:35:11 +0530 Subject: [PATCH 01/36] internal: enable semantic pull request support (#7946) Co-authored-by: Zach Bloomquist --- .github/semantic.yml | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .github/semantic.yml diff --git a/.github/semantic.yml b/.github/semantic.yml new file mode 100644 index 000000000000..4168a3cdeed9 --- /dev/null +++ b/.github/semantic.yml @@ -0,0 +1,2 @@ +# Always validate the PR title, and ignore the commits +titleOnly: true From a1c562f29febf8b423c4875b3d18429241913fb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?La=C3=ADs=20Tomaz?= Date: Thu, 23 Jul 2020 09:21:54 +0200 Subject: [PATCH 02/36] Run specs with name containing '+' (#8015) Co-authored-by: Chris Breiding --- packages/server/lib/util/escape_filename.ts | 2 ++ packages/server/test/e2e/4_controllers_spec.js | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/server/lib/util/escape_filename.ts b/packages/server/lib/util/escape_filename.ts index 30216e4ff2ca..c75b0a7ddfbb 100644 --- a/packages/server/lib/util/escape_filename.ts +++ b/packages/server/lib/util/escape_filename.ts @@ -1,6 +1,7 @@ const ampersandRe = /&/g const percentRe = /%/g const questionRe = /\?/g +const plusRe = /\+/g export function escapeFilenameInUrl (url: string) { // escape valid file name characters that cannot be used in URL @@ -8,4 +9,5 @@ export function escapeFilenameInUrl (url: string) { .replace(percentRe, '%25') // % .replace(ampersandRe, '%26') // & .replace(questionRe, '%3F') // ? -> it's only valid in Linux + .replace(plusRe, '%2B') // + https://github.com/cypress-io/cypress/issues/5909 } diff --git a/packages/server/test/e2e/4_controllers_spec.js b/packages/server/test/e2e/4_controllers_spec.js index 9d1c83ff4f84..d3d67403b412 100644 --- a/packages/server/test/e2e/4_controllers_spec.js +++ b/packages/server/test/e2e/4_controllers_spec.js @@ -20,8 +20,8 @@ describe('e2e plugins', () => { }) }) - it('handles specs with $, &, ? in file name', function () { - let relativeSpecPath = path.join('d?ir&1%', '%di?r2&', 's%pec&?.js') + it('handles specs with $, &, ?, + in file name', function () { + let relativeSpecPath = path.join('d?ir&1%', '%di?r2&', 's%p+ec&?.js') // windows doesn't support ? in file names if (process.platform === 'win32') { From 7bf12dbfbb072b961969e4e247179af7af031bd9 Mon Sep 17 00:00:00 2001 From: Chris Breiding Date: Thu, 23 Jul 2020 03:27:03 -0400 Subject: [PATCH 03/36] Make improvements to deploy doc (#8057) --- DEPLOY.md | 122 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 70 insertions(+), 52 deletions(-) diff --git a/DEPLOY.md b/DEPLOY.md index ce44fc4fe85d..52537c0d8c4b 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -1,7 +1,6 @@ # Deployment -Anyone can build the binary and NPM package, but you can only deploy the Cypress application -and publish the NPM module `cypress` if you are a member of the `cypress` NPM organization. +Anyone can build the binary and NPM package, but you can only deploy the Cypress application and publish the NPM module `cypress` if you are a member of the `cypress` NPM organization. > :information_source: See the [publishing](#publishing) section for how to build, test and publish a new official version of the binary and `cypress` NPM package. @@ -35,6 +34,32 @@ You can build the Cypress binary locally by running `yarn binary-build`. You can ## Publishing +### Prerequisites + +- Ensure you have the following permissions set up: + - An AWS account with permission to create AWS access keys for the Cypress CDN. + - Permissions for your npm account to publish the `cypress` package. + - Permissions to modify environment variables for `cypress` on CircleCI and AppVeyor. + - Permissions to update releases in ZenHub. + +- Set up the following environment variables: + - Cypress AWS access key and secret in `aws_credentials_json`, which looks like this: + ```text + aws_credentials_json={"bucket":"cdn.cypress.io","folder":"desktop","key":"...","secret":"..."} + ``` + - A [GitHub token](https://github.com/settings/tokens), a [CircleCI token](https://circleci.com/account/api), + and a `cypress-io` account-specific [AppVeyor token](https://ci.appveyor.com/api-keys) in `ci_json`: + ```text + ci_json={"githubToken":"...","circleToken":"...","appVeyorToken":"..."} + ``` + - You'll also need to put the GitHub token under its own variable and get a [ZenHub API token](https://app.zenhub.com/dashboard/tokens) for the `release-automations` step. + ```text + GITHUB_TOKEN="..." + ZENHUB_API_TOKEN="..." + ``` + - The `cypress-bot` GitHub app credentials are also needed. Ask another team member who has done a deploy for those. + - Tip: Use [as-a](https://github.com/bahmutov/as-a) to manage environment variables for different situations. + ### Before Publishing a New Version In order to publish a new `cypress` package to the NPM registry, we must build and test it across multiple platforms and test projects. This makes publishing *directly* into the NPM registry impossible. Instead, we have CI set up to do the following on every commit to `develop`: @@ -60,35 +85,14 @@ Once the `develop` branch for all test projects are reliably passing with the ne In the following instructions, "X.Y.Z" is used to denote the version of Cypress being published. -0. Make sure that if there is a new [`cypress-example-kitchensink`](https://github.com/cypress-io/cypress-example-kitchensink/releases) version, the corresponding dependency in [`packages/example`](./packages/example) has been updated to that new version. -1. Make sure you have the correct permissions set up before proceeding: - - An AWS account with permission to create AWS access keys for the Cypress CDN. - - Permissions for your npm account to publish the `cypress` package. - - Permissions to modify environment variables for `cypress` on CircleCI and AppVeyor. - - Permissions to update releases in ZenHub. -2. Make sure that you have the correct environment variables set up before proceeding: - - Cypress AWS access key and secret in `aws_credentials_json`, which looks like this: - ```text - aws_credentials_json={"bucket":"cdn.cypress.io","folder":"desktop","key":"...","secret":"..."} - ``` - - A [GitHub token](https://github.com/settings/tokens), a [CircleCI token](https://circleci.com/account/api), - and a `cypress-io` account-specific [AppVeyor token](https://ci.appveyor.com/api-keys) in `ci_json`: - ```text - ci_json={"githubToken":"...","circleToken":"...","appVeyorToken":"..."} - ``` - - You'll also need to put the GitHub token under its own variable and get a [ZenHub API token](https://app.zenhub.com/dashboard/tokens) for the `release-automations` step. - ```text - GITHUB_TOKEN="..." - ZENHUB_API_TOKEN="..." - ``` - - The `cypress-bot` GitHub app credentials are also needed. Ask another team member who has done a deploy for those. - - Tip: Use [as-a](https://github.com/bahmutov/as-a) to manage environment variables for different situations. -3. Use the `move-binaries` script to move the binaries for `` from `beta` to the `desktop` folder - for `` +1. If there is a new [`cypress-example-kitchensink`](https://github.com/cypress-io/cypress-example-kitchensink/releases) version, update the corresponding dependency in [`packages/example`](./packages/example) to that new version. + +2. Use the `move-binaries` script to move the binaries for `` from `beta` to the `desktop` folder for `` ```shell yarn move-binaries --sha --version ``` -4. Publish the new NPM package under the `dev` tag, using your personal NPM account. + +3. Publish the new NPM package under the `dev` tag, using your personal NPM account. - To find the link to the package file `cypress.tgz`: 1. In GitHub, go to the latest commit (the one whose sha you used in the last step). ![commit-link](https://user-images.githubusercontent.com/1157043/80608728-33fe6100-8a05-11ea-8b53-375303757b67.png) @@ -98,12 +102,14 @@ In the following instructions, "X.Y.Z" is used to denote the version of Cypress ```shell npm publish https://cdn.../npm/X.Y.Z//cypress.tgz --tag dev ``` -5. Double-check that the new version has been published under the `dev` tag using `npm info cypress` or [available-versions](https://github.com/bahmutov/available-versions). `latest` should still point to the previous version. Example output: + +4. Double-check that the new version has been published under the `dev` tag using `npm info cypress` or [available-versions](https://github.com/bahmutov/available-versions). `latest` should still point to the previous version. Example output: ```shell dist-tags: dev: 3.4.0 latest: 3.3.2 ``` -6. Test `cypress@X.Y.Z` to make sure everything is working. + +5. Test `cypress@X.Y.Z` to make sure everything is working. - Install the new version: `npm install -g cypress@X.Y.Z` - Run a quick, manual smoke test: - `cypress open` @@ -114,7 +120,8 @@ In the following instructions, "X.Y.Z" is used to denote the version of Cypress node scripts/test-other-projects.js --npm cypress@X.Y.Z --binary X.Y.Z ``` - Test the new version of Cypress against the Cypress dashboard repo. -7. Deploy the release-specific documentation and changelog in [cypress-documentation](https://github.com/cypress-io/cypress-documentation). + +6. Deploy the release-specific documentation and changelog in [cypress-documentation](https://github.com/cypress-io/cypress-documentation). - If there is not already a release-specific PR open, create one. You can use [`release-automations`](https://github.com/cypress-io/release-automations)'s `issues-in-release` tool to generate a starting point for the changelog, based off of ZenHub: ``` cd packages/issues-in-release @@ -123,37 +130,44 @@ In the following instructions, "X.Y.Z" is used to denote the version of Cypress - Ensure the changelog is up-to-date and has the correct date. - Merge any release-specific documentation changes into the main release PR. - Merging this PR into `develop` will deploy to `docs-staging` and then a PR will be automatically created against `master`. It will be automatically merged after it passes and will deploy to production. -8. Make the new NPM version the "latest" version by updating the dist-tag `latest` to point to the new version: + +7. Make the new NPM version the "latest" version by updating the dist-tag `latest` to point to the new version: ```shell npm dist-tag add cypress@X.Y.Z ``` -9. Run `binary-release` to update the [download server's manifest](https://download.cypress.io/desktop.json) and set the next CI version: + +8. Run `binary-release` to update the [download server's manifest](https://download.cypress.io/desktop.json) and set the next CI version: ```shell yarn run binary-release --version X.Y.Z ``` - > Note: Currently, there is an [issue setting the next CI version](https://github.com/cypress-io/cypress/issues/7176) that will cause this command to fail after setting the download manifest. You will need to manually update NEXT_DEV_VERSION by logging in to CircleCI and AppVeyor. -10. If needed, push out any updated changes to the links manifest to [`on.cypress.io`](https://github.com/cypress-io/cypress-services/tree/develop/packages/on). -11. If needed, deploy the updated [`cypress-example-kitchensink`][cypress-example-kitchensink] to `example.cypress.io` by following [these instructions under "Deployment"](./packages/example/README.md). -12. Update the releases in [ZenHub](https://app.zenhub.com/workspaces/test-runner-5c3ea3baeb1e75374f7b0708/reports/release): + > Note: Currently, there is an [issue setting the next CI version](https://github.com/cypress-io/cypress/issues/7176) that will cause this command to fail after setting the download manifest. You will need to manually update NEXT_DEV_VERSION by logging in to CircleCI and AppVeyor. This is noted in Step 16 below. + +9. If needed, push out any updated changes to the links manifest to [`on.cypress.io`](https://github.com/cypress-io/cypress-services/tree/develop/packages/on). + +10. If needed, deploy the updated [`cypress-example-kitchensink`][cypress-example-kitchensink] to `example.cypress.io` by following [these instructions under "Deployment"](./packages/example/README.md). + +11. Update the releases in [ZenHub](https://app.zenhub.com/workspaces/test-runner-5c3ea3baeb1e75374f7b0708/reports/release): - Close the current release in ZenHub. - Create a new patch release (and a new minor release, if this is a minor release) in ZenHub, and schedule them both to be completed 2 weeks from the current date. - Move all issues that are still open from the current release to the appropriate future release. -13. Bump `version` in [`package.json`](package.json), commit it to `develop`, and tag it with version: - ```shell - # commit and tag at the same time - git commit -a vX.Y.Z -m "release X.Y.Z [skip ci]" - # OR if you don't tag it with the commit, you can tag it after - git commit -m "release X.Y.Z [skip ci]" - git log --pretty=oneline # copy sha of the previous commit +12. Bump `version` in [`package.json`](package.json), commit it to `develop`, tag it with the version, and push the tag up: + ```shell + git commit -am "release X.Y.Z [skip ci]" + git log --pretty=oneline + # copy sha of the previous commit git tag -a vX.Y.Z + git push origin vX.Y.Z ``` -14. Push the tag up: +13. Merge `develop` into `master` and push both branches up. ```shell - git push origin vX.Y.Z + git push origin develop + git checkout master + git merge develop + git push origin master ``` -15. Merge `develop` into `master` and push that branch up. -16. Inside of [cypress-io/release-automations][release-automations]: + +14. Inside of [cypress-io/release-automations][release-automations]: - Publish GitHub release to [cypress-io/cypress/releases](https://github.com/cypress-io/cypress/releases) using package `set-releases`: ```shell cd packages/set-releases && npm run release-log -- --version X.Y.Z @@ -162,9 +176,12 @@ In the following instructions, "X.Y.Z" is used to denote the version of Cypress ```shell cd packages/issues-in-release && npm run do:comment -- --release X.Y.Z ``` -17. Publish a new docker image in [`cypress-docker-images`](https://github.com/cypress-io/cypress-docker-images) under `included` for the new cypress version. -18. Decide on the next version that we will work on. For example, if we have just released `3.7.0` we probably will work on `3.7.1` next. Set it on [CI machines](#set-next-version-on-cis). -19. Update example projects to the new version. For most projects, you can go to the Renovate dependency issue and check the box next to `Update dependency cypress to X.Y.Z`. It will automatically create a PR. Once it passes, you can merge it. Try updating at least the following projects: + +15. Publish a new docker image in [`cypress-docker-images`](https://github.com/cypress-io/cypress-docker-images) under `included` for the new cypress version. + +16. Decide on the next version that we will work on. For example, if we have just released `3.7.0` we probably will work on `3.7.1` next. Set it on [CI machines](#set-next-version-on-cis). + +17. Update example projects to the new version. For most projects, you can go to the Renovate dependency issue and check the box next to `Update dependency cypress to X.Y.Z`. It will automatically create a PR. Once it passes, you can merge it. Try updating at least the following projects: - [cypress-example-todomvc](https://github.com/cypress-io/cypress-example-todomvc/issues/99) - [cypress-example-todomvc-redux](https://github.com/cypress-io/cypress-example-todomvc-redux/issues/1) - [cypress-example-realworld](https://github.com/cypress-io/cypress-example-realworld/issues/2) @@ -175,7 +192,8 @@ In the following instructions, "X.Y.Z" is used to denote the version of Cypress - [cypress-example-piechopper](https://github.com/cypress-io/cypress-example-piechopper/issues/75) - [cypress-documentation](https://github.com/cypress-io/cypress-documentation/issues/1313) - [cypress-example-docker-compose](https://github.com/cypress-io/cypress-example-docker-compose) - Doesn't have a Renovate issue, but will auto-create and auto-merge non-major Cypress updates as long as the tests pass. -20. Check if any test or example repositories have a branch for testing the features or fixes from the newly published version `x.y.z`. The branch should also be named `x.y.z`. Check all `cypress-test-*` and `cypress-example-*` repositories, and if there is a branch named `x.y.z`, merge it into `master`. + +18. Check if any test or example repositories have a branch for testing the features or fixes from the newly published version `x.y.z`. The branch should also be named `x.y.z`. Check all `cypress-test-*` and `cypress-example-*` repositories, and if there is a branch named `x.y.z`, merge it into `master`. **Test Repos** From 8cf846bc57ee5bc8691fd5e460b746a5d6431b8f Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Thu, 23 Jul 2020 14:05:34 -0400 Subject: [PATCH 04/36] fix: AST rewriting when inline script is very long (#8048) * Promisify html rewrite Co-authored-by: Zach Bloomquist --- .../rewriter/__snapshots__/html-spec.ts.js | 6 +++- packages/rewriter/lib/html.ts | 8 +++-- packages/rewriter/lib/threads/worker.ts | 4 +-- packages/rewriter/test/unit/html-spec.ts | 34 +++++++++++-------- 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/packages/rewriter/__snapshots__/html-spec.ts.js b/packages/rewriter/__snapshots__/html-spec.ts.js index 4b124d2903a3..2731b513b275 100644 --- a/packages/rewriter/__snapshots__/html-spec.ts.js +++ b/packages/rewriter/__snapshots__/html-spec.ts.js @@ -19,7 +19,7 @@ exports['html rewriter .rewriteHtmlJs rewrites a real-ish document with sourcema "url": "http://example.com/foo.html:0", "js": "\n if (top != self) run()\n if (top!=self) run()\n if (self !== top) run()\n if (self!==top) run()\n if (self === top) return\n if (top.location!=self.location&&(top.location.href=self.location.href)) run()\n if (top.location != self.location) run()\n if (top.location != location) run()\n if (self.location != top.location) run()\n if (parent.frames.length > 0) run()\n if (window != top) run()\n if (window.top !== window.self) run()\n if (window.top!==window.self) run()\n if (window.self != window.top) run()\n if (window.top != window.self) run()\n if (window[\"top\"] != window[\"parent\"]) run()\n if (window['top'] != window['parent']) run()\n if (window[\"top\"] != self['parent']) run()\n if (parent && parent != window) run()\n if (parent && parent != self) run()\n if (parent && window != parent) run()\n if (parent && self != parent) run()\n if (parent && parent.frames && parent.frames.length > 0) run()\n if ((self.parent && !(self.parent === self)) && (self.parent.frames.length != 0)) run()\n if (parent !== null && parent.tag !== 'HostComponent' && parent.tag !== 'HostRoot') { }\n if (null !== parent && parent.tag !== 'HostComponent' && parent.tag !== 'HostRoot') { }\n if (top===self) return\n if (top==self) return\n " }, - "html": "\n \n top1\n settop\n settopbox\n parent1\n grandparent\n grandparents\n topFoo\n topFoo.window\n topFoo.window != topFoo\n parentFoo\n parentFoo.window\n parentFoo.window != parentFoo\n\n
\n
\n
\n\n parent()\n foo.parent()\n top()\n foo.top()\n foo(\"parent\")\n foo(\"top\")\n\n const parent = () => { bar: 'bar' }\n\n parent.bar\n\n \n \n" + "html": "\n \n top1\n settop\n settopbox\n parent1\n grandparent\n grandparents\n topFoo\n topFoo.window\n topFoo.window != topFoo\n parentFoo\n parentFoo.window\n parentFoo.window != parentFoo\n\n
\n
\n
\n\n parent()\n foo.parent()\n top()\n foo.top()\n foo(\"parent\")\n foo(\"top\")\n\n const parent = () => { bar: 'bar' }\n\n parent.bar\n\n \n \n\n" } exports['html rewriter .rewriteHtmlJs with inline scripts rewrites inline JS with no type 1'] = ` @@ -33,3 +33,7 @@ exports['html rewriter .rewriteHtmlJs with inline scripts rewrites inline JS wit exports['html rewriter .rewriteHtmlJs with inline scripts does not rewrite non-JS inline 1'] = ` ` + +exports['html rewriter .rewriteHtmlJs with inline scripts rewrites extra long JS string 1'] = ` + +` diff --git a/packages/rewriter/lib/html.ts b/packages/rewriter/lib/html.ts index d3cab45b01e0..1a498323cbbf 100644 --- a/packages/rewriter/lib/html.ts +++ b/packages/rewriter/lib/html.ts @@ -14,7 +14,7 @@ export function HtmlJsRewriter (url: string, deferSourceMapRewrite?: DeferSource return rewriter } -export function rewriteHtmlJs (url: string, html: string, deferSourceMapRewrite?: DeferSourceMapRewriteFn): string { +export function rewriteHtmlJs (url: string, html: string, deferSourceMapRewrite?: DeferSourceMapRewriteFn): Promise { let out = '' const rewriter = HtmlJsRewriter(url, deferSourceMapRewrite) @@ -24,5 +24,9 @@ export function rewriteHtmlJs (url: string, html: string, deferSourceMapRewrite? rewriter.end(html) - return out + return new Promise((resolve) => { + rewriter.on('end', () => { + resolve(out) + }) + }) } diff --git a/packages/rewriter/lib/threads/worker.ts b/packages/rewriter/lib/threads/worker.ts index 24d029827906..dd4de569863d 100644 --- a/packages/rewriter/lib/threads/worker.ts +++ b/packages/rewriter/lib/threads/worker.ts @@ -16,7 +16,7 @@ parentPort!.postMessage(true) let _idCounter = 0 -parentPort!.on('message', (req: RewriteRequest) => { +parentPort!.on('message', async (req: RewriteRequest) => { if (req.shutdown) { return process.exit() } @@ -58,7 +58,7 @@ parentPort!.on('message', (req: RewriteRequest) => { } try { - const output = _getOutput() + const output = await _getOutput() _reply({ output, threadMs: _getThreadMs() }) } catch (error) { diff --git a/packages/rewriter/test/unit/html-spec.ts b/packages/rewriter/test/unit/html-spec.ts index 3d655049ad23..f53e2ae3f82f 100644 --- a/packages/rewriter/test/unit/html-spec.ts +++ b/packages/rewriter/test/unit/html-spec.ts @@ -10,21 +10,21 @@ const rewriteNoSourceMap = (html) => rewriteHtmlJs(URL, html) describe('html rewriter', function () { context('.rewriteHtmlJs', function () { // https://github.com/cypress-io/cypress/issues/2393 - it('strips SRI', function () { - snapshot(rewriteNoSourceMap('')) + snapshot(await rewriteNoSourceMap('')) // should preserve namespaced attrs and still rewrite if no `type` - snapshot(rewriteNoSourceMap('')) + it('rewrites inline JS with no type', async function () { + snapshot(await rewriteNoSourceMap('')) }) - it('rewrites inline JS with type', function () { - snapshot(rewriteNoSourceMap('')) + it('rewrites inline JS with type', async function () { + snapshot(await rewriteNoSourceMap('')) }) - it('does not rewrite non-JS inline', function () { - snapshot(rewriteNoSourceMap('')) + it('does not rewrite non-JS inline', async function () { + snapshot(await rewriteNoSourceMap('')) }) - it('ignores invalid inline JS', function () { + it('ignores invalid inline JS', async function () { const str = '' - expect(rewriteNoSourceMap(str)).to.eq(str) + expect(await rewriteHtmlJs(URL, str)).to.eq(str) + }) + + it('rewrites extra long JS string', async function () { + snapshot(await rewriteNoSourceMap('')) }) }) }) From 3ab9643f5fc695484afa5278c85f20752379f428 Mon Sep 17 00:00:00 2001 From: Adam Stachowicz Date: Fri, 24 Jul 2020 05:21:17 +0000 Subject: [PATCH 05/36] docs: NPM -> npm (#8072) https://github.com/cypress-io/cypress/pull/8071#pullrequestreview-454136175 --- DEPLOY.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/DEPLOY.md b/DEPLOY.md index 52537c0d8c4b..7c29be7a8fd7 100644 --- a/DEPLOY.md +++ b/DEPLOY.md @@ -1,24 +1,24 @@ # Deployment -Anyone can build the binary and NPM package, but you can only deploy the Cypress application and publish the NPM module `cypress` if you are a member of the `cypress` NPM organization. +Anyone can build the binary and npm package, but you can only deploy the Cypress application and publish the npm module `cypress` if you are a member of the `cypress` npm organization. > :information_source: See the [publishing](#publishing) section for how to build, test and publish a -new official version of the binary and `cypress` NPM package. +new official version of the binary and `cypress` npm package. ## Building Locally -### Building the NPM package +### Building the npm package > :warning: Note: The steps in this section are automated in CI, and you should not need to do them yourself when publishing. -Building a new NPM package is very quick. +Building a new npm package is very quick. - Increment the version in the root `package.json` - `yarn build --scope cypress` The steps above: -- Build the `cypress` NPM package +- Build the `cypress` npm package - Transpile the code into ES5 to be compatible with the common Node versions - Put the result into the [`cli/build`](./cli/build) folder. @@ -26,7 +26,7 @@ The steps above: > :warning: Note: The steps in this section are automated in CI, and you should not need to do them yourself when publishing. -The NPM package requires a corresponding binary of the same version. In production, it will try to retrieve the binary from the Cypress CDN if it is not cached locally. +The npm package requires a corresponding binary of the same version. In production, it will try to retrieve the binary from the Cypress CDN if it is not cached locally. You can build the Cypress binary locally by running `yarn binary-build`. You can use Docker to build a Linux binary by running `yarn binary-build-linux`. @@ -62,12 +62,12 @@ You can build the Cypress binary locally by running `yarn binary-build`. You can ### Before Publishing a New Version -In order to publish a new `cypress` package to the NPM registry, we must build and test it across multiple platforms and test projects. This makes publishing *directly* into the NPM registry impossible. Instead, we have CI set up to do the following on every commit to `develop`: +In order to publish a new `cypress` package to the npm registry, we must build and test it across multiple platforms and test projects. This makes publishing *directly* into the npm registry impossible. Instead, we have CI set up to do the following on every commit to `develop`: -1. Build the NPM package with the new target version baked in. +1. Build the npm package with the new target version baked in. 2. Build the Linux/Mac binaries on CircleCI and build Windows on AppVeyor. -3. Upload the binaries and the new NPM package to `cdn.cypress.io` under the "beta" folder. -4. Launch the test projects like [cypress-test-node-versions](https://github.com/cypress-io/cypress-test-node-versions) and [cypress-test-example-repos](https://github.com/cypress-io/cypress-test-example-repos) using the newly-uploaded package & binary instead of installing from the NPM registry. That installation looks like this: +3. Upload the binaries and the new npm package to `cdn.cypress.io` under the "beta" folder. +4. Launch the test projects like [cypress-test-node-versions](https://github.com/cypress-io/cypress-test-node-versions) and [cypress-test-example-repos](https://github.com/cypress-io/cypress-test-example-repos) using the newly-uploaded package & binary instead of installing from the npm registry. That installation looks like this: ```shell export CYPRESS_INSTALL_BINARY=https://cdn.../binary///cypress.zip npm i https://cdn.../npm///cypress.tgz @@ -92,13 +92,13 @@ In the following instructions, "X.Y.Z" is used to denote the version of Cypress yarn move-binaries --sha --version ``` -3. Publish the new NPM package under the `dev` tag, using your personal NPM account. +3. Publish the new npm package under the `dev` tag, using your personal npm account. - To find the link to the package file `cypress.tgz`: 1. In GitHub, go to the latest commit (the one whose sha you used in the last step). ![commit-link](https://user-images.githubusercontent.com/1157043/80608728-33fe6100-8a05-11ea-8b53-375303757b67.png) 2. Scroll down past the changes to the comments. The first comment should be a `cypress-bot` comment that includes a line beginning `npm install ...`. Grab the `https://cdn.../npm/X.Y.Z//cypress.tgz` link. ![cdn-tgz-link](https://user-images.githubusercontent.com/1157043/80608736-3791e800-8a05-11ea-8d75-e4f80128e857.png) - - Publish to the NPM registry straight from the URL: + - Publish to the npm registry straight from the URL: ```shell npm publish https://cdn.../npm/X.Y.Z//cypress.tgz --tag dev ``` @@ -131,7 +131,7 @@ In the following instructions, "X.Y.Z" is used to denote the version of Cypress - Merge any release-specific documentation changes into the main release PR. - Merging this PR into `develop` will deploy to `docs-staging` and then a PR will be automatically created against `master`. It will be automatically merged after it passes and will deploy to production. -7. Make the new NPM version the "latest" version by updating the dist-tag `latest` to point to the new version: +7. Make the new npm version the "latest" version by updating the dist-tag `latest` to point to the new version: ```shell npm dist-tag add cypress@X.Y.Z ``` From dbe88dad15325b08acdbe601a7af494b3fd998b0 Mon Sep 17 00:00:00 2001 From: Przemek Date: Mon, 27 Jul 2020 21:03:06 +0200 Subject: [PATCH 06/36] fix: cy.route swallows the error about missing fixture #7818 (#7983) --- .../cypress/integration/commands/fixtures_spec.js | 4 ++++ .../driver/cypress/integration/commands/xhr_spec.js | 13 +++++++++++++ packages/driver/src/cy/commands/fixtures.js | 6 ++---- packages/driver/src/cy/commands/xhr.js | 11 ++++++++++- 4 files changed, 29 insertions(+), 5 deletions(-) diff --git a/packages/driver/cypress/integration/commands/fixtures_spec.js b/packages/driver/cypress/integration/commands/fixtures_spec.js index f8a547ed411f..254afb7879b9 100644 --- a/packages/driver/cypress/integration/commands/fixtures_spec.js +++ b/packages/driver/cypress/integration/commands/fixtures_spec.js @@ -50,6 +50,10 @@ describe('src/cy/commands/fixtures', () => { cy.fixture('example').should('deep.eq', { example: true }) }) + it('works with null.json', () => { + cy.fixture('null.json').should('equal', null) + }) + it('can read a fixture without extension with multiple dots in the name', () => { cy.fixture('foo.bar.baz').should('deep.eq', { quux: 'quuz' }) }) diff --git a/packages/driver/cypress/integration/commands/xhr_spec.js b/packages/driver/cypress/integration/commands/xhr_spec.js index 3aa251f132d2..a29bec5ccaab 100644 --- a/packages/driver/cypress/integration/commands/xhr_spec.js +++ b/packages/driver/cypress/integration/commands/xhr_spec.js @@ -2150,6 +2150,19 @@ describe('src/cy/commands/xhr', () => { .wrap({ foo: 'bar' }).as('foo') .route(/foo/, '@bar') }) + + // https://github.com/cypress-io/cypress/issues/7818 + it('throws when fixture cannot be found', (done) => { + cy.on('fail', (err) => { + expect(err.message).to.contains('A fixture file could not be found at any of the following paths:') + done() + }) + + cy.route(/foo/, 'fx:NOT_EXISTING_FILE_FIXTURE') + cy.window().then((win) => { + win.$.get('/foo') + }) + }) }) describe('.log', () => { diff --git a/packages/driver/src/cy/commands/fixtures.js b/packages/driver/src/cy/commands/fixtures.js index 6e088516f3e1..c357e68ff3bb 100644 --- a/packages/driver/src/cy/commands/fixtures.js +++ b/packages/driver/src/cy/commands/fixtures.js @@ -58,10 +58,8 @@ module.exports = (Commands, Cypress, cy, state, config) => { return Cypress.backend('get:fixture', fixture, _.pick(options, 'encoding')) .timeout(timeout) .then((response) => { - const err = response.__error - - if (err) { - return $errUtils.throwErr(err) + if (response && response.__error) { + return $errUtils.throwErr(response.__error) } // add the fixture to the cache diff --git a/packages/driver/src/cy/commands/xhr.js b/packages/driver/src/cy/commands/xhr.js index 4a20a13b7a52..b2a26ac7bb15 100644 --- a/packages/driver/src/cy/commands/xhr.js +++ b/packages/driver/src/cy/commands/xhr.js @@ -200,7 +200,7 @@ const startXhrServer = (cy, state, config) => { }, onFixtureError (xhr, err) { - err = $errUtils.cypressErr(err) + err = $errUtils.cypressErr({ message: err }) return this.onError(xhr, err) }, @@ -471,6 +471,15 @@ module.exports = (Commands, Cypress, cy, state, config) => { }) } + // look ahead to see if fixture exists + const fixturesRe = /^(fx:|fixture:)/ + + if (hasResponse && fixturesRe.test(options.response)) { + const fixtureName = options.response.replace(fixturesRe, '') + + return cy.now('fixture', fixtureName).then(() => route()) + } + return route() } From fbce860f310e71b16a86e8a676f51696f2d45c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?La=C3=ADs=20Tomaz?= Date: Tue, 28 Jul 2020 07:09:38 +0200 Subject: [PATCH 07/36] feat: Add configuration option for disabling screenshots (#8083) Co-authored-by: Jennifer Shehane --- cli/schema/cypress.schema.json | 5 +++++ cli/types/cypress.d.ts | 5 +++++ .../integration/commands/screenshot_spec.js | 19 +++++++++++++++++++ packages/driver/src/cy/commands/screenshot.js | 2 +- packages/server/lib/config.js | 3 +++ packages/server/test/unit/config_spec.js | 16 ++++++++++++++++ 6 files changed, 49 insertions(+), 1 deletion(-) diff --git a/cli/schema/cypress.schema.json b/cli/schema/cypress.schema.json index f68a30ee6c18..5b964c63df85 100644 --- a/cli/schema/cypress.schema.json +++ b/cli/schema/cypress.schema.json @@ -124,6 +124,11 @@ "default": "cypress/plugins/index.js", "description": "Path to plugins file. (Pass false to disable)" }, + "screenshotOnRunFailure": { + "type": "boolean", + "default": true, + "description": "Whether Cypress will take a screenshot when a test fails during cypress run" + }, "screenshotsFolder": { "type": "string", "default": "cypress/screenshots", diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index 7c912f74929f..9daebefccd14 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -2421,6 +2421,11 @@ declare namespace Cypress { * @example 1.2.3 */ resolvedNodeVersion: string + /** + * Whether Cypress will take a screenshot when a test fails during cypress run. + * @default true + */ + screenshotOnRunFailure: boolean /** * Path to folder where screenshots will be saved from [cy.screenshot()](https://on.cypress.io/screenshot) command or after a headless or CI run’s test failure * @default "cypress/screenshots" diff --git a/packages/driver/cypress/integration/commands/screenshot_spec.js b/packages/driver/cypress/integration/commands/screenshot_spec.js index f090de43a898..dcb584a8d9d3 100644 --- a/packages/driver/cypress/integration/commands/screenshot_spec.js +++ b/packages/driver/cypress/integration/commands/screenshot_spec.js @@ -94,6 +94,25 @@ describe('src/cy/commands/screenshot', () => { }) }) + it('is noop when screenshotOnRunFailure is false', () => { + Cypress.config('isInteractive', false) + Cypress.config('screenshotOnRunFailure', false) + + cy.spy(Cypress, 'action').log(false) + + const test = { + err: new Error, + } + + const runnable = cy.state('runnable') + + Cypress.action('runner:runnable:after:run:async', test, runnable) + .then(() => { + expect(Cypress.action).not.to.be.calledWith('cy:test:set:state') + expect(Cypress.automation).not.to.be.called + }) + }) + it('sends before/after events', function () { Cypress.config('isInteractive', false) this.screenshotConfig.scale = false diff --git a/packages/driver/src/cy/commands/screenshot.js b/packages/driver/src/cy/commands/screenshot.js index 7dce851f209f..708383cb6a96 100644 --- a/packages/driver/src/cy/commands/screenshot.js +++ b/packages/driver/src/cy/commands/screenshot.js @@ -388,7 +388,7 @@ module.exports = function (Commands, Cypress, cy, state, config) { Cypress.on('runnable:after:run:async', (test, runnable) => { const screenshotConfig = $Screenshot.getConfig() - if (!test.err || !screenshotConfig.screenshotOnRunFailure || config('isInteractive') || test.err.isPending) { + if (!test.err || !screenshotConfig.screenshotOnRunFailure || config('isInteractive') || test.err.isPending || !config('screenshotOnRunFailure')) { return } diff --git a/packages/server/lib/config.js b/packages/server/lib/config.js index ab75fec3140a..73dd6f57db0c 100644 --- a/packages/server/lib/config.js +++ b/packages/server/lib/config.js @@ -76,6 +76,7 @@ viewportHeight responseTimeout video taskTimeout videoCompression videoUploadOnPasses +screenshotOnRunFailure watchForFileChanges waitForAnimations resolvedNodeVersion nodeVersion resolvedNodePath @@ -142,6 +143,7 @@ const CONFIG_DEFAULTS = { video: true, videoCompression: 32, videoUploadOnPasses: true, + screenshotOnRunFailure: true, modifyObstructiveCode: true, chromeWebSecurity: true, waitForAnimations: true, @@ -212,6 +214,7 @@ const validationRules = { videoCompression: v.isNumberOrFalse, videosFolder: v.isString, videoUploadOnPasses: v.isBoolean, + screenshotOnRunFailure: v.isBoolean, viewportHeight: v.isNumber, viewportWidth: v.isNumber, waitForAnimations: v.isBoolean, diff --git a/packages/server/test/unit/config_spec.js b/packages/server/test/unit/config_spec.js index 1a153e2f0c6c..c4ac45aae0fd 100644 --- a/packages/server/test/unit/config_spec.js +++ b/packages/server/test/unit/config_spec.js @@ -593,6 +593,20 @@ describe('lib/config', () => { }) }) + context('screenshotOnRunFailure', () => { + it('passes if a boolean', function () { + this.setup({ screenshotOnRunFailure: false }) + + return this.expectValidationPasses() + }) + + it('fails if not a boolean', function () { + this.setup({ screenshotOnRunFailure: 42 }) + + return this.expectValidationFails('be a boolean') + }) + }) + context('viewportHeight', () => { it('passes if a number', function () { this.setup({ viewportHeight: 10 }) @@ -1125,6 +1139,7 @@ describe('lib/config', () => { video: { value: true, from: 'default' }, videoCompression: { value: 32, from: 'default' }, videoUploadOnPasses: { value: true, from: 'default' }, + screenshotOnRunFailure: { value: true, from: 'default' }, videosFolder: { value: 'cypress/videos', from: 'default' }, supportFile: { value: 'cypress/support', from: 'default' }, pluginsFile: { value: 'cypress/plugins', from: 'default' }, @@ -1201,6 +1216,7 @@ describe('lib/config', () => { video: { value: true, from: 'default' }, videoCompression: { value: 32, from: 'default' }, videoUploadOnPasses: { value: true, from: 'default' }, + screenshotOnRunFailure: { value: true, from: 'default' }, videosFolder: { value: 'cypress/videos', from: 'default' }, supportFile: { value: 'cypress/support', from: 'default' }, pluginsFile: { value: 'cypress/plugins', from: 'default' }, From 6beeb203fc57ef9392045a835dd36c9438a3fde8 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Tue, 28 Jul 2020 02:13:45 -0400 Subject: [PATCH 08/36] fix: Fix issue with open hook in IDE on rerun (#8097) --- packages/driver/src/cypress/mocha.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/driver/src/cypress/mocha.js b/packages/driver/src/cypress/mocha.js index eb35fdf69107..04a248533ef0 100644 --- a/packages/driver/src/cypress/mocha.js +++ b/packages/driver/src/cypress/mocha.js @@ -97,7 +97,7 @@ function getInvocationDetails (specWindow, config) { // firefox throws a different stack than chromium // which includes this file (mocha.js) and mocha/.../common.js at the top - if (specWindow.Cypress && specWindow.Cypress.browser.family === 'firefox') { + if (specWindow.Cypress && specWindow.Cypress.isBrowser('firefox')) { stack = $stackUtils.stackWithLinesDroppedFromMarker(stack, 'mocha/lib/interfaces/common.js') } @@ -114,7 +114,9 @@ function overloadMochaHook (fnName, suite, specWindow, config) { this._createHook = function (title, fn) { const hook = _createHook.call(this, title, fn) - hook.invocationDetails = getInvocationDetails(specWindow, config) + if (!hook.invocationDetails) { + hook.invocationDetails = getInvocationDetails(specWindow, config) + } return hook } @@ -131,7 +133,9 @@ function overloadMochaTest (suite, specWindow, config) { const _fn = suite.addTest suite.addTest = function (test) { - test.invocationDetails = getInvocationDetails(specWindow, config) + if (!test.invocationDetails) { + test.invocationDetails = getInvocationDetails(specWindow, config) + } return _fn.call(this, test) } From 508da38d1e3112ecb91dfc15766ae7f1d6ab8819 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Tue, 28 Jul 2020 12:43:57 -0400 Subject: [PATCH 09/36] fix: bug where cy.createSnapshot would interact with documents using custom elements (#8080) * fix: prevent XHR requests from getting stuck in an infinite retry loop --- .../cypress/fixtures/custom-elements.html | 29 +++++++++++++++++++ .../cypress/integration/cy/snapshot_spec.js | 24 +++++++++++++++ packages/driver/src/cy/snapshots.js | 7 ++++- 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 packages/driver/cypress/fixtures/custom-elements.html diff --git a/packages/driver/cypress/fixtures/custom-elements.html b/packages/driver/cypress/fixtures/custom-elements.html new file mode 100644 index 000000000000..611bddc44f48 --- /dev/null +++ b/packages/driver/cypress/fixtures/custom-elements.html @@ -0,0 +1,29 @@ + + + + Custom Elements + + + + + + + diff --git a/packages/driver/cypress/integration/cy/snapshot_spec.js b/packages/driver/cypress/integration/cy/snapshot_spec.js index 0faa9b7960ca..0e916033351b 100644 --- a/packages/driver/cypress/integration/cy/snapshot_spec.js +++ b/packages/driver/cypress/integration/cy/snapshot_spec.js @@ -166,4 +166,28 @@ describe('driver/src/cy/snapshots', () => { }) }) }) + + context('custom elements', () => { + beforeEach(() => { + cy.visit('/fixtures/custom-elements.html') + }) + + // https://github.com/cypress-io/cypress/issues/7187 + it('does not trigger constructor', () => { + const constructor = cy.stub(cy.state('window'), 'shadowScreenshotConstructor') + + cy.createSnapshot() + + expect(constructor).not.to.be.called + }) + + // https://github.com/cypress-io/cypress/issues/7187 + it('does not trigger attributeChangedCallback', () => { + const attributeChanged = cy.stub(cy.state('window'), 'shadowScreenshotAttributeChanged') + + cy.createSnapshot() + + expect(attributeChanged).not.to.be.called + }) + }) }) diff --git a/packages/driver/src/cy/snapshots.js b/packages/driver/src/cy/snapshots.js index 316ff0514288..52d4004f5729 100644 --- a/packages/driver/src/cy/snapshots.js +++ b/packages/driver/src/cy/snapshots.js @@ -147,7 +147,12 @@ const create = ($$, state) => { // TODO: throw error here if cy is undefined! - const $body = $$('body').clone() + // cloneNode can actually trigger functions attached to custom elements + // so we have to use importNode to clone the element + // to the outer doc and then reassign ownership to the original doc + // https://github.com/cypress-io/cypress/issues/7187 + // https://github.com/cypress-io/cypress/issues/1068 + const $body = $$(state('document').adoptNode(document.importNode($$('body')[0], true))) // for the head and body, get an array of all CSS, // whether it's links or style tags From 7da2c4d397d48131e5a0a50a9fae482b70747a94 Mon Sep 17 00:00:00 2001 From: Kukhyeon Heo Date: Wed, 29 Jul 2020 02:58:03 +0900 Subject: [PATCH 10/36] fix: add more should interface definitions. (#8068) --- cli/types/cypress.d.ts | 403 +++++++++++++++++++++++----- cli/types/tests/chainer-examples.ts | 43 +-- cli/types/tests/kitchen-sink.ts | 1 + 3 files changed, 370 insertions(+), 77 deletions(-) diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index 9daebefccd14..5dafff160f25 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -2838,7 +2838,7 @@ declare namespace Cypress { encoding: Encodings } - // Kind of onerous, but has a nice auto-complete. Also fallbacks at the end for custom stuff + // Kind of onerous, but has a nice auto-complete. /** * @see https://on.cypress.io/should * @@ -3029,6 +3029,22 @@ declare namespace Cypress { * @see https://on.cypress.io/assertions */ (chainer: 'be.undefined'): Chainable + /** + * Asserts that the target is strictly (`===`) equal to null. + * @example + * cy.wrap(null).should('be.null') + * @see http://chaijs.com/api/bdd/#method_null + * @see https://on.cypress.io/assertions + */ + (chainer: 'be.null'): Chainable + /** + * Asserts that the target is strictly (`===`) equal to NaN. + * @example + * cy.wrap(NaN).should('be.NaN') + * @see http://chaijs.com/api/bdd/#method_null + * @see https://on.cypress.io/assertions + */ + (chainer: 'be.NaN'): Chainable /** * Asserts that the target is a number or a date greater than or equal to the given number or date `start`, and less than or equal to the given number or date `finish` respectively. * However, it’s often best to assert that the target is equal to its expected value. @@ -3157,7 +3173,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_all * @see https://on.cypress.io/assertions */ - (chainer: 'have.all.keys', ...value: string[]): Chainable + (chainer: 'have.all.keys' | 'have.keys' | 'have.deep.keys' | 'have.all.deep.keys', ...value: string[]): Chainable /** * Causes all `.keys` assertions that follow in the chain to only require that the target have at least one of the given keys. This is the opposite of `.all`, which requires that the target have all of the given keys. * @example @@ -3165,7 +3181,15 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_any * @see https://on.cypress.io/assertions */ - (chainer: 'have.any.keys', ...value: string[]): Chainable + (chainer: 'have.any.keys' | 'include.any.keys', ...value: string[]): Chainable + /** + * Causes all `.keys` assertions that follow in the chain to require the target to be a superset of the expected set, rather than an identical set. + * @example + * cy.wrap({ a: 1, b: 2 }).should('include.all.keys', 'a', 'b') + * @see http://chaijs.com/api/bdd/#method_keys + * @see https://on.cypress.io/assertions + */ + (chainer: 'include.all.keys', ...value: string[]): Chainable /** * Asserts that the target has a property with the given key `name`. See the `deep-eql` project page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql. * @example @@ -3183,7 +3207,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_lengthof * @see https://on.cypress.io/assertions */ - (chainer: 'have.length', value: number): Chainable + (chainer: 'have.length' | 'have.lengthOf', value: number): Chainable /** * Asserts that the target’s `length` property is greater than to the given number `n`. * @example @@ -3192,7 +3216,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_lengthof * @see https://on.cypress.io/assertions */ - (chainer: 'have.length.greaterThan', value: number): Chainable + (chainer: 'have.length.greaterThan' | 'have.lengthOf.greaterThan', value: number): Chainable /** * Asserts that the target’s `length` property is greater than to the given number `n`. * @example @@ -3201,7 +3225,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_lengthof * @see https://on.cypress.io/assertions */ - (chainer: 'have.length.gt', value: number): Chainable + (chainer: 'have.length.gt' | 'have.lengthOf.gt' | 'have.length.above' | 'have.lengthOf.above', value: number): Chainable /** * Asserts that the target’s `length` property is greater than or equal to the given number `n`. * @example @@ -3210,7 +3234,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_lengthof * @see https://on.cypress.io/assertions */ - (chainer: 'have.length.gte', value: number): Chainable + (chainer: 'have.length.gte' | 'have.lengthOf.gte' | 'have.length.at.least' | 'have.lengthOf.at.least', value: number): Chainable /** * Asserts that the target’s `length` property is less than to the given number `n`. * @example @@ -3219,7 +3243,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_lengthof * @see https://on.cypress.io/assertions */ - (chainer: 'have.length.lessThan', value: number): Chainable + (chainer: 'have.length.lessThan' | 'have.lengthOf.lessThan', value: number): Chainable /** * Asserts that the target’s `length` property is less than to the given number `n`. * @example @@ -3228,7 +3252,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_lengthof * @see https://on.cypress.io/assertions */ - (chainer: 'have.length.lt', value: number): Chainable + (chainer: 'have.length.lt' | 'have.lengthOf.lt' | 'have.length.below' | 'have.lengthOf.below', value: number): Chainable /** * Asserts that the target’s `length` property is less than or equal to the given number `n`. * @example @@ -3237,7 +3261,15 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_lengthof * @see https://on.cypress.io/assertions */ - (chainer: 'have.length.lte', value: number): Chainable + (chainer: 'have.length.lte' | 'have.lengthOf.lte' | 'have.length.at.most' | 'have.lengthOf.at.most', value: number): Chainable + /** + * Asserts that the target’s `length` property is within `start` and `finish`. + * @example + * cy.wrap([1, 2, 3]).should('have.length.within', 1, 5) + * @see http://chaijs.com/api/bdd/#method_lengthof + * @see https://on.cypress.io/assertions + */ + (chainer: 'have.length.within' | 'have.lengthOf.within', start: number, finish: number): Chainable /** * Asserts that the target array has the same members as the given array `set`. * @example @@ -3245,7 +3277,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_members * @see https://on.cypress.io/assertions */ - (chainer: 'have.members', values: any[]): Chainable + (chainer: 'have.members' | 'have.deep.members', values: any[]): Chainable /** * Asserts that the target array has the same members as the given array where order matters. * @example @@ -3271,7 +3303,15 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_property * @see https://on.cypress.io/assertions */ - (chainer: 'have.property', property: string, value?: any): Chainable + (chainer: 'have.property' | 'have.nested.property' | 'have.own.property' | 'have.a.property' | 'have.deep.property' | 'have.deep.own.property' | 'have.deep.nested.property', property: string, value?: any): Chainable + /** + * Asserts that the target has its own property descriptor with the given key name. + * @example + * cy.wrap({a: 1}).should('have.ownPropertyDescriptor', 'a', { value: 1 }) + * @see http://chaijs.com/api/bdd/#method_ownpropertydescriptor + * @see https://on.cypress.io/assertions + */ + (chainer: 'have.ownPropertyDescriptor' | 'haveOwnPropertyDescriptor', name: string, descriptor?: PropertyDescriptor): Chainable /** * Asserts that the target string contains the given substring `str`. * @example @@ -3287,7 +3327,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_include * @see https://on.cypress.io/assertions */ - (chainer: 'include', value: any): Chainable + (chainer: 'include' | 'deep.include' | 'nested.include' | 'own.include' | 'deep.own.include' | 'deep.nested.include', value: any): Chainable /** * When the target is a string, `.include` asserts that the given string `val` is a substring of the target. * @example @@ -3295,21 +3335,29 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_members * @see https://on.cypress.io/assertions */ - (chainer: 'include.members', value: any[]): Chainable + (chainer: 'include.members' | 'include.ordered.members' | 'include.deep.ordered.members', value: any[]): Chainable /** * When one argument is provided, `.increase` asserts that the given function `subject` returns a greater number when it’s * invoked after invoking the target function compared to when it’s invoked beforehand. * `.increase` also causes all `.by` assertions that follow in the chain to assert how much greater of a number is returned. * It’s often best to assert that the return value increased by the expected amount, rather than asserting it increased by any amount. + * + * When two arguments are provided, `.increase` asserts that the value of the given object `subject`’s `prop` property is greater after + * invoking the target function compared to beforehand. + * * @example * let val = 1 * function addTwo() { val += 2 } * function getVal() { return val } * cy.wrap(addTwo).should('increase', getVal) + * + * const myObj = { val: 1 } + * function addTwo() { myObj.val += 2 } + * cy.wrap(addTwo).should('increase', myObj, 'val') * @see http://chaijs.com/api/bdd/#method_increase * @see https://on.cypress.io/assertions */ - (chainer: 'increase', value: object, property: string): Chainable + (chainer: 'increase', value: object, property?: string): Chainable /** * Asserts that the target matches the given regular expression `re`. * @example @@ -3362,6 +3410,50 @@ declare namespace Cypress { */ // tslint:disable-next-line ban-types (chainer: 'throw', error: Error | Function, expected?: string | RegExp): Chainable + /** + * Asserts that the target is a member of the given array list. + * @example + * cy.wrap(1).should('be.oneOf', [1, 2, 3]) + * @see http://chaijs.com/api/bdd/#method_oneof + * @see https://on.cypress.io/assertions + */ + (chainer: 'be.oneOf', list: ReadonlyArray): Chainable + /** + * Asserts that the target is extensible, which means that new properties can be added to it. + * @example + * cy.wrap({a: 1}).should('be.extensible') + * @see http://chaijs.com/api/bdd/#method_extensible + * @see https://on.cypress.io/assertions + */ + (chainer: 'be.extensible'): Chainable + /** + * Asserts that the target is sealed, which means that new properties can’t be added to it, and its existing properties can’t be reconfigured or deleted. + * @example + * let sealedObject = Object.seal({}) + * let frozenObject = Object.freeze({}) + * cy.wrap(sealedObject).should('be.sealed') + * cy.wrap(frozenObject).should('be.sealed') + * @see http://chaijs.com/api/bdd/#method_sealed + * @see https://on.cypress.io/assertions + */ + (chainer: 'be.sealed'): Chainable + /** + * Asserts that the target is frozen, which means that new properties can’t be added to it, and its existing properties can’t be reassigned to different values, reconfigured, or deleted. + * @example + * let frozenObject = Object.freeze({}) + * cy.wrap(frozenObject).should('be.frozen') + * @see http://chaijs.com/api/bdd/#method_frozen + * @see https://on.cypress.io/assertions + */ + (chainer: 'be.frozen'): Chainable + /** + * Asserts that the target is a number, and isn’t `NaN` or positive/negative `Infinity`. + * @example + * cy.wrap(1).should('be.finite') + * @see http://chaijs.com/api/bdd/#method_finite + * @see https://on.cypress.io/assertions + */ + (chainer: 'be.finite'): Chainable // chai.not /** @@ -3546,6 +3638,22 @@ declare namespace Cypress { * @see https://on.cypress.io/assertions */ (chainer: 'not.be.undefined'): Chainable + /** + * Asserts that the target is strictly (`===`) equal to null. + * @example + * cy.wrap(null).should('not.be.null') + * @see http://chaijs.com/api/bdd/#method_null + * @see https://on.cypress.io/assertions + */ + (chainer: 'not.be.null'): Chainable + /** + * Asserts that the target is strictly (`===`) equal to NaN. + * @example + * cy.wrap(NaN).should('not.be.NaN') + * @see http://chaijs.com/api/bdd/#method_nan + * @see https://on.cypress.io/assertions + */ + (chainer: 'not.be.NaN'): Chainable /** * Asserts that the target is not a number or a date greater than or equal to the given number or date `start`, and less than or equal to the given number or date `finish` respectively. * However, it’s often best to assert that the target is equal to its expected value. @@ -3657,7 +3765,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_all * @see https://on.cypress.io/assertions */ - (chainer: 'not.have.all.keys', ...value: string[]): Chainable + (chainer: 'not.have.all.keys' | 'not.have.keys' | 'not.have.deep.keys' | 'not.have.all.deep.keys', ...value: string[]): Chainable /** * Causes all `.keys` assertions that follow in the chain to only require that the target not have at least one of the given keys. This is the opposite of `.all`, which requires that the target have all of the given keys. * @example @@ -3665,7 +3773,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_any * @see https://on.cypress.io/assertions */ - (chainer: 'not.have.any.keys', ...value: string[]): Chainable + (chainer: 'not.have.any.keys' | 'not.include.any.keys', ...value: string[]): Chainable /** * Asserts that the target does not have a property with the given key `name`. See the `deep-eql` project page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql. * @example @@ -3683,7 +3791,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_lengthof * @see https://on.cypress.io/assertions */ - (chainer: 'not.have.length', value: number): Chainable + (chainer: 'not.have.length' | 'not.have.lengthOf', value: number): Chainable /** * Asserts that the target’s `length` property is not greater than to the given number `n`. * @example @@ -3692,7 +3800,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_lengthof * @see https://on.cypress.io/assertions */ - (chainer: 'not.have.length.greaterThan', value: number): Chainable + (chainer: 'not.have.length.greaterThan' | 'not.have.lengthOf.greaterThan', value: number): Chainable /** * Asserts that the target’s `length` property is not greater than to the given number `n`. * @example @@ -3701,7 +3809,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_lengthof * @see https://on.cypress.io/assertions */ - (chainer: 'not.have.length.gt', value: number): Chainable + (chainer: 'not.have.length.gt' | 'not.have.lengthOf.gt' | 'not.have.length.above' | 'not.have.lengthOf.above', value: number): Chainable /** * Asserts that the target’s `length` property is not greater than or equal to the given number `n`. * @example @@ -3710,7 +3818,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_lengthof * @see https://on.cypress.io/assertions */ - (chainer: 'have.length.gte', value: number): Chainable + (chainer: 'not.have.length.gte' | 'not.have.lengthOf.gte' | 'not.have.length.at.least' | 'not.have.lengthOf.at.least', value: number): Chainable /** * Asserts that the target’s `length` property is less than to the given number `n`. * @example @@ -3719,7 +3827,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_lengthof * @see https://on.cypress.io/assertions */ - (chainer: 'not.have.length.lessThan', value: number): Chainable + (chainer: 'not.have.length.lessThan' | 'not.have.lengthOf.lessThan', value: number): Chainable /** * Asserts that the target’s `length` property is not less than to the given number `n`. * @example @@ -3728,16 +3836,24 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_lengthof * @see https://on.cypress.io/assertions */ - (chainer: 'not.have.length.lt', value: number): Chainable + (chainer: 'not.have.length.lt' | 'not.have.lengthOf.lt' | 'not.have.length.below' | 'not.have.lengthOf.below', value: number): Chainable /** * Asserts that the target’s `length` property is not less than or equal to the given number `n`. * @example - * cy.wrap([1, 2, 3]).should('not.have.length.let', 2) + * cy.wrap([1, 2, 3]).should('not.have.length.lte', 2) * cy.wrap('foo').should('not.have.length.lte', 2) * @see http://chaijs.com/api/bdd/#method_lengthof * @see https://on.cypress.io/assertions */ - (chainer: 'not.have.length.lte', value: number): Chainable + (chainer: 'not.have.length.lte' | 'not.have.lengthOf.lte' | 'not.have.length.at.most' | 'not.have.lengthOf.at.most', value: number): Chainable + /** + * Asserts that the target’s `length` property is within `start` and `finish`. + * @example + * cy.wrap([1, 2, 3]).should('not.have.length.within', 6, 12) + * @see http://chaijs.com/api/bdd/#method_lengthof + * @see https://on.cypress.io/assertions + */ + (chainer: 'not.have.length.within' | 'not.have.lengthOf.within', start: number, finish: number): Chainable /** * Asserts that the target array does not have the same members as the given array `set`. * @example @@ -3745,7 +3861,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_members * @see https://on.cypress.io/assertions */ - (chainer: 'not.have.members', values: any[]): Chainable + (chainer: 'not.have.members' | 'not.have.deep.members', values: any[]): Chainable /** * Asserts that the target array does not have the same members as the given array where order matters. * @example @@ -3771,7 +3887,15 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_property * @see https://on.cypress.io/assertions */ - (chainer: 'not.have.property', property: string, value?: any): Chainable + (chainer: 'not.have.property' | 'not.have.nested.property' | 'not.have.own.property' | 'not.have.a.property' | 'not.have.deep.property' | 'not.have.deep.own.property' | 'not.have.deep.nested.property', property: string, value?: any): Chainable + /** + * Asserts that the target has its own property descriptor with the given key name. + * @example + * cy.wrap({a: 1}).should('not.have.ownPropertyDescriptor', 'a', { value: 2 }) + * @see http://chaijs.com/api/bdd/#method_ownpropertydescriptor + * @see https://on.cypress.io/assertions + */ + (chainer: 'not.have.ownPropertyDescriptor' | 'not.haveOwnPropertyDescriptor', name: string, descriptor?: PropertyDescriptor): Chainable /** * Asserts that the target string does not contains the given substring `str`. * @example @@ -3787,7 +3911,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_include * @see https://on.cypress.io/assertions */ - (chainer: 'not.include', value: any): Chainable + (chainer: 'not.include' | 'not.deep.include' | 'not.nested.include' | 'not.own.include' | 'not.deep.own.include' | 'not.deep.nested.include', value: any): Chainable /** * When the target is a string, `.include` asserts that the given string `val` is not a substring of the target. * @example @@ -3795,21 +3919,29 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_members * @see https://on.cypress.io/assertions */ - (chainer: 'not.include.members', value: any[]): Chainable + (chainer: 'not.include.members' | 'not.include.ordered.members' | 'not.include.deep.ordered.members', value: any[]): Chainable /** * When one argument is provided, `.increase` asserts that the given function `subject` returns a greater number when it’s * invoked after invoking the target function compared to when it’s invoked beforehand. * `.increase` also causes all `.by` assertions that follow in the chain to assert how much greater of a number is returned. * It’s often best to assert that the return value increased by the expected amount, rather than asserting it increased by any amount. + * + * When two arguments are provided, `.increase` asserts that the value of the given object `subject`’s `prop` property is greater after + * invoking the target function compared to beforehand. + * * @example * let val = 1 * function addTwo() { val += 2 } * function getVal() { return val } * cy.wrap(() => {}).should('not.increase', getVal) + * + * const myObj = { val: 1 } + * function addTwo() { myObj.val += 2 } + * cy.wrap(addTwo).should('increase', myObj, 'val') * @see http://chaijs.com/api/bdd/#method_increase * @see https://on.cypress.io/assertions */ - (chainer: 'not.increase', value: object, property: string): Chainable + (chainer: 'not.increase', value: object, property?: string): Chainable /** * Asserts that the target does not match the given regular expression `re`. * @example @@ -3848,7 +3980,7 @@ declare namespace Cypress { * @see http://chaijs.com/api/bdd/#method_throw * @see https://on.cypress.io/assertions */ - (chainer: 'throw', value?: string | RegExp): Chainable + (chainer: 'not.throw', value?: string | RegExp): Chainable /** * When no arguments are provided, `.throw` invokes the target function and asserts that no error is thrown. * When one argument is provided, and it’s a string, `.throw` invokes the target function and asserts that no error is thrown with a message that contains that string. @@ -3861,7 +3993,50 @@ declare namespace Cypress { * @see https://on.cypress.io/assertions */ // tslint:disable-next-line ban-types - (chainer: 'throw', error: Error | Function, expected?: string | RegExp): Chainable + (chainer: 'not.throw', error: Error | Function, expected?: string | RegExp): Chainable + /** + * Asserts that the target is a member of the given array list. + * @example + * cy.wrap(42).should('not.be.oneOf', [1, 2, 3]) + * @see http://chaijs.com/api/bdd/#method_oneof + * @see https://on.cypress.io/assertions + */ + (chainer: 'not.be.oneOf', list: ReadonlyArray): Chainable + /** + * Asserts that the target is extensible, which means that new properties can be added to it. + * @example + * let o = Object.seal({}) + * cy.wrap(o).should('not.be.extensible') + * @see http://chaijs.com/api/bdd/#method_extensible + * @see https://on.cypress.io/assertions + */ + (chainer: 'not.be.extensible'): Chainable + /** + * Asserts that the target is sealed, which means that new properties can’t be added to it, and its existing properties can’t be reconfigured or deleted. + * @example + * cy.wrap({a: 1}).should('be.sealed') + * cy.wrap({a: 1}).should('be.sealed') + * @see http://chaijs.com/api/bdd/#method_sealed + * @see https://on.cypress.io/assertions + */ + (chainer: 'not.be.sealed'): Chainable + /** + * Asserts that the target is frozen, which means that new properties can’t be added to it, and its existing properties can’t be reassigned to different values, reconfigured, or deleted. + * @example + * cy.wrap({a: 1}).should('not.be.frozen') + * @see http://chaijs.com/api/bdd/#method_frozen + * @see https://on.cypress.io/assertions + */ + (chainer: 'not.be.frozen'): Chainable + /** + * Asserts that the target is a number, and isn’t `NaN` or positive/negative `Infinity`. + * @example + * cy.wrap(NaN).should('not.be.finite') + * cy.wrap(Infinity).should('not.be.finite') + * @see http://chaijs.com/api/bdd/#method_finite + * @see https://on.cypress.io/assertions + */ + (chainer: 'not.be.finite'): Chainable // sinon-chai /** @@ -3870,80 +4045,80 @@ declare namespace Cypress { * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledwithnew * @see https://on.cypress.io/assertions */ - (chainer: 'be.always.calledWithNew'): Chainable + (chainer: 'be.always.calledWithNew' | 'always.have.been.calledWithNew'): Chainable /** * Assert if spy was always called with matching arguments (and possibly others). * @see http://sinonjs.org/releases/v4.1.3/spies/#spyalwayscalledwithmatcharg1-arg2- * @see https://on.cypress.io/assertions */ - (chainer: 'be.always.calledWithMatch', ...args: any[]): Chainable + (chainer: 'be.always.calledWithMatch' | 'always.have.been.calledWithMatch', ...args: any[]): Chainable /** * Assert spy always returned the provided value. * @see http://sinonjs.org/releases/v4.1.3/spies/#spyalwaysreturnedobj * @see https://on.cypress.io/assertions */ - (chainer: 'always.returned', value: any): Chainable + (chainer: 'always.returned' | 'have.always.returned', value: any): Chainable /** * `true` if the spy was called at least once * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalled * @see https://on.cypress.io/assertions */ - (chainer: 'be.called'): Chainable + (chainer: 'be.called' | 'have.been.called'): Chainable /** * Assert spy was called after `anotherSpy` * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledafteranotherspy * @see https://on.cypress.io/assertions */ - (chainer: 'be.calledAfter', spy: sinon.SinonSpy): Chainable + (chainer: 'be.calledAfter' | 'have.been.calledAfter', spy: sinon.SinonSpy): Chainable /** * Assert spy was called before `anotherSpy` * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledbeforeanotherspy * @see https://on.cypress.io/assertions */ - (chainer: 'be.calledBefore', spy: sinon.SinonSpy): Chainable + (chainer: 'be.calledBefore' | 'have.been.calledBefore', spy: sinon.SinonSpy): Chainable /** * Assert spy was called at least once with `obj` as `this`. `calledOn` also accepts a matcher (see [matchers](http://sinonjs.org/releases/v4.1.3/spies/#matchers)). * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledonobj * @see https://on.cypress.io/assertions */ - (chainer: 'be.calledOn', context: any): Chainable + (chainer: 'be.calledOn' | 'have.been.calledOn', context: any): Chainable /** * Assert spy was called exactly once * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledonce * @see https://on.cypress.io/assertions */ - (chainer: 'be.calledOnce'): Chainable + (chainer: 'be.calledOnce' | 'have.been.calledOnce'): Chainable /** * Assert spy was called exactly three times * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledthrice * @see https://on.cypress.io/assertions */ - (chainer: 'be.calledThrice'): Chainable + (chainer: 'be.calledThrice' | 'have.been.calledThrice'): Chainable /** * Assert spy was called exactly twice * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledtwice * @see https://on.cypress.io/assertions */ - (chainer: 'be.calledTwice'): Chainable + (chainer: 'be.calledTwice' | 'have.been.calledTwice'): Chainable /** * Assert spy was called at least once with the provided arguments and no others. * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledwithexactlyarg1-arg2- * @see https://on.cypress.io/assertions */ - (chainer: 'be.calledWithExactly', ...args: any[]): Chainable + (chainer: 'be.calledWithExactly' | 'have.been.calledWithExactly', ...args: any[]): Chainable /** * Assert spy was called with matching arguments (and possibly others). * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledwithmatcharg1-arg2- * @see https://on.cypress.io/assertions */ - (chainer: 'be.calledWithMatch', ...args: any[]): Chainable + (chainer: 'be.calledWithMatch' | 'have.been.calledWithMatch', ...args: any[]): Chainable /** * Assert spy/stub was called the `new` operator. * Beware that this is inferred based on the value of the this object and the spy function’s prototype, so it may give false positives if you actively return the right kind of object. * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledwithnew * @see https://on.cypress.io/assertions */ - (chainer: 'be.calledWithNew'): Chainable + (chainer: 'be.calledWithNew' | 'have.been.calledWithNew'): Chainable /** * Assert spy always threw an exception. * @see http://sinonjs.org/releases/v4.1.3/spies/#spyalwaysthrew @@ -3967,7 +4142,61 @@ declare namespace Cypress { * @see http://sinonjs.org/releases/v4.1.3/spies/#spyreturnedobj * @see https://on.cypress.io/assertions */ - (chainer: 'returned', value: any): Chainable + (chainer: 'returned' | 'have.returned', value: any): Chainable + /** + * Assert spy was called before anotherSpy, and no spy calls occurred between spy and anotherSpy. + * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledimmediatelybeforeanotherspy + * @see https://on.cypress.io/assertions + */ + (chainer: 'be.calledImmediatelyBefore' | 'have.been.calledImmediatelyBefore', anotherSpy: sinon.SinonSpy): Chainable + /** + * Assert spy was called after anotherSpy, and no spy calls occurred between anotherSpy and spy. + * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledimmediatelyafteranotherspy + * @see https://on.cypress.io/assertions + */ + (chainer: 'be.calledImmediatelyAfter' | 'have.been.calledImmediatelyAfter', anotherSpy: sinon.SinonSpy): Chainable + /** + * Assert the spy was always called with obj as this + * @see http://sinonjs.org/releases/v4.1.3/spies/#spyalwayscalledonobj + * @see https://on.cypress.io/assertions + */ + (chainer: 'be.always.calledOn' | 'always.have.been.calledOn', obj: any): Chainable + /** + * Assert spy was called at least once with the provided arguments. + * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledwitharg1-arg2- + * @see https://on.cypress.io/assertions + */ + (chainer: 'be.calledWith' | 'have.been.calledWith', ...args: any[]): Chainable + /** + * Assert spy was always called with the provided arguments (and possibly others). + * @see http://sinonjs.org/releases/v4.1.3/spies/#spyalwayscalledwitharg1-arg2- + * @see https://on.cypress.io/assertions + */ + (chainer: 'be.always.calledWith' | 'always.have.been.calledWith', ...args: any[]): Chainable + /** + * Assert spy was called at exactly once with the provided arguments. + * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledwitharg1-arg2- + * @see https://on.cypress.io/assertions + */ + (chainer: 'be.calledOnceWith' | 'have.been.calledOnceWith', ...args: any[]): Chainable + /** + * Assert spy was always called with the exact provided arguments. + * @see http://sinonjs.org/releases/v4.1.3/spies/#spyalwayscalledwithexactlyarg1-arg2- + * @see https://on.cypress.io/assertions + */ + (chainer: 'be.always.calledWithExactly' | 'have.been.calledWithExactly', ...args: any[]): Chainable + /** + * Assert spy was called at exactly once with the provided arguments. + * @see http://sinonjs.org/releases/v4.1.3/spies/# + * @see https://on.cypress.io/assertions + */ + (chainer: 'be.calledOnceWithExactly' | 'have.been.calledOnceWithExactly', ...args: any[]): Chainable + /** + * Assert spy always returned the provided value. + * @see http://sinonjs.org/releases/v4.1.3/spies/# + * @see https://on.cypress.io/assertions + */ + (chainer: 'have.always.returned', obj: any): Chainable // sinon-chai.not /** @@ -3976,80 +4205,80 @@ declare namespace Cypress { * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledwithnew * @see https://on.cypress.io/assertions */ - (chainer: 'not.be.always.calledWithNew'): Chainable + (chainer: 'not.be.always.calledWithNew' | 'not.always.have.been.calledWithNew'): Chainable /** * Assert if spy was not always called with matching arguments (and possibly others). * @see http://sinonjs.org/releases/v4.1.3/spies/#spyalwayscalledwithmatcharg1-arg2- * @see https://on.cypress.io/assertions */ - (chainer: 'not.be.always.calledWithMatch', ...args: any[]): Chainable + (chainer: 'not.be.always.calledWithMatch' | 'not.always.have.been.calledWithMatch', ...args: any[]): Chainable /** * Assert spy not always returned the provided value. * @see http://sinonjs.org/releases/v4.1.3/spies/#spyalwaysreturnedobj * @see https://on.cypress.io/assertions */ - (chainer: 'not.always.returned', value: any): Chainable + (chainer: 'not.always.returned' | 'not.have.always.returned', value: any): Chainable /** * `true` if the spy was not called at least once * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalled * @see https://on.cypress.io/assertions */ - (chainer: 'not.be.called'): Chainable + (chainer: 'not.be.called' | 'not.have.been.called'): Chainable /** * Assert spy was not.called after `anotherSpy` * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledafteranotherspy * @see https://on.cypress.io/assertions */ - (chainer: 'not.be.calledAfter', spy: sinon.SinonSpy): Chainable + (chainer: 'not.be.calledAfter' | 'not.have.been.calledAfter', spy: sinon.SinonSpy): Chainable /** * Assert spy was not called before `anotherSpy` * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledbeforeanotherspy * @see https://on.cypress.io/assertions */ - (chainer: 'not.be.calledBefore', spy: sinon.SinonSpy): Chainable + (chainer: 'not.be.calledBefore' | 'not.have.been.calledBefore', spy: sinon.SinonSpy): Chainable /** * Assert spy was not called at least once with `obj` as `this`. `calledOn` also accepts a matcher (see [matchers](http://sinonjs.org/releases/v4.1.3/spies/#matchers)). * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledonobj * @see https://on.cypress.io/assertions */ - (chainer: 'not.be.calledOn', context: any): Chainable + (chainer: 'not.be.calledOn' | 'not.have.been.calledOn', context: any): Chainable /** * Assert spy was not called exactly once * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledonce * @see https://on.cypress.io/assertions */ - (chainer: 'not.be.calledOnce'): Chainable + (chainer: 'not.be.calledOnce' | 'not.have.been.calledOnce'): Chainable /** * Assert spy was not called exactly three times * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledthrice * @see https://on.cypress.io/assertions */ - (chainer: 'not.be.calledThrice'): Chainable + (chainer: 'not.be.calledThrice' | 'not.have.been.calledThrice'): Chainable /** * Assert spy was not called exactly twice * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledtwice * @see https://on.cypress.io/assertions */ - (chainer: 'not.be.calledTwice'): Chainable + (chainer: 'not.be.calledTwice' | 'not.have.been.calledTwice'): Chainable /** * Assert spy was not called at least once with the provided arguments and no others. * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledwithexactlyarg1-arg2- * @see https://on.cypress.io/assertions */ - (chainer: 'not.be.calledWithExactly', ...args: any[]): Chainable + (chainer: 'not.be.calledWithExactly' | 'not.have.been.calledWithExactly', ...args: any[]): Chainable /** * Assert spy was not called with matching arguments (and possibly others). * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledwithmatcharg1-arg2- * @see https://on.cypress.io/assertions */ - (chainer: 'not.be.calledWithMatch', ...args: any[]): Chainable + (chainer: 'not.be.calledWithMatch' | 'not.have.been.calledWithMatch', ...args: any[]): Chainable /** * Assert spy/stub was not called the `new` operator. * Beware that this is inferred based on the value of the this object and the spy function’s prototype, so it may give false positives if you actively return the right kind of object. * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledwithnew * @see https://on.cypress.io/assertions */ - (chainer: 'not.be.calledWithNew'): Chainable + (chainer: 'not.be.calledWithNew' | 'not.have.been.calledWithNew'): Chainable /** * Assert spy did not always throw an exception. * @see http://sinonjs.org/releases/v4.1.3/spies/#spyalwaysthrew @@ -4073,7 +4302,61 @@ declare namespace Cypress { * @see http://sinonjs.org/releases/v4.1.3/spies/#spyreturnedobj * @see https://on.cypress.io/assertions */ - (chainer: 'not.returned', value: any): Chainable + (chainer: 'not.returned' | 'not.have.returned', value: any): Chainable + /** + * Assert spy was called before anotherSpy, and no spy calls occurred between spy and anotherSpy. + * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledimmediatelybeforeanotherspy + * @see https://on.cypress.io/assertions + */ + (chainer: 'not.be.calledImmediatelyBefore' | 'not.have.been.calledImmediatelyBefore', anotherSpy: sinon.SinonSpy): Chainable + /** + * Assert spy was called after anotherSpy, and no spy calls occurred between anotherSpy and spy. + * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledimmediatelyafteranotherspy + * @see https://on.cypress.io/assertions + */ + (chainer: 'not.be.calledImmediatelyAfter' | 'not.have.been.calledImmediatelyAfter', anotherSpy: sinon.SinonSpy): Chainable + /** + * Assert the spy was always called with obj as this + * @see http://sinonjs.org/releases/v4.1.3/spies/#spyalwayscalledonobj + * @see https://on.cypress.io/assertions + */ + (chainer: 'not.be.always.calledOn' | 'not.always.have.been.calledOn', obj: any): Chainable + /** + * Assert spy was called at least once with the provided arguments. + * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledwitharg1-arg2- + * @see https://on.cypress.io/assertions + */ + (chainer: 'not.be.calledWith' | 'not.have.been.calledWith', ...args: any[]): Chainable + /** + * Assert spy was always called with the provided arguments (and possibly others). + * @see http://sinonjs.org/releases/v4.1.3/spies/#spyalwayscalledwitharg1-arg2- + * @see https://on.cypress.io/assertions + */ + (chainer: 'not.be.always.calledWith' | 'not.always.have.been.calledWith', ...args: any[]): Chainable + /** + * Assert spy was called at exactly once with the provided arguments. + * @see http://sinonjs.org/releases/v4.1.3/spies/#spycalledwitharg1-arg2- + * @see https://on.cypress.io/assertions + */ + (chainer: 'not.be.calledOnceWith' | 'not.have.been.calledOnceWith', ...args: any[]): Chainable + /** + * Assert spy was always called with the exact provided arguments. + * @see http://sinonjs.org/releases/v4.1.3/spies/#spyalwayscalledwithexactlyarg1-arg2- + * @see https://on.cypress.io/assertions + */ + (chainer: 'not.be.always.calledWithExactly' | 'not.have.been.calledWithExactly', ...args: any[]): Chainable + /** + * Assert spy was called at exactly once with the provided arguments. + * @see http://sinonjs.org/releases/v4.1.3/spies/# + * @see https://on.cypress.io/assertions + */ + (chainer: 'not.be.calledOnceWithExactly' | 'not.have.been.calledOnceWithExactly', ...args: any[]): Chainable + /** + * Assert spy always returned the provided value. + * @see http://sinonjs.org/releases/v4.1.3/spies/# + * @see https://on.cypress.io/assertions + */ + (chainer: 'not.have.always.returned', obj: any): Chainable // jquery-chai /** diff --git a/cli/types/tests/chainer-examples.ts b/cli/types/tests/chainer-examples.ts index f73532e20dd4..7538a638b297 100644 --- a/cli/types/tests/chainer-examples.ts +++ b/cli/types/tests/chainer-examples.ts @@ -97,7 +97,7 @@ cy.wrap({ x: {a: 1 }}).should('have.deep.property', 'x', { a: 1 }) cy.wrap([1, 2, 3]).should('have.length', 3) cy.wrap('foo').should('have.length', 3) -cy.wrap([1, 2, 3]).should('have.length.greaterThan') +cy.wrap([1, 2, 3]).should('have.length.greaterThan', 2) cy.wrap('foo').should('have.length.greaterThan', 2) cy.wrap([1, 2, 3]).should('have.length.gt', 2) @@ -128,19 +128,19 @@ cy.wrap('foobar').should('have.string', 'bar') cy.wrap('foobar').should('include', 'foo') -cy.wrap('foo').should('contain.value') -cy.wrap('foo').should('contain.text') -cy.wrap('foo').should('contain.html') -cy.wrap('foo').should('not.contain.value') -cy.wrap('foo').should('not.contain.text') -cy.wrap('foo').should('not.contain.html') +cy.wrap('foo').should('contain.value', 'foo') +cy.wrap('foo').should('contain.text', 'foo') +cy.wrap('foo').should('contain.html', 'foo') +cy.wrap('foo').should('not.contain.value', 'foo') +cy.wrap('foo').should('not.contain.text', 'foo') +cy.wrap('foo').should('not.contain.html', 'foo') -cy.wrap('foo').should('include.value') -cy.wrap('foo').should('include.text') -cy.wrap('foo').should('include.html') -cy.wrap('foo').should('not.include.value') -cy.wrap('foo').should('not.include.text') -cy.wrap('foo').should('not.incldue.html') +cy.wrap('foo').should('include.value', 'foo') +cy.wrap('foo').should('include.text', 'foo') +cy.wrap('foo').should('include.html', 'foo') +cy.wrap('foo').should('not.include.value', 'foo') +cy.wrap('foo').should('not.include.text', 'foo') +cy.wrap('foo').should('not.include.html', 'foo') // Ensure we've extended chai.Includes correctly expect('foo').to.include.value('foo') @@ -157,6 +157,9 @@ cy.wrap([1, 2, 3]).should('include.members', [1, 2]) function addTwo() { val += 2 } function getVal() { return val } cy.wrap(addTwo).should('increase', getVal) + + const myObj = { val: 1 } + cy.wrap(addTwo).should('increase', myObj, 'val') } cy.wrap('foobar').should('match', /^foo/) @@ -226,6 +229,12 @@ cy.wrap(true).should('not.be.undefined') cy.wrap(3).should('not.be.within', 5, 10) +cy.wrap(null).should('be.null') +cy.wrap(123).should('not.be.null') + +cy.wrap(NaN).should('be.NaN') +cy.wrap('cypress').should('not.be.NaN') + ; () => { let dots = '' @@ -256,7 +265,7 @@ cy.wrap('tester').should('not.contain', 'foo') cy.wrap(() => {}).should('not.decrease', myObj, 'val') } -cy.wrap({ a: 1 }).should('not.deep.equal', { b: 1 }) +cy.wrap<{a?: number, b?: number }>({ a: 1 }).should('not.deep.equal', { b: 1 }) cy.wrap(null).should('not.exist') @@ -287,12 +296,12 @@ cy.wrap('foo').should('have.length.lessThan', 2) cy.wrap([1, 2, 3]).should('not.have.length.lt', 2) cy.wrap('foo').should('not.have.length.lt', 2) -cy.wrap([1, 2, 3]).should('not.have.length.let', 2) +cy.wrap([1, 2, 3]).should('not.have.length.lte', 2) cy.wrap('foo').should('not.have.length.lte', 2) cy.wrap([1, 2, 3]).should('not.have.members', [4, 5, 6]) -cy.wrap([1, 2, 3]).should('not. have.ordered.members', [4, 5, 6]) +cy.wrap([1, 2, 3]).should('not.have.ordered.members', [4, 5, 6]) ; (Object as any).prototype.b = 2 @@ -361,7 +370,7 @@ cy.get('#result').should('not.be.focused') cy.get('#result').should('have.focus') cy.get('#result').should('not.have.focus') -cy.get('#result').should('be.contain', 'text') +cy.get('#result').should('contain', 'text') cy.get('#result').should('have.attr', 'role') cy.get('#result').should('have.attr', 'role', 'menu') diff --git a/cli/types/tests/kitchen-sink.ts b/cli/types/tests/kitchen-sink.ts index ad0d299b102e..8df9c1ea1d61 100644 --- a/cli/types/tests/kitchen-sink.ts +++ b/cli/types/tests/kitchen-sink.ts @@ -62,6 +62,7 @@ expect(stub).to.not.have.been.called stub() expect(stub).to.have.been.calledOnce cy.wrap(stub).should('have.been.calledOnce') +cy.wrap(stub).should('be.calledOnce') namespace EventInterfaceTests { // window:confirm stubbing From 9c8e6f7a1a0607b8cfaf5c49817ddfde231e1307 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 11:29:25 +0630 Subject: [PATCH 11/36] =?UTF-8?q?fix(deps):=20update=20dependency=20jimp?= =?UTF-8?q?=20to=20version=200.14.0=20=F0=9F=8C=9F=20(#8102)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Renovate Bot Co-authored-by: Jennifer Shehane --- packages/server/package.json | 2 +- yarn.lock | 368 +++++++++++++++++------------------ 2 files changed, 185 insertions(+), 185 deletions(-) diff --git a/packages/server/package.json b/packages/server/package.json index 5b7ad4326b46..55137bf9d2a2 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -70,7 +70,7 @@ "image-size": "0.8.3", "is-fork-pr": "2.5.0", "is-html": "2.0.0", - "jimp": "0.13.0", + "jimp": "0.14.0", "jsonlint": "1.6.3", "konfig": "0.2.1", "launch-editor": "2.2.1", diff --git a/yarn.lock b/yarn.lock index 68c2bfb5aec2..b02abd060ecf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2194,22 +2194,22 @@ "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^13.0.0" -"@jimp/bmp@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.13.0.tgz#cca2301e56231e7dc20d5aba757fb237b94e2013" - integrity sha512-7i/XZLoK5JETBKO0VL7qjnr6WDVl1X8mmaUk6Lzq06/veMPC5IwUIZi1JRVAXPEwTf5uUegq0WFnmUS0lVYzFw== +"@jimp/bmp@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.14.0.tgz#6df246026554f276f7b354047c6fff9f5b2b5182" + integrity sha512-5RkX6tSS7K3K3xNEb2ygPuvyL9whjanhoaB/WmmXlJS6ub4DjTqrapu8j4qnIWmO4YYtFeTbDTXV6v9P1yMA5A== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" bmp-js "^0.1.0" -"@jimp/core@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/core/-/core-0.13.0.tgz#6ec104d69cd7bf32bd5748f5d6106133e2ee3205" - integrity sha512-BMFEUm5HbRP4yCo4Q23CJFx/v6Yr3trw7rERmS1GKUEooDq9ktApZWWTvWq/vggKyysKX0nQ+KT+FaFD/75Q+Q== +"@jimp/core@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/core/-/core-0.14.0.tgz#870c9ca25b40be353ebda1d2abb48723d9010055" + integrity sha512-S62FcKdtLtj3yWsGfJRdFXSutjvHg7aQNiFogMbwq19RP4XJWqS2nOphu7ScB8KrSlyy5nPF2hkWNhLRLyD82w== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" any-base "^1.1.0" buffer "^5.2.0" exif-parser "^0.1.12" @@ -2220,266 +2220,266 @@ pixelmatch "^4.0.2" tinycolor2 "^1.4.1" -"@jimp/custom@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/custom/-/custom-0.13.0.tgz#bc7b2568e73eea1e1c15260b7283d7d099630881" - integrity sha512-Zir/CHoLRhQDGfPWueCIQbVjVUlayNIUch9fulq4M9V2S+ynHx9BqRn58z8wy+mk8jm1WlpRVhvZ8QUenbL0vg== +"@jimp/custom@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/custom/-/custom-0.14.0.tgz#1dbbf0094df7403f4e03bc984ed92e7458842f74" + integrity sha512-kQJMeH87+kWJdVw8F9GQhtsageqqxrvzg7yyOw3Tx/s7v5RToe8RnKyMM+kVtBJtNAG+Xyv/z01uYQ2jiZ3GwA== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/core" "^0.13.0" + "@jimp/core" "^0.14.0" -"@jimp/gif@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/gif/-/gif-0.13.0.tgz#09f208f616d83acc8f8e1f1f6df784bafea46062" - integrity sha512-7FO2Fa9FZluqGt1MM/L8s6P5UEedxrIQT2eBAxzB8Z82YTTSWQXw4bdrZWCwiQjBFZwKTIaULIfw6+TxA/Q2XA== +"@jimp/gif@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/gif/-/gif-0.14.0.tgz#db159f57c3cfd1566bbe8b124958791998614960" + integrity sha512-DHjoOSfCaCz72+oGGEh8qH0zE6pUBaBxPxxmpYJjkNyDZP7RkbBkZJScIYeQ7BmJxmGN4/dZn+MxamoQlr+UYg== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" gifwrap "^0.9.2" omggif "^1.0.9" -"@jimp/jpeg@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/jpeg/-/jpeg-0.13.0.tgz#e7609a932cb0b795c422b6ad25882277a9db029d" - integrity sha512-Fol/DxA1lnIzCsNx/CckIEoyWImQHiWPgFAWL5s7VIVaJrEFnnbRqfOxmvr8yWg8mh3hWLeXNcxqA82CKXgg+Q== +"@jimp/jpeg@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/jpeg/-/jpeg-0.14.0.tgz#8a687a6a653bbbae38c522edef8f84bb418d9461" + integrity sha512-561neGbr+87S/YVQYnZSTyjWTHBm9F6F1obYHiyU3wVmF+1CLbxY3FQzt4YolwyQHIBv36Bo0PY2KkkU8BEeeQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" jpeg-js "^0.4.0" -"@jimp/plugin-blit@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-blit/-/plugin-blit-0.13.0.tgz#31d8744a2fe79abe0ffd1af3f385953fb9e3b4d5" - integrity sha512-roCShFZosJgRMLCLzuOT1pRZysQF/p3avQieZiu9pfg2F9X09f91OauU2Lf3/yOp0TZCWbheqbem9MPlhyED8w== +"@jimp/plugin-blit@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-blit/-/plugin-blit-0.14.0.tgz#5eb374be1201313b2113899fb842232d8fcfd345" + integrity sha512-YoYOrnVHeX3InfgbJawAU601iTZMwEBZkyqcP1V/S33Qnz9uzH1Uj1NtC6fNgWzvX6I4XbCWwtr4RrGFb5CFrw== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-blur@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-blur/-/plugin-blur-0.13.0.tgz#35c57830391da331fc28f847742c2ea822d8641f" - integrity sha512-LeBhQe72bRk2fe2AftcqcDaWgSu6vFD0fxiAYYMy3pHa8pnPAwnw2W3u4bV/gc5XJt6AJzoRyc7WVG2pE4A3gg== +"@jimp/plugin-blur@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-blur/-/plugin-blur-0.14.0.tgz#fe07e4932d5a2f5d8c9831e245561553224bfc60" + integrity sha512-9WhZcofLrT0hgI7t0chf7iBQZib//0gJh9WcQMUt5+Q1Bk04dWs8vTgLNj61GBqZXgHSPzE4OpCrrLDBG8zlhQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-circle@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-circle/-/plugin-circle-0.13.0.tgz#2df8783e7e648ed1135d9197a3927543c0e340de" - integrity sha512-INwIl8zgWnJYXxYkNhIjG8TXg2Q1nh008SDKyC+Pug4ce/XRJC8w/Gk6HS+U9Z2tIO2/zXv473k/JaiwvDMu1w== +"@jimp/plugin-circle@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-circle/-/plugin-circle-0.14.0.tgz#82c0e904a34e90fa672fb9c286bc892e92088ddf" + integrity sha512-o5L+wf6QA44tvTum5HeLyLSc5eVfIUd5ZDVi5iRfO4o6GT/zux9AxuTSkKwnjhsG8bn1dDmywAOQGAx7BjrQVA== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-color@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-color/-/plugin-color-0.13.0.tgz#6f5683bb1e02bc1576867b5b79b7736a1249faec" - integrity sha512-e71UDivZdZGOhQRLjDo4a0BKgrH858HJ7zFk7/Yti58LwgeIGjYHhuYc+xQOdnBWPzGSD47TuFX5GXmf/x1nmg== +"@jimp/plugin-color@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-color/-/plugin-color-0.14.0.tgz#772bd2d80a88bc66ea1331d010207870f169a74b" + integrity sha512-JJz512SAILYV0M5LzBb9sbOm/XEj2fGElMiHAxb7aLI6jx+n0agxtHpfpV/AePTLm1vzzDxx6AJxXbKv355hBQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" tinycolor2 "^1.4.1" -"@jimp/plugin-contain@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-contain/-/plugin-contain-0.13.0.tgz#d87408f078d3f9438b5d04045cba5d1f185d8fc2" - integrity sha512-qPYS+ccMP4mEnf7BB0bcaszUTth8OxeRX0MdMvU6PDEI0nIvVVNwmuI6YtNqqs12PwuYxgPkq6AFenyLyoNP1g== +"@jimp/plugin-contain@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-contain/-/plugin-contain-0.14.0.tgz#c68115420d182e696f81bbe76fb5e704909b2b6a" + integrity sha512-RX2q233lGyaxiMY6kAgnm9ScmEkNSof0hdlaJAVDS1OgXphGAYAeSIAwzESZN4x3ORaWvkFefeVH9O9/698Evg== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-cover@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-cover/-/plugin-cover-0.13.0.tgz#bf7e82df3857b374ece24cfb0f524c0cc6e03a6e" - integrity sha512-S2GkbXNgIb0afof/NLLq9IJDZPOcFtu1mc32ngt9S8HzXsNHgRAzONW7cg56bwQ6p0+sz/dS5tB4ctOW/pu/Dw== +"@jimp/plugin-cover@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-cover/-/plugin-cover-0.14.0.tgz#4755322589c5885e44e14e31b86b542e907297ce" + integrity sha512-0P/5XhzWES4uMdvbi3beUgfvhn4YuQ/ny8ijs5kkYIw6K8mHcl820HahuGpwWMx56DJLHRl1hFhJwo9CeTRJtQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-crop@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-crop/-/plugin-crop-0.13.0.tgz#2215923db11694796a40a294faf373454a0af3f8" - integrity sha512-Y1Ug3kOzsq72EjLiWQlwkHuvUvdSmFUDtxpyOXh3RxeWF7wmdjH8FvdhPj8hWvFLsDYFgWGaLI4Z6SXOr+N8nA== +"@jimp/plugin-crop@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-crop/-/plugin-crop-0.14.0.tgz#4cbd856ca84ffc37230fad2534906f2f75aa3057" + integrity sha512-Ojtih+XIe6/XSGtpWtbAXBozhCdsDMmy+THUJAGu2x7ZgKrMS0JotN+vN2YC3nwDpYkM+yOJImQeptSfZb2Sug== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-displace@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-displace/-/plugin-displace-0.13.0.tgz#ace748989133322cc1da94f7699ab393904fc306" - integrity sha512-c80VIUjIqQoavafthLpYRZdzANCxbOCHzqkFVbZ0kNKJnDDk6fW55mvVW4TJLDToDU81WMlttCmNV0oXcX93gQ== +"@jimp/plugin-displace@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-displace/-/plugin-displace-0.14.0.tgz#b0e6a57d00cb1f893f541413fe9d737d23c3b70c" + integrity sha512-c75uQUzMgrHa8vegkgUvgRL/PRvD7paFbFJvzW0Ugs8Wl+CDMGIPYQ3j7IVaQkIS+cAxv+NJ3TIRBQyBrfVEOg== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-dither@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-dither/-/plugin-dither-0.13.0.tgz#c5a917955b9b5690e9cece2ee10e072ff9cfe82e" - integrity sha512-EUz/y/AaQ00TnaiVLVAXLz8n8Nx7S36lKi4VXPeYy5a5FyzBimxNiKxdITVe9zooN7+H4FP++/xGFGFMpfWtRg== +"@jimp/plugin-dither@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-dither/-/plugin-dither-0.14.0.tgz#9185ec4c38e02edc9e5831f5d709f6ba891e1b93" + integrity sha512-g8SJqFLyYexXQQsoh4dc1VP87TwyOgeTElBcxSXX2LaaMZezypmxQfLTzOFzZoK8m39NuaoH21Ou1Ftsq7LzVQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-fisheye@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-fisheye/-/plugin-fisheye-0.13.0.tgz#d300564c30ae1513268680b5ced4de87d6719aee" - integrity sha512-O7h5pNTk2sYcTKxLvV6+zzUpLx8qzdNl6qiP9x1S0CKy64oZ9IwtK1eR1eLom0YA8tUR7rX5Ra4pB8bhq8Oyqw== +"@jimp/plugin-fisheye@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-fisheye/-/plugin-fisheye-0.14.0.tgz#9f26346cf2fbc660cc2008cd7fd30a83b5029e78" + integrity sha512-BFfUZ64EikCaABhCA6mR3bsltWhPpS321jpeIQfJyrILdpFsZ/OccNwCgpW1XlbldDHIoNtXTDGn3E+vCE7vDg== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-flip@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-flip/-/plugin-flip-0.13.0.tgz#502c07fbefddbe045a1a8d691f3918651bb0f349" - integrity sha512-gWk+Q0LmCvupUuWRfoGyETmH/+lJKZuPCeA9K6UHJldq5Cdg/3MrlKUNS1HcPCDXjw+dWDGC8QnNslvMTaY5VQ== +"@jimp/plugin-flip@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-flip/-/plugin-flip-0.14.0.tgz#7966d6aa3b5fe1aa4d2d561ff12b8ef5ccb9b071" + integrity sha512-WtL1hj6ryqHhApih+9qZQYA6Ye8a4HAmdTzLbYdTMrrrSUgIzFdiZsD0WeDHpgS/+QMsWwF+NFmTZmxNWqKfXw== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-gaussian@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-gaussian/-/plugin-gaussian-0.13.0.tgz#9ae00f6080b3ed777eb837d94d9d0a071aa1246b" - integrity sha512-0ctRqbCcLdy8y9IrSIH2McWNPLnEwjoe8qxtqoi51zRsM3z3mwjiTC2q8AWeF0SdIdWwV+YV/eP0494AJqjTsg== +"@jimp/plugin-gaussian@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-gaussian/-/plugin-gaussian-0.14.0.tgz#452bc1971a4467ad9b984aa67f4c200bf941bb65" + integrity sha512-uaLwQ0XAQoydDlF9tlfc7iD9drYPriFe+jgYnWm8fbw5cN+eOIcnneEX9XCOOzwgLPkNCxGox6Kxjn8zY6GxtQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-invert@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-invert/-/plugin-invert-0.13.0.tgz#f06ba0eed19225f45d1b87fcc84ed8a233e32d1e" - integrity sha512-k7TWx/la0MrTcT1dMtncV6I9IuGToRm9Q0ekzfb3k8bHzWRYX4SUtt/WrZ/I+/znD/fGorLtFI057v7mcLJc5A== +"@jimp/plugin-invert@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-invert/-/plugin-invert-0.14.0.tgz#cd31a555860e9f821394936d15af161c09c42921" + integrity sha512-UaQW9X9vx8orQXYSjT5VcITkJPwDaHwrBbxxPoDG+F/Zgv4oV9fP+udDD6qmkgI9taU+44Fy+zm/J/gGcMWrdg== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-mask@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-mask/-/plugin-mask-0.13.0.tgz#42492be551c7d1eeb52f13d369476301b51cea7e" - integrity sha512-U3OdsgtMNpbCYc1lzzu96zdSgyz7BK9eD8IoFHdw4Ma8gCuM8kp9gdBJlKnzOh8eyYvssdCMZOWz9Xbxc5xH9A== +"@jimp/plugin-mask@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-mask/-/plugin-mask-0.14.0.tgz#52619643ac6222f85e6b27dee33c771ca3a6a4c9" + integrity sha512-tdiGM69OBaKtSPfYSQeflzFhEpoRZ+BvKfDEoivyTjauynbjpRiwB1CaiS8En1INTDwzLXTT0Be9SpI3LkJoEA== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-normalize@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-normalize/-/plugin-normalize-0.13.0.tgz#e1f4de7f8caef061c2dc093f3a8251d278b837e5" - integrity sha512-yKOgZSvOxSHNlh+U9NOQH4Drgca0Dwb7DQRk3vj67gvHQC96JafIpGwN+9V4fP89lA3rkItbw6xgN6C/28HEUQ== +"@jimp/plugin-normalize@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-normalize/-/plugin-normalize-0.14.0.tgz#bf39e356b6d473f582ce95633ad49c9cdb82492b" + integrity sha512-AfY8sqlsbbdVwFGcyIPy5JH/7fnBzlmuweb+Qtx2vn29okq6+HelLjw2b+VT2btgGUmWWHGEHd86oRGSoWGyEQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-print@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-print/-/plugin-print-0.13.0.tgz#32a1e9c30dbf38564956eb326b138b729b6067f1" - integrity sha512-Tv7r/1t7z63oLeRuEWw9xbm0G5uuBE54986+BOu8OFaHBpV/BbVHrE7ouApA0mKVZqMZCVjhO6Ph8+uFzRjdOw== +"@jimp/plugin-print@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-print/-/plugin-print-0.14.0.tgz#1c43c2a92a7adc05b464863882cb89ce486d63e6" + integrity sha512-MwP3sH+VS5AhhSTXk7pui+tEJFsxnTKFY3TraFJb8WFbA2Vo2qsRCZseEGwpTLhENB7p/JSsLvWoSSbpmxhFAQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" load-bmfont "^1.4.0" -"@jimp/plugin-resize@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-resize/-/plugin-resize-0.13.0.tgz#17eb70bed34054b4b9633a213e1396431e8d682e" - integrity sha512-XOo0Skn7aq/aGxV9czFx6EaBUbAsAGCVbAS26fMM0AZ4YAWWUEleKTpHunEo92giIPhvlxeFFjQR2jQ9UcB3uQ== +"@jimp/plugin-resize@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-resize/-/plugin-resize-0.14.0.tgz#ef7fc6c2e45f8bcab62456baf8fd3bc415b02b64" + integrity sha512-qFeMOyXE/Bk6QXN0GQo89+CB2dQcXqoxUcDb2Ah8wdYlKqpi53skABkgVy5pW3EpiprDnzNDboMltdvDslNgLQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-rotate@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-rotate/-/plugin-rotate-0.13.0.tgz#325e799055b748fe1948eb85e7ad6ec46d08bc5b" - integrity sha512-BaNeh655kF9Rz01ZV+Bkc8hLsHpNu3QnzigruVDjGt9Paoig0EBr+Dgyjje+7eTLu20kyuyxwPUAxLSOiPiraQ== +"@jimp/plugin-rotate@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-rotate/-/plugin-rotate-0.14.0.tgz#3632bc159bf1c3b9ec9f459d9c05d02a11781ee7" + integrity sha512-aGaicts44bvpTcq5Dtf93/8TZFu5pMo/61lWWnYmwJJU1RqtQlxbCLEQpMyRhKDNSfPbuP8nyGmaqXlM/82J0Q== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-scale@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-scale/-/plugin-scale-0.13.0.tgz#cf498f6fef97354c5a6f1e37d5c5ef940a963297" - integrity sha512-e/f7lvii+DmRMgYF+uBKQy437f+J66WbL0FcFEataCF/W9UkTIQGeXdECwJSPfqr81SxC5mGbSBbsdbMKChzAQ== +"@jimp/plugin-scale@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-scale/-/plugin-scale-0.14.0.tgz#d30f0cd1365b8e68f43fa423300ae7f124e9bf10" + integrity sha512-ZcJk0hxY5ZKZDDwflqQNHEGRblgaR+piePZm7dPwPUOSeYEH31P0AwZ1ziceR74zd8N80M0TMft+e3Td6KGBHw== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-shadow@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-shadow/-/plugin-shadow-0.13.0.tgz#dd35819800e7375f2a8eb13a02bf1b8829a3e47e" - integrity sha512-qObtH63dmfPLze5wE8XDRjDsBOUnAfEWib4YbjPXGBZVxeKD7+2oPGemsK56HqC/+rYzIynkbi4MUIV1Q0dGjA== +"@jimp/plugin-shadow@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-shadow/-/plugin-shadow-0.14.0.tgz#471fdb9f109ff2d9e20d533d45e1e18e0b48c749" + integrity sha512-p2igcEr/iGrLiTu0YePNHyby0WYAXM14c5cECZIVnq/UTOOIQ7xIcWZJ1lRbAEPxVVXPN1UibhZAbr3HAb5BjQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugin-threshold@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugin-threshold/-/plugin-threshold-0.13.0.tgz#d92febd59f72d44e3afd60d74e1232ab1645b3a4" - integrity sha512-ACF7jk0ogso+2RK+0EsvBupVfE3IMq39wGFQWgpnHR9Tj12mSO279f6i/H8bcj1ZXmHot22nwLOG0wO4AlAaRg== +"@jimp/plugin-threshold@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugin-threshold/-/plugin-threshold-0.14.0.tgz#ebd72721c7d1d518c5bb6e494e55d97ac3351d3b" + integrity sha512-N4BlDgm/FoOMV/DQM2rSpzsgqAzkP0DXkWZoqaQrlRxQBo4zizQLzhEL00T/YCCMKnddzgEhnByaocgaaa0fKw== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" -"@jimp/plugins@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/plugins/-/plugins-0.13.0.tgz#d1f2aed6ce4b7de7e3d683daf723d887aa4a826f" - integrity sha512-onu8GnSnFjLFuFVFq8+aTYFIDfH8kwZuBHeGaDyScPFFn6QMKsPl4TeLzQ5vwIPvcpkADuFFfuAshE4peutjjA== +"@jimp/plugins@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/plugins/-/plugins-0.14.0.tgz#41dba85f15ab8dadb4162100eb54e5f27b93ee2c" + integrity sha512-vDO3XT/YQlFlFLq5TqNjQkISqjBHT8VMhpWhAfJVwuXIpilxz5Glu4IDLK6jp4IjPR6Yg2WO8TmRY/HI8vLrOw== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/plugin-blit" "^0.13.0" - "@jimp/plugin-blur" "^0.13.0" - "@jimp/plugin-circle" "^0.13.0" - "@jimp/plugin-color" "^0.13.0" - "@jimp/plugin-contain" "^0.13.0" - "@jimp/plugin-cover" "^0.13.0" - "@jimp/plugin-crop" "^0.13.0" - "@jimp/plugin-displace" "^0.13.0" - "@jimp/plugin-dither" "^0.13.0" - "@jimp/plugin-fisheye" "^0.13.0" - "@jimp/plugin-flip" "^0.13.0" - "@jimp/plugin-gaussian" "^0.13.0" - "@jimp/plugin-invert" "^0.13.0" - "@jimp/plugin-mask" "^0.13.0" - "@jimp/plugin-normalize" "^0.13.0" - "@jimp/plugin-print" "^0.13.0" - "@jimp/plugin-resize" "^0.13.0" - "@jimp/plugin-rotate" "^0.13.0" - "@jimp/plugin-scale" "^0.13.0" - "@jimp/plugin-shadow" "^0.13.0" - "@jimp/plugin-threshold" "^0.13.0" + "@jimp/plugin-blit" "^0.14.0" + "@jimp/plugin-blur" "^0.14.0" + "@jimp/plugin-circle" "^0.14.0" + "@jimp/plugin-color" "^0.14.0" + "@jimp/plugin-contain" "^0.14.0" + "@jimp/plugin-cover" "^0.14.0" + "@jimp/plugin-crop" "^0.14.0" + "@jimp/plugin-displace" "^0.14.0" + "@jimp/plugin-dither" "^0.14.0" + "@jimp/plugin-fisheye" "^0.14.0" + "@jimp/plugin-flip" "^0.14.0" + "@jimp/plugin-gaussian" "^0.14.0" + "@jimp/plugin-invert" "^0.14.0" + "@jimp/plugin-mask" "^0.14.0" + "@jimp/plugin-normalize" "^0.14.0" + "@jimp/plugin-print" "^0.14.0" + "@jimp/plugin-resize" "^0.14.0" + "@jimp/plugin-rotate" "^0.14.0" + "@jimp/plugin-scale" "^0.14.0" + "@jimp/plugin-shadow" "^0.14.0" + "@jimp/plugin-threshold" "^0.14.0" timm "^1.6.1" -"@jimp/png@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/png/-/png-0.13.0.tgz#f4d9b6f7843908b081dbace984f0d45e45f1ffda" - integrity sha512-9MVU0BLMQKJ6Kaiwjrq6dLDnDktZzeHtxz4qthRHaGOyHLx3RpxmbhaDuK9dDg6NASX3JuXznEhaOP4lqQODpQ== +"@jimp/png@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/png/-/png-0.14.0.tgz#0f2dddb5125c0795ca7e67c771204c5437fcda4b" + integrity sha512-0RV/mEIDOrPCcNfXSPmPBqqSZYwGADNRVUTyMt47RuZh7sugbYdv/uvKmQSiqRdR0L1sfbCBMWUEa5G/8MSbdA== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/utils" "^0.13.0" + "@jimp/utils" "^0.14.0" pngjs "^3.3.3" -"@jimp/tiff@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/tiff/-/tiff-0.13.0.tgz#2795a35073fe296dc09ac2fa693fe5b3558386f6" - integrity sha512-8lLGgEmhVRRjzZfn/QgpM3+mijq5ORYqRHtLcqDgcQaUY/q/OU1CxLYX777pozyQ3KIq1O+jyyHZm2xu3RZkPA== +"@jimp/tiff@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/tiff/-/tiff-0.14.0.tgz#a5b25bbe7c43fc3b07bad4e2ab90e0e164c1967f" + integrity sha512-zBYDTlutc7j88G/7FBCn3kmQwWr0rmm1e0FKB4C3uJ5oYfT8645lftUsvosKVUEfkdmOaMAnhrf4ekaHcb5gQw== dependencies: "@babel/runtime" "^7.7.2" utif "^2.0.1" -"@jimp/types@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/types/-/types-0.13.0.tgz#e397bc848ee9a01e0fe8e266efcc045f23c36f79" - integrity sha512-qGq9qVHiRTgtIy061FSBr9l7OFrSiFLkKyQVnOBndEjwls2XLBKXkMmSD2U3oiHcNuf3ACsDSTIzK3KX/hDHvg== +"@jimp/types@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/types/-/types-0.14.0.tgz#ef681ff702883c5f105b5e4e30d49abf39ee9e34" + integrity sha512-hx3cXAW1KZm+b+XCrY3LXtdWy2U+hNtq0rPyJ7NuXCjU7lZR3vIkpz1DLJ3yDdS70hTi5QDXY3Cd9kd6DtloHQ== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/bmp" "^0.13.0" - "@jimp/gif" "^0.13.0" - "@jimp/jpeg" "^0.13.0" - "@jimp/png" "^0.13.0" - "@jimp/tiff" "^0.13.0" + "@jimp/bmp" "^0.14.0" + "@jimp/gif" "^0.14.0" + "@jimp/jpeg" "^0.14.0" + "@jimp/png" "^0.14.0" + "@jimp/tiff" "^0.14.0" timm "^1.6.1" -"@jimp/utils@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@jimp/utils/-/utils-0.13.0.tgz#4cde8039a70a1c94baa33e4d8074e174ba895b74" - integrity sha512-zA4573jE4FIpBKiYpPGo66JOAGdv/FS/N9fW9GpkbwJeTu12fV+r4R1ARSyt8UEKdE4DMBatBmQC0U2FGZijOA== +"@jimp/utils@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@jimp/utils/-/utils-0.14.0.tgz#296254e63118554c62c31c19ac6b8c4bfe6490e5" + integrity sha512-MY5KFYUru0y74IsgM/9asDwb3ERxWxXEu3CRCZEvE7DtT86y1bR1XgtlSliMrptjz4qbivNGMQSvUBpEFJDp1A== dependencies: "@babel/runtime" "^7.7.2" regenerator-runtime "^0.13.3" @@ -15578,15 +15578,15 @@ jetpack-id@1.0.0: resolved "https://registry.yarnpkg.com/jetpack-id/-/jetpack-id-1.0.0.tgz#2cf9fbae46d8074fc16b7de0071c8efebca473a6" integrity sha1-LPn7rkbYB0/Ba33gBxyO/rykc6Y= -jimp@0.13.0: - version "0.13.0" - resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.13.0.tgz#d5497350adaebf5dd32e4b873871fe41297cccf4" - integrity sha512-N/iG8L7Qe+AcHhrgcL0m7PTP/14iybmSIuOqCDvuel9gcIKEzxbbGuPCJVMchwXzusc2E7h9UjO9LZDfXb/09w== +jimp@0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/jimp/-/jimp-0.14.0.tgz#fde55f69bdb918c1b01ac633d89a25853af85625" + integrity sha512-8BXU+J8+SPmwwyq9ELihpSV4dWPTiOKBWCEgtkbnxxAVMjXdf3yGmyaLSshBfXc8sP/JQ9OZj5R8nZzz2wPXgA== dependencies: "@babel/runtime" "^7.7.2" - "@jimp/custom" "^0.13.0" - "@jimp/plugins" "^0.13.0" - "@jimp/types" "^0.13.0" + "@jimp/custom" "^0.14.0" + "@jimp/plugins" "^0.14.0" + "@jimp/types" "^0.14.0" regenerator-runtime "^0.13.3" jmespath@0.15.0: From 128ee98641064cc48a321af2dea0d9dc83563051 Mon Sep 17 00:00:00 2001 From: Jennifer Shehane Date: Wed, 29 Jul 2020 12:06:28 +0630 Subject: [PATCH 12/36] chore: Use 'bump' range strategy for deps, use caret/tilde for CLI deps (#8060) --- cli/package.json | 74 ++++++++++++++++++++++++------------------------ renovate.json | 2 +- yarn.lock | 69 +++++++++++++++++++++++--------------------- 3 files changed, 75 insertions(+), 70 deletions(-) diff --git a/cli/package.json b/cli/package.json index 012ee33afe36..ee0610ee19a3 100644 --- a/cli/package.json +++ b/cli/package.json @@ -20,43 +20,43 @@ "unit": "cross-env BLUEBIRD_DEBUG=1 NODE_ENV=test mocha --reporter mocha-multi-reporters --reporter-options configFile=../mocha-reporter-config.json" }, "dependencies": { - "@cypress/listr-verbose-renderer": "0.4.1", - "@cypress/request": "2.88.5", - "@cypress/xvfb": "1.2.4", - "@types/sinonjs__fake-timers": "6.0.1", - "@types/sizzle": "2.3.2", - "arch": "2.1.2", - "bluebird": "3.7.2", - "cachedir": "2.3.0", - "chalk": "2.4.2", - "check-more-types": "2.24.0", - "cli-table3": "0.5.1", - "commander": "4.1.1", - "common-tags": "1.8.0", - "debug": "4.1.1", - "eventemitter2": "6.4.2", - "execa": "1.0.0", - "executable": "4.1.1", - "extract-zip": "1.7.0", - "fs-extra": "8.1.0", - "getos": "3.2.1", - "is-ci": "2.0.0", - "is-installed-globally": "0.3.2", - "lazy-ass": "1.6.0", - "listr": "0.14.3", - "lodash": "4.17.19", - "log-symbols": "3.0.0", - "minimist": "1.2.5", - "moment": "2.26.0", - "ospath": "1.2.2", - "pretty-bytes": "5.3.0", - "ramda": "0.26.1", - "request-progress": "3.0.0", - "supports-color": "7.1.0", - "tmp": "0.1.0", - "untildify": "4.0.0", - "url": "0.11.0", - "yauzl": "2.10.0" + "@cypress/listr-verbose-renderer": "^0.4.1", + "@cypress/request": "^2.88.5", + "@cypress/xvfb": "^1.2.4", + "@types/sinonjs__fake-timers": "^6.0.1", + "@types/sizzle": "^2.3.2", + "arch": "^2.1.2", + "bluebird": "^3.7.2", + "cachedir": "^2.3.0", + "chalk": "^2.4.2", + "check-more-types": "^2.24.0", + "cli-table3": "~0.5.1", + "commander": "^4.1.1", + "common-tags": "^1.8.0", + "debug": "^4.1.1", + "eventemitter2": "^6.4.2", + "execa": "^1.0.0", + "executable": "^4.1.1", + "extract-zip": "^1.7.0", + "fs-extra": "^8.1.0", + "getos": "^3.2.1", + "is-ci": "^2.0.0", + "is-installed-globally": "^0.3.2", + "lazy-ass": "^1.6.0", + "listr": "^0.14.3", + "lodash": "^4.17.19", + "log-symbols": "^3.0.0", + "minimist": "^1.2.5", + "moment": "^2.26.0", + "ospath": "^1.2.2", + "pretty-bytes": "^5.3.0", + "ramda": "~0.26.1", + "request-progress": "^3.0.0", + "supports-color": "^7.1.0", + "tmp": "~0.1.0", + "untildify": "^4.0.0", + "url": "^0.11.0", + "yauzl": "^2.10.0" }, "devDependencies": { "@babel/cli": "7.8.4", diff --git a/renovate.json b/renovate.json index bac49dbac7fb..66c810601224 100644 --- a/renovate.json +++ b/renovate.json @@ -9,7 +9,7 @@ "minor": { "automerge": false }, - "rangeStrategy": "pin", + "rangeStrategy": "bump", "packageRules": [ { "packagePatterns": "^@types/", diff --git a/yarn.lock b/yarn.lock index b02abd060ecf..8f8cf7a720e2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1574,7 +1574,7 @@ lodash.merge "^4.6.2" lodash.omit "^4.5.0" -"@cypress/listr-verbose-renderer@0.4.1": +"@cypress/listr-verbose-renderer@^0.4.1": version "0.4.1" resolved "https://registry.yarnpkg.com/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#a77492f4b11dcc7c446a34b3e28721afd33c642a" integrity sha1-p3SS9LEdzHxEajSz4ochr9M8ZCo= @@ -1626,7 +1626,7 @@ stealthy-require "^1.1.1" tough-cookie "^2.3.3" -"@cypress/request@2.88.5": +"@cypress/request@2.88.5", "@cypress/request@^2.88.5": version "2.88.5" resolved "https://registry.yarnpkg.com/@cypress/request/-/request-2.88.5.tgz#8d7ecd17b53a849cfd5ab06d5abe7d84976375d7" integrity sha512-TzEC1XMi1hJkywWpRfD2clreTa/Z+lOrXDCxxBTBPEcY5azdPi56A6Xw+O4tWJnaJH3iIE7G5aDXZC6JgRZLcA== @@ -1716,7 +1716,7 @@ lodash.includes "^4.3.0" lodash.isobject "^3.0.2" -"@cypress/xvfb@1.2.4": +"@cypress/xvfb@^1.2.4": version "1.2.4" resolved "https://registry.yarnpkg.com/@cypress/xvfb/-/xvfb-1.2.4.tgz#2daf42e8275b39f4aa53c14214e557bd14e7748a" integrity sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q== @@ -4232,12 +4232,12 @@ resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-7.5.1.tgz#d27b81af0d1cfe1f9b24eebe7a24f74ae40f5b7c" integrity sha512-EZQUP3hSZQyTQRfiLqelC9NMWd1kqLcmQE0dMiklxBkgi84T+cHOhnKpgk4NnOWpGX863yE6+IaGnOXUNFqDnQ== -"@types/sinonjs__fake-timers@*", "@types/sinonjs__fake-timers@6.0.1": +"@types/sinonjs__fake-timers@*", "@types/sinonjs__fake-timers@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.1.tgz#681df970358c82836b42f989188d133e218c458e" integrity sha512-yYezQwGWty8ziyYLdZjwxyMb0CZR49h8JALHGrxjQHWlqGgc8kLdHEgWrgL0uZ29DMvEVBDnHU2Wg36zKSIUtA== -"@types/sizzle@*", "@types/sizzle@2.3.2": +"@types/sizzle@*", "@types/sizzle@^2.3.2": version "2.3.2" resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47" integrity sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg== @@ -5167,7 +5167,7 @@ aproba@^2.0.0: resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== -arch@2.1.2, arch@^2.1.0: +arch@^2.1.0, arch@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/arch/-/arch-2.1.2.tgz#0c52bbe7344bb4fa260c443d2cbad9c00ff2f0bf" integrity sha512-NTBIIbAfkJeIletyABbVtdPgeKfDafR+1mZV/AyyfC1UkVkp9iUjV+wwmqtUgphHYajbI86jejBJp5e+jkGTiQ== @@ -6977,7 +6977,7 @@ bluebird@3.7.1: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.1.tgz#df70e302b471d7473489acf26a93d63b53f874de" integrity sha512-DdmyoGCleJnkbp3nkbxTLJ18rjDsE4yCggEwKNXkeV123sPNfOCYeDoeuOY+F2FrSjO1YXcTU+dsy96KMy+gcg== -bluebird@3.7.2, bluebird@^3.1.1, bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5: +bluebird@3.7.2, bluebird@^3.1.1, bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5, bluebird@^3.7.2: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== @@ -7692,7 +7692,7 @@ cached-path-relative@^1.0.0, cached-path-relative@^1.0.2: resolved "https://registry.yarnpkg.com/cached-path-relative/-/cached-path-relative-1.0.2.tgz#a13df4196d26776220cc3356eb147a52dba2c6db" integrity sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg== -cachedir@2.3.0: +cachedir@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw== @@ -8658,7 +8658,7 @@ commander@2.x.x, commander@^2.11.0, commander@^2.12.1, commander@^2.13.0, comman resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@4.1.1, commander@^4.0.1: +commander@^4.0.1, commander@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== @@ -11179,6 +11179,11 @@ eventemitter2@6.4.2: resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.2.tgz#f31f8b99d45245f0edbc5b00797830ff3b388970" integrity sha512-r/Pwupa5RIzxIHbEKCkNXqpEQIIT4uQDxmP4G/Lug/NokVUWj0joz/WzWl3OxRpC5kDrH/WdiUJoR+IrwvXJEw== +eventemitter2@^6.4.2: + version "6.4.3" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.3.tgz#35c563619b13f3681e7eb05cbdaf50f56ba58820" + integrity sha512-t0A2msp6BzOf+QAcI6z9XMktLj52OjGQg+8SJH6v5+3uxNpWYRR3wQmfA+6xtMU9kOC59qk9licus5dYcrYkMQ== + eventemitter3@^3.1.0: version "3.1.2" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7" @@ -11376,7 +11381,7 @@ execa@^2.0.3: signal-exit "^3.0.2" strip-final-newline "^2.0.0" -executable@4.1.1, executable@^4.1.0: +executable@^4.1.0, executable@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/executable/-/executable-4.1.1.tgz#41532bff361d3e57af4d763b70582db18f5d133c" integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg== @@ -11643,7 +11648,7 @@ extract-text-webpack-plugin@4.0.0-beta.0: schema-utils "^0.4.5" webpack-sources "^1.1.0" -extract-zip@1.7.0, extract-zip@^1.0.3: +extract-zip@^1.0.3, extract-zip@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/extract-zip/-/extract-zip-1.7.0.tgz#556cc3ae9df7f452c493a0cfb51cc30277940927" integrity sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA== @@ -12735,7 +12740,7 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= -getos@3.2.1: +getos@3.2.1, getos@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/getos/-/getos-3.2.1.tgz#0134d1f4e00eb46144c5a9c0ac4dc087cbb27dc5" integrity sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q== @@ -14634,14 +14639,6 @@ is-html@2.0.0: dependencies: html-tags "^3.0.0" -is-installed-globally@0.3.2, is-installed-globally@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141" - integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g== - dependencies: - global-dirs "^2.0.1" - is-path-inside "^3.0.1" - is-installed-globally@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" @@ -14650,6 +14647,14 @@ is-installed-globally@^0.1.0: global-dirs "^0.1.0" is-path-inside "^1.0.0" +is-installed-globally@^0.3.1, is-installed-globally@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141" + integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g== + dependencies: + global-dirs "^2.0.1" + is-path-inside "^3.0.1" + is-integer@^1.0.4: version "1.0.7" resolved "https://registry.yarnpkg.com/is-integer/-/is-integer-1.0.7.tgz#6bde81aacddf78b659b6629d629cadc51a886d5c" @@ -16744,7 +16749,7 @@ lodash@4.17.15: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== -lodash@4.17.19, lodash@^4.0.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.16.4, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.16, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.8.0, lodash@~4.17.10, lodash@~4.17.2: +lodash@4.17.19, lodash@^4.0.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.16.4, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.16, lodash@^4.17.19, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.8.0, lodash@~4.17.10, lodash@~4.17.2: version "4.17.19" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== @@ -17939,7 +17944,7 @@ moment@2.26.0: resolved "https://registry.yarnpkg.com/moment/-/moment-2.26.0.tgz#5e1f82c6bafca6e83e808b30c8705eed0dcbd39a" integrity sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw== -moment@^2.18.1, moment@^2.19.1, moment@^2.9.0: +moment@^2.18.1, moment@^2.19.1, moment@^2.26.0, moment@^2.9.0: version "2.27.0" resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d" integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ== @@ -19037,7 +19042,7 @@ osenv@0, osenv@^0.1.3, osenv@^0.1.4, osenv@^0.1.5: os-homedir "^1.0.0" os-tmpdir "^1.0.0" -ospath@1.2.2: +ospath@1.2.2, ospath@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/ospath/-/ospath-1.2.2.tgz#1276639774a3f8ef2572f7fe4280e0ea4550c07b" integrity sha1-EnZjl3Sj+O8lcvf+QoDg6kVQwHs= @@ -20053,7 +20058,7 @@ preserve@^0.2.0: resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks= -pretty-bytes@5.3.0: +pretty-bytes@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2" integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg== @@ -21486,7 +21491,7 @@ replace-homedir@^1.0.0: is-absolute "^1.0.0" remove-trailing-separator "^1.1.0" -request-progress@3.0.0: +request-progress@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/request-progress/-/request-progress-3.0.0.tgz#4ca754081c7fec63f505e4faa825aa06cd669dbe" integrity sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4= @@ -24777,11 +24782,6 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" -untildify@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" - integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== - untildify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0" @@ -24789,6 +24789,11 @@ untildify@^2.1.0: dependencies: os-homedir "^1.0.0" +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + unused-filename@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unused-filename/-/unused-filename-1.0.0.tgz#d340880f71ae2115ebaa1325bef05cc6684469c6" @@ -24919,7 +24924,7 @@ url@0.10.3: punycode "1.3.2" querystring "0.2.0" -url@0.11.0, url@^0.11.0, url@~0.11.0: +url@^0.11.0, url@~0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= @@ -26280,7 +26285,7 @@ yargs@~3.27.0: window-size "^0.1.2" y18n "^3.2.0" -yauzl@2.10.0, yauzl@^2.10.0: +yauzl@^2.10.0: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk= From 298612bc684e76d7338e54d8e6b9c0781662b9e7 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Wed, 29 Jul 2020 02:07:15 -0400 Subject: [PATCH 13/36] fix: Update visibility check for `position: fixed` combined with `pointer-events: none` (#8095) --- .../integration/dom/visibility_spec.ts | 36 ++++++++++++++++++- packages/driver/src/dom/visibility.js | 6 +++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/packages/driver/cypress/integration/dom/visibility_spec.ts b/packages/driver/cypress/integration/dom/visibility_spec.ts index c989d76bac9a..27beb750a03b 100644 --- a/packages/driver/cypress/integration/dom/visibility_spec.ts +++ b/packages/driver/cypress/integration/dom/visibility_spec.ts @@ -244,6 +244,12 @@ describe('src/cypress/dom/visibility', () => { `) + this.$childPointerEventsNone = add(`\ +
+ child pointer-events: none +
\ +`) + this.$descendentPosAbs = add(`\
@@ -289,6 +295,19 @@ describe('src/cypress/dom/visibility', () => { \ +`) + + this.$parentPointerEventsNone = add(`\ +
+ parent pointer-events: none +
\ +`) + + this.$parentPointerEventsNoneCovered = add(`\ +
+ parent pointer-events: none +
+covering the element with pointer-events: none\ `) this.$elOutOfParentBoundsToLeft = add(`\ @@ -688,7 +707,7 @@ describe('src/cypress/dom/visibility', () => { expect(this.$coveredUpPosFixed.find('#coveredUpPosFixed')).not.to.be.visible }) - it('is hidden if position: fixed and off screent', function () { + it('is hidden if position: fixed and off screen', function () { expect(this.$offScreenPosFixed).to.be.hidden expect(this.$offScreenPosFixed).not.to.be.visible }) @@ -702,6 +721,21 @@ describe('src/cypress/dom/visibility', () => { expect(this.$parentPosAbs.find('span')).to.be.hidden expect(this.$parentPosAbs.find('span')).to.not.be.visible }) + + it('is visible if position: fixed and parent has pointer-events: none', function () { + expect(this.$parentPointerEventsNone.find('span')).to.be.visible + expect(this.$parentPointerEventsNone.find('span')).to.not.be.hidden + }) + + it('is not visible if covered when position: fixed and parent has pointer-events: none', function () { + expect(this.$parentPointerEventsNoneCovered.find('span')).to.be.hidden + expect(this.$parentPointerEventsNoneCovered.find('span')).to.not.be.visible + }) + + it('is visible if pointer-events: none and parent has position: fixed', function () { + expect(this.$childPointerEventsNone.find('span')).to.be.visible + expect(this.$childPointerEventsNone.find('span')).to.not.be.hidden + }) }) describe('css overflow', () => { diff --git a/packages/driver/src/dom/visibility.js b/packages/driver/src/dom/visibility.js index 1c4d4881a590..ae6e941601d6 100644 --- a/packages/driver/src/dom/visibility.js +++ b/packages/driver/src/dom/visibility.js @@ -240,7 +240,11 @@ const elIsNotElementFromPoint = function ($el) { // if the element at point is not a descendent // of our $el then we know it's being covered or its // not visible - return !$elements.isDescendent($el, $elAtPoint) + + // we also check if the element at point is a + // parent since pointer-events: none + // will cause elAtCenterPoint to fall through to parent + return !($elements.isDescendent($el, $elAtPoint) || ($elAtPoint && $elements.isAncestor($el, $elAtPoint))) } const elIsOutOfBoundsOfAncestorsOverflow = function ($el, $ancestor = $el.parent()) { From b5b92a4459c001b577f84ab18c538d03f13a0ba5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2020 14:28:14 +0630 Subject: [PATCH 14/36] =?UTF-8?q?chore(deps):=20update=20dependency=20@cyp?= =?UTF-8?q?ress/webpack-preprocessor=20to=20version=205.4.2=20=F0=9F=8C=9F?= =?UTF-8?q?=20(#8116)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 8c360151b502..b75b154b6158 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "@cypress/questions-remain": "1.0.1", "@cypress/request": "2.88.5", "@cypress/request-promise": "4.2.6", - "@cypress/webpack-preprocessor": "5.4.1", + "@cypress/webpack-preprocessor": "5.4.2", "@fellow/eslint-plugin-coffee": "0.4.13", "@percy/cypress": "2.3.1", "@types/bluebird": "3.5.29", diff --git a/yarn.lock b/yarn.lock index 8f8cf7a720e2..67ee2981c6e9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1708,6 +1708,15 @@ debug "4.1.1" lodash "4.17.15" +"@cypress/webpack-preprocessor@5.4.2": + version "5.4.2" + resolved "https://registry.yarnpkg.com/@cypress/webpack-preprocessor/-/webpack-preprocessor-5.4.2.tgz#d40fed6375b09dd16b266a045f4577e9c7a0299a" + integrity sha512-ffydnj6mTVm83qc1p63dE2qxRkiIQNXxiHp2xyuVelwmksX+l0VSBxawYd/9Z99rInmqa583yUDPKk8IkCtmDg== + dependencies: + bluebird "3.7.1" + debug "4.1.1" + lodash "4.17.19" + "@cypress/what-is-circular@1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@cypress/what-is-circular/-/what-is-circular-1.0.1.tgz#c88adb7106a4e1624e403512fc87c18e9700c877" @@ -8276,7 +8285,7 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" -cli-table3@0.5.1: +cli-table3@0.5.1, cli-table3@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== @@ -20483,7 +20492,7 @@ ramda@0.25.0: resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.25.0.tgz#8fdf68231cffa90bc2f9460390a0cb74a29b29a9" integrity sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ== -ramda@0.26.1, ramda@^0.26.0, ramda@^0.26.1: +ramda@0.26.1, ramda@^0.26.0, ramda@^0.26.1, ramda@~0.26.1: version "0.26.1" resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ== @@ -24088,7 +24097,7 @@ tmp@0.0.33, tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" -tmp@0.1.0, tmp@^0.1.0: +tmp@0.1.0, tmp@^0.1.0, tmp@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.1.0.tgz#ee434a4e22543082e294ba6201dcc6eafefa2877" integrity sha512-J7Z2K08jbGcdA1kkQpJSqLF6T0tdQqpR2pnSUXsIchbPdTI9v3e85cLW0d6WDhwuAleOV71j2xWs8qMPfK7nKw== From 15c71c5bd765159362f02b26431b75ece74d52df Mon Sep 17 00:00:00 2001 From: Kukhyeon Heo Date: Thu, 30 Jul 2020 02:48:57 +0900 Subject: [PATCH 15/36] fix: Introduce CypressCommandLine namespace to type NPM module api --- cli/types/cypress-npm-api.d.ts | 10 ++++++---- cli/types/tests/cypress-npm-api-test.ts | 4 ++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/cli/types/cypress-npm-api.d.ts b/cli/types/cypress-npm-api.d.ts index c3c59f5e206e..40721b8fc0c9 100644 --- a/cli/types/cypress-npm-api.d.ts +++ b/cli/types/cypress-npm-api.d.ts @@ -6,7 +6,7 @@ // in the future the NPM module itself will be in TypeScript // but for now describe it as an ambient module -declare module 'cypress' { +declare namespace CypressCommandLine { /** * All options that one can pass to "cypress.run" * @see https://on.cypress.io/module-api#cypress-run @@ -324,7 +324,9 @@ declare module 'cypress' { */ parseRunArguments(args: string[]): Promise> } +} +declare module 'cypress' { /** * Cypress NPM module interface. * @see https://on.cypress.io/module-api @@ -349,19 +351,19 @@ declare module 'cypress' { }) ``` */ - run(options?: Partial): Promise, + run(options?: Partial): Promise, /** * Opens Cypress GUI. Resolves with void when the * GUI is closed. * @see https://on.cypress.io/module-api#cypress-open */ - open(options?: Partial): Promise + open(options?: Partial): Promise /** * Utility functions for parsing CLI arguments the same way * Cypress does */ - cli: CypressCliParser + cli: CypressCommandLine.CypressCliParser } // export Cypress NPM module interface diff --git a/cli/types/tests/cypress-npm-api-test.ts b/cli/types/tests/cypress-npm-api-test.ts index e4ae6fa3ba5f..8fbcd703c35d 100644 --- a/cli/types/tests/cypress-npm-api-test.ts +++ b/cli/types/tests/cypress-npm-api-test.ts @@ -38,3 +38,7 @@ const runConfig: Cypress.ConfigOptions = { }, } cypress.run({ config: runConfig }) + +cypress.run({}).then((results) => { + results as CypressCommandLine.CypressRunResult // $ExpectType CypressRunResult +}) From d246272bca4a3b6d409820a9c221132a82c7c4c5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 30 Jul 2020 18:02:19 +0630 Subject: [PATCH 16/36] =?UTF-8?q?fix(deps):=20update=20dependency=20moment?= =?UTF-8?q?=20to=20version=202.27.0=20=F0=9F=8C=9F=20(#8122)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Renovate Bot --- cli/package.json | 2 +- packages/desktop-gui/package.json | 2 +- packages/driver/package.json | 2 +- packages/server/package.json | 2 +- yarn.lock | 7 +------ 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/cli/package.json b/cli/package.json index ee0610ee19a3..37afdebc23d6 100644 --- a/cli/package.json +++ b/cli/package.json @@ -47,7 +47,7 @@ "lodash": "^4.17.19", "log-symbols": "^3.0.0", "minimist": "^1.2.5", - "moment": "^2.26.0", + "moment": "^2.27.0", "ospath": "^1.2.2", "pretty-bytes": "^5.3.0", "ramda": "~0.26.1", diff --git a/packages/desktop-gui/package.json b/packages/desktop-gui/package.json index bb6a382e3864..15898aa50a40 100644 --- a/packages/desktop-gui/package.json +++ b/packages/desktop-gui/package.json @@ -35,7 +35,7 @@ "mobx": "5.15.4", "mobx-react": "6.1.8", "mobx-react-devtools": "6.1.1", - "moment": "2.26.0", + "moment": "2.27.0", "prop-types": "15.7.2", "rc-collapse": "2.0.0", "react": "16.8.6", diff --git a/packages/driver/package.json b/packages/driver/package.json index d0eef3167728..c77551820a07 100644 --- a/packages/driver/package.json +++ b/packages/driver/package.json @@ -52,7 +52,7 @@ "minimatch": "3.0.4", "minimist": "1.2.5", "mocha": "7.0.1", - "moment": "2.26.0", + "moment": "2.27.0", "morgan": "1.9.1", "ordinal": "1.0.3", "react-15.6.1": "npm:react@15.6.1", diff --git a/packages/server/package.json b/packages/server/package.json index 55137bf9d2a2..6106327ec12c 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -86,7 +86,7 @@ "mocha-7.0.1": "npm:mocha@7.0.1", "mocha-junit-reporter": "1.23.1", "mocha-teamcity-reporter": "3.0.0", - "moment": "2.26.0", + "moment": "2.27.0", "morgan": "1.9.1", "node-machine-id": "1.1.12", "node-webkit-updater": "cypress-io/node-webkit-updater#e74623726f381487f543e373e71515177a32daeb", diff --git a/yarn.lock b/yarn.lock index 67ee2981c6e9..2a2337f38503 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17948,12 +17948,7 @@ module-not-found-error@^1.0.1: resolved "https://registry.yarnpkg.com/module-not-found-error/-/module-not-found-error-1.0.1.tgz#cf8b4ff4f29640674d6cdd02b0e3bc523c2bbdc0" integrity sha1-z4tP9PKWQGdNbN0CsOO8UjwrvcA= -moment@2.26.0: - version "2.26.0" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.26.0.tgz#5e1f82c6bafca6e83e808b30c8705eed0dcbd39a" - integrity sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw== - -moment@^2.18.1, moment@^2.19.1, moment@^2.26.0, moment@^2.9.0: +moment@2.27.0, moment@^2.18.1, moment@^2.19.1, moment@^2.27.0, moment@^2.9.0: version "2.27.0" resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d" integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ== From fe96d7cf2ac0108ccefd805f19860e721413d8a5 Mon Sep 17 00:00:00 2001 From: Gleb Bahmutov Date: Thu, 30 Jul 2020 10:29:21 -0400 Subject: [PATCH 17/36] feat: run only filtered specs (#8007) Co-authored-by: Jennifer Shehane --- cli/types/cypress.d.ts | 1 + .../cypress/integration/specs_list_spec.js | 70 +++- .../desktop-gui/src/projects/projects-api.js | 4 +- packages/desktop-gui/src/specs/specs-list.jsx | 82 ++++- packages/desktop-gui/src/specs/specs-store.js | 39 ++- packages/desktop-gui/src/specs/specs.scss | 10 +- .../cypress/integration/tests_spec.ts | 329 +++++++++++------- .../src/runnables/runnable-header.tsx | 9 +- packages/server/lib/controllers/files.js | 34 +- packages/server/lib/gui/events.js | 8 +- packages/server/lib/project.js | 2 + packages/server/lib/routes.js | 13 +- .../test/integration/http_requests_spec.js | 25 +- .../expected_todos_filtered_tests_iframe.html | 20 ++ packages/server/test/unit/gui/events_spec.js | 38 ++ 15 files changed, 514 insertions(+), 170 deletions(-) create mode 100644 packages/server/test/support/fixtures/server/expected_todos_filtered_tests_iframe.html diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index 5dafff160f25..03133300343d 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -218,6 +218,7 @@ declare namespace Cypress { name: string // "config_passing_spec.coffee" relative: string // "cypress/integration/config_passing_spec.coffee" or "__all" if clicked all specs button absolute: string + specFilter?: string // optional spec filter used by the user } /** diff --git a/packages/desktop-gui/cypress/integration/specs_list_spec.js b/packages/desktop-gui/cypress/integration/specs_list_spec.js index 313905c70f9d..44f9c7420fcb 100644 --- a/packages/desktop-gui/cypress/integration/specs_list_spec.js +++ b/packages/desktop-gui/cypress/integration/specs_list_spec.js @@ -201,12 +201,15 @@ describe('Specs List', function () { it('triggers browser launch on click of button', () => { cy.contains('.all-tests', 'Run all specs').click() + .find('.fa-dot-circle') .then(function () { const launchArgs = this.ipc.launchBrowser.lastCall.args - expect(launchArgs[0].browser.name).to.eq('chrome') + expect(launchArgs[0].browser.name, 'browser name').to.eq('chrome') - expect(launchArgs[0].spec.name).to.eq('All Specs') + expect(launchArgs[0].spec.name, 'spec name').to.eq('All Specs') + + expect(launchArgs[0].specFilter, 'spec filter').to.eq(null) }) }) @@ -406,13 +409,23 @@ describe('Specs List', function () { this.ipc.getSpecs.yields(null, this.specs) this.openProject.resolve(this.config) + cy.contains('.all-tests', 'Run all specs') cy.get('.filter').type('new') }) - it('displays only matching spec', () => { + it('displays only matching spec', function () { cy.get('.specs-list .file') .should('have.length', 1) .and('contain', 'account_new_spec.coffee') + + cy.contains('.all-tests', 'Run 1 spec').click() + .find('.fa-dot-circle') + .then(() => { + expect(this.ipc.launchBrowser).to.have.property('called').equal(true) + const launchArgs = this.ipc.launchBrowser.lastCall.args + + expect(launchArgs[0].specFilter, 'spec filter').to.eq('new') + }) }) it('only shows matching folders', () => { @@ -427,6 +440,8 @@ describe('Specs List', function () { cy.get('.specs-list .file') .should('have.length', this.numSpecs) + + cy.contains('.all-tests', 'Run all specs') }) it('clears the filter if the user press ESC key', function () { @@ -435,6 +450,9 @@ describe('Specs List', function () { cy.get('.specs-list .file') .should('have.length', this.numSpecs) + + cy.contains('.all-tests', 'Run all specs') + .find('.fa-play') }) it('shows empty message if no results', function () { @@ -442,6 +460,17 @@ describe('Specs List', function () { cy.get('.specs-list').should('not.exist') cy.get('.empty-well').should('contain', 'No specs match your search: "foobarbaz"') + + cy.contains('.all-tests', 'No specs') + }) + + it('disables run all tests if no results', function () { + cy.get('.filter').clear().type('foobarbaz') + + cy.contains('.all-tests', 'No specs').should('be.disabled').click({ force: true }) + .then(function () { + expect(this.ipc.launchBrowser).to.have.property('called').equal(false) + }) }) it('clears and focuses the filter field when clear search is clicked', function () { @@ -460,6 +489,29 @@ describe('Specs List', function () { expect(JSON.parse(win.localStorage[`specsFilter-${this.config.projectId}-/foo/bar`])).to.equal('new') }) }) + + it('does not update run button label while running', function () { + cy.contains('.all-tests', 'Run 1 spec').click() + // mock opened browser and running tests + // to force "Stop" button to show up + cy.window().its('__project').then((project) => { + project.browserOpened() + }) + + // the button has its its label reflect the running specs + cy.contains('.all-tests', 'Running 1 spec') + .should('have.class', 'active') + + // the button has its label unchanged while the specs are running + cy.get('.filter').clear() + cy.contains('.all-tests', 'Running 1 spec') + .should('have.class', 'active') + + // but once the project stops running tests, the button gets updated + cy.get('.close-browser').click() + cy.contains('.all-tests', 'Run all specs') + .should('not.have.class', 'active') + }) }) describe('when there\'s a saved filter', function () { @@ -475,6 +527,7 @@ describe('Specs List', function () { this.openProject.resolve(this.config) cy.get('.filter').should('have.value', 'app') + cy.contains('.all-tests', 'Run 1 spec') }) it('does not apply it for a different project', function () { @@ -525,7 +578,7 @@ describe('Specs List', function () { cy.get('@firstSpec') .click() .then(function () { - expect(this.ipc.closeBrowser).to.be.called + expect(this.ipc.closeBrowser).to.have.property('called', true) const launchArgs = this.ipc.launchBrowser.lastCall.args @@ -544,6 +597,12 @@ describe('Specs List', function () { .should('have.class', 'active') }) + it('shows the running spec label', () => { + cy.get('@firstSpec').click() + cy.contains('.all-tests', 'Running 1 spec') + .find('.fa-dot-circle') + }) + it('maintains active selection if specs change', function () { cy.get('@firstSpec').click().then(() => { this.ipc.getSpecs.yield(null, this.specs) @@ -682,7 +741,8 @@ describe('Specs List', function () { }) it('opens in preferred opener', function () { - cy.get('@button').click().then(() => { + cy.get('@button').click() + .then(() => { expect(this.ipc.openFile).to.be.calledWith({ where: this.availableEditors[4], file: '/user/project/cypress/integration/app_spec.coffee', diff --git a/packages/desktop-gui/src/projects/projects-api.js b/packages/desktop-gui/src/projects/projects-api.js index 67518cf210ed..533a13b4bea7 100644 --- a/packages/desktop-gui/src/projects/projects-api.js +++ b/packages/desktop-gui/src/projects/projects-api.js @@ -63,7 +63,8 @@ const addProject = (path) => { .return(project) } -const runSpec = (project, spec, browser) => { +// TODO: refactor to take options object +const runSpec = (project, spec, browser, specFilter) => { specsStore.setChosenSpec(spec) project.setChosenBrowser(browser) @@ -75,6 +76,7 @@ const runSpec = (project, spec, browser) => { spec: spec.file, specType: spec.specType, relative: spec.relative, + specFilter, } ipc.launchBrowser(launchOptions, (err, data = {}) => { diff --git a/packages/desktop-gui/src/specs/specs-list.jsx b/packages/desktop-gui/src/specs/specs-list.jsx index b88c3f729667..f201e709a0cd 100644 --- a/packages/desktop-gui/src/specs/specs-list.jsx +++ b/packages/desktop-gui/src/specs/specs-list.jsx @@ -15,12 +15,56 @@ class SpecsList extends Component { constructor (props) { super(props) this.filterRef = React.createRef() + // when the specs are running and the user changes the search filter + // we still want to show the previous button label to reflect what + // is currently running + this.runAllSavedLabel = null + + if (window.Cypress) { + // expose project object for testing + window.__project = this.props.project + } } render () { if (specsStore.isLoading) return - if (!specsStore.filter && !specsStore.specs.length) return this._empty() + const filteredSpecs = specsStore.getFilteredSpecs() + + const hasSpecFilter = specsStore.filter + const numberOfShownSpecs = filteredSpecs.length + const hasNoSpecs = !hasSpecFilter && !numberOfShownSpecs + + if (hasNoSpecs) { + return this._empty() + } + + const areTestsRunning = this._areTestsRunning() + let runSpecsLabel = allSpecsSpec.displayName + let runButtonDisabled = false + + if (areTestsRunning && this.runAllSavedLabel) { + runSpecsLabel = this.runAllSavedLabel + } else { + if (hasSpecFilter) { + if (numberOfShownSpecs < 1) { + runSpecsLabel = 'No specs' + runButtonDisabled = true + } else { + const specLabel = numberOfShownSpecs === 1 ? 'spec' : 'specs' + + runSpecsLabel = `Run ${numberOfShownSpecs} ${specLabel}` + } + } + } + + const runTestsButton = () return (
@@ -47,12 +91,7 @@ class SpecsList extends Component {
- - {' '} - {allSpecsSpec.displayName} - + {runTestsButton} {this._specsList()}
@@ -86,8 +125,17 @@ class SpecsList extends Component { return spec.hasChildren ? this._folderContent(spec, nestingLevel) : this._specContent(spec, nestingLevel) } - _allSpecsIcon (allSpecsChosen) { - return allSpecsChosen ? 'far fa-dot-circle green' : 'fas fa-play' + _allSpecsIcon () { + return this._areTestsRunning() ? 'far fa-dot-circle green' : 'fas fa-play' + } + + _areTestsRunning () { + if (!this.props.project) { + return false + } + + return this.props.project.browserState === 'opening' + || this.props.project.browserState === 'opened' } _specIcon (isChosen) { @@ -117,7 +165,21 @@ class SpecsList extends Component { const { project } = this.props - return projectsApi.runSpec(project, spec, project.chosenBrowser) + if (spec.relative === '__all') { + if (specsStore.filter) { + const filteredSpecs = specsStore.getFilteredSpecs() + const numberOfShownSpecs = filteredSpecs.length + + this.runAllSavedLabel = numberOfShownSpecs === 1 + ? 'Running 1 spec' : `Running ${numberOfShownSpecs} specs` + } else { + this.runAllSavedLabel = 'Running all specs' + } + } else { + this.runAllSavedLabel = 'Running 1 spec' + } + + return projectsApi.runSpec(project, spec, project.chosenBrowser, specsStore.filter) } _setExpandRootFolder (specFolderPath, isExpanded, e) { diff --git a/packages/desktop-gui/src/specs/specs-store.js b/packages/desktop-gui/src/specs/specs-store.js index 74ee745519b5..1968c24643d1 100644 --- a/packages/desktop-gui/src/specs/specs-store.js +++ b/packages/desktop-gui/src/specs/specs-store.js @@ -25,7 +25,27 @@ const pathsEqual = (path1, path2) => { return path1.replace(pathSeparatorRe, '') === path2.replace(pathSeparatorRe, '') } +/** + * Filters give file objects by spec name substring +*/ +const filterSpecs = (filter, files) => { + if (!filter) { + return files + } + + const filteredFiles = _.filter(files, (spec) => { + return spec.name.toLowerCase().includes(filter.toLowerCase()) + }) + + return filteredFiles +} + export class SpecsStore { + /** + * All spec files + * + * @memberof SpecsStore + */ @observable _files = [] @observable chosenSpecPath @observable error @@ -75,7 +95,9 @@ export class SpecsStore { } @action setFilter (project, filter = null) { - if (!filter) return this.clearFilter(project) + if (!filter) { + return this.clearFilter(project) + } localData.set(this.getSpecsFilterId(project), filter) @@ -106,12 +128,17 @@ export class SpecsStore { return specOrFolder.children.some((child) => child.isFolder) } + /** + * Returns only specs matching the current filter + * + * @memberof SpecsStore + */ + getFilteredSpecs () { + return filterSpecs(this.filter, this._files) + } + _tree (files) { - if (this.filter) { - files = _.filter(files, (spec) => { - return spec.name.toLowerCase().includes(this.filter.toLowerCase()) - }) - } + files = filterSpecs(this.filter, files) const tree = _.reduce(files, (root, file) => { const segments = [file.type].concat(file.name.split(pathSeparatorRe)) diff --git a/packages/desktop-gui/src/specs/specs.scss b/packages/desktop-gui/src/specs/specs.scss index be2da3974a87..1eed0bb0efcb 100644 --- a/packages/desktop-gui/src/specs/specs.scss +++ b/packages/desktop-gui/src/specs/specs.scss @@ -17,6 +17,8 @@ $max-nesting-level: 14; height: 42px; background: #f5f5f5; border-bottom: 1px solid #ddd; + display: flex; + justify-content: space-between; } .search { @@ -24,7 +26,7 @@ $max-nesting-level: 14; margin-right: 15px; display: inline-block; position: relative; - width: calc(100% - 140px); + width: calc(100% - 160px); label { position: absolute; @@ -91,10 +93,14 @@ $max-nesting-level: 14; pointer-events: none; color: #4c4e63; text-decoration: none; - } } + &:disabled { + cursor: not-allowed; + color: #ddd; + } + i { font-size: 8px; position: relative; diff --git a/packages/reporter/cypress/integration/tests_spec.ts b/packages/reporter/cypress/integration/tests_spec.ts index e2bcf0736036..5647c32073b4 100644 --- a/packages/reporter/cypress/integration/tests_spec.ts +++ b/packages/reporter/cypress/integration/tests_spec.ts @@ -2,179 +2,240 @@ import { EventEmitter } from 'events' import { itHandlesFileOpening } from '../support/utils' describe('controls', function () { - beforeEach(function () { - cy.fixture('runnables').as('runnables') - - this.runner = new EventEmitter() - - cy.visit('/dist').then((win) => { - win.render({ - runner: this.runner, - spec: { - name: 'foo.js', - relative: 'relative/path/to/foo.js', - absolute: '/absolute/path/to/foo.js', - }, + context('all specs', function () { + beforeEach(function () { + cy.fixture('runnables').as('runnables') + + this.runner = new EventEmitter() + + cy.visit('/dist').then((win) => { + win.render({ + runner: this.runner, + spec: { + relative: '__all', + name: '', + absolute: '', + }, + }) }) - }) - cy.get('.reporter').then(() => { - this.runner.emit('runnables:ready', this.runnables) + cy.get('.reporter').then(() => { + this.runner.emit('runnables:ready', this.runnables) - this.runner.emit('reporter:start', {}) + this.runner.emit('reporter:start', {}) + }) }) - }) - describe('tests', function () { - beforeEach(function () { - this.passingTestTitle = this.runnables.suites[0].tests[0].title - this.failingTestTitle = this.runnables.suites[0].tests[1].title + it('shows header', () => { + cy.contains('.runnable-header', 'All Specs') }) + }) - describe('expand and collapse', function () { - it('is collapsed by default', function () { - cy.contains(this.passingTestTitle) - .parents('.collapsible').first() - .should('not.have.class', 'is-open') - .find('.collapsible-content') - .should('not.be.visible') - }) - - describe('expand/collapse test manually', function () { - beforeEach(function () { - cy.contains(this.passingTestTitle) - .parents('.collapsible').first().as('testWrapper') - .should('not.have.class', 'is-open') - .find('.collapsible-content') - .should('not.be.visible') + context('filtered specs', function () { + beforeEach(function () { + cy.fixture('runnables').as('runnables') + + this.runner = new EventEmitter() + + cy.visit('/dist').then((win) => { + win.render({ + runner: this.runner, + spec: { + relative: '__all', + name: '', + absolute: '', + specFilter: 'cof', + }, }) + }) - it('expands/collapses on click', function () { - cy.contains(this.passingTestTitle) - .click() + cy.get('.reporter').then(() => { + this.runner.emit('runnables:ready', this.runnables) - cy.get('@testWrapper') - .should('have.class', 'is-open') - .find('.collapsible-content').should('be.visible') + this.runner.emit('reporter:start', {}) + }) + }) - cy.contains(this.passingTestTitle) - .click() + it('shows header', () => { + cy.contains('.runnable-header', 'Specs matching "cof"') + }) + }) - cy.get('@testWrapper') - .should('not.have.class', 'is-open') - .find('.collapsible-content').should('not.be.visible') + context('single spec', function () { + beforeEach(function () { + cy.fixture('runnables').as('runnables') + + this.runner = new EventEmitter() + + cy.visit('/dist').then((win) => { + win.render({ + runner: this.runner, + spec: { + name: 'foo.js', + relative: 'relative/path/to/foo.js', + absolute: '/absolute/path/to/foo.js', + }, }) + }) - it('expands/collapses on enter', function () { - cy.contains(this.passingTestTitle) - .parents('.collapsible-header').first() - .focus().type('{enter}') + cy.get('.reporter').then(() => { + this.runner.emit('runnables:ready', this.runnables) - cy.get('@testWrapper') - .should('have.class', 'is-open') - .find('.collapsible-content').should('be.visible') + this.runner.emit('reporter:start', {}) + }) + }) - cy.contains(this.passingTestTitle) - .parents('.collapsible-header').first() - .focus().type('{enter}') + describe('tests', function () { + beforeEach(function () { + this.passingTestTitle = this.runnables.suites[0].tests[0].title + this.failingTestTitle = this.runnables.suites[0].tests[1].title + }) - cy.get('@testWrapper') + describe('expand and collapse', function () { + it('is collapsed by default', function () { + cy.contains(this.passingTestTitle) + .parents('.collapsible').first() .should('not.have.class', 'is-open') - .find('.collapsible-content').should('not.be.visible') + .find('.collapsible-content') + .should('not.be.visible') }) - it('expands/collapses on space', function () { - cy.contains(this.passingTestTitle) - .parents('.collapsible-header').first() - .focus().type(' ') - - cy.get('@testWrapper') - .should('have.class', 'is-open') - .find('.collapsible-content').should('be.visible') - - cy.contains(this.passingTestTitle) - .parents('.collapsible-header').first() - .focus().type(' ') - - cy.get('@testWrapper') - .should('not.have.class', 'is-open') - .find('.collapsible-content').should('not.be.visible') + describe('expand/collapse test manually', function () { + beforeEach(function () { + cy.contains(this.passingTestTitle) + .parents('.collapsible').first().as('testWrapper') + .should('not.have.class', 'is-open') + .find('.collapsible-content') + .should('not.be.visible') + }) + + it('expands/collapses on click', function () { + cy.contains(this.passingTestTitle) + .click() + + cy.get('@testWrapper') + .should('have.class', 'is-open') + .find('.collapsible-content').should('be.visible') + + cy.contains(this.passingTestTitle) + .click() + + cy.get('@testWrapper') + .should('not.have.class', 'is-open') + .find('.collapsible-content').should('not.be.visible') + }) + + it('expands/collapses on enter', function () { + cy.contains(this.passingTestTitle) + .parents('.collapsible-header').first() + .focus().type('{enter}') + + cy.get('@testWrapper') + .should('have.class', 'is-open') + .find('.collapsible-content').should('be.visible') + + cy.contains(this.passingTestTitle) + .parents('.collapsible-header').first() + .focus().type('{enter}') + + cy.get('@testWrapper') + .should('not.have.class', 'is-open') + .find('.collapsible-content').should('not.be.visible') + }) + + it('expands/collapses on space', function () { + cy.contains(this.passingTestTitle) + .parents('.collapsible-header').first() + .focus().type(' ') + + cy.get('@testWrapper') + .should('have.class', 'is-open') + .find('.collapsible-content').should('be.visible') + + cy.contains(this.passingTestTitle) + .parents('.collapsible-header').first() + .focus().type(' ') + + cy.get('@testWrapper') + .should('not.have.class', 'is-open') + .find('.collapsible-content').should('not.be.visible') + }) }) }) - }) - describe('failed tests', function () { - it('expands automatically', function () { - cy.contains(this.failingTestTitle) - .parents('.collapsible').first() - .should('have.class', 'is-open') - .find('.collapsible-content') - .should('be.visible') + describe('failed tests', function () { + it('expands automatically', function () { + cy.contains(this.failingTestTitle) + .parents('.collapsible').first() + .should('have.class', 'is-open') + .find('.collapsible-content') + .should('be.visible') + }) }) - }) - describe('header', function () { - it('displays', function () { - cy.get('.runnable-header').find('a').should('have.text', 'relative/path/to/foo.js') - }) + describe('header', function () { + it('displays', function () { + cy.get('.runnable-header').find('a').should('have.text', 'relative/path/to/foo.js') + }) - it('displays tooltip on hover', () => { - cy.get('.runnable-header a').first().trigger('mouseover') - cy.get('.cy-tooltip').first().should('have.text', 'Open in IDE') - }) + it('displays tooltip on hover', () => { + cy.get('.runnable-header a').first().trigger('mouseover') + cy.get('.cy-tooltip').first().should('have.text', 'Open in IDE') + }) - itHandlesFileOpening('.runnable-header a', { - file: '/absolute/path/to/foo.js', - line: 0, - column: 0, + itHandlesFileOpening('.runnable-header a', { + file: '/absolute/path/to/foo.js', + line: 0, + column: 0, + }) }) - }) - describe('progress bar', function () { - it('displays', function () { - cy.get('.runnable-active').click() - cy.get('.command-progress').should('be.visible') - }) + describe('progress bar', function () { + it('displays', function () { + cy.get('.runnable-active').click() + cy.get('.command-progress').should('be.visible') + }) - it('calculates correct width', function () { - const { wallClockStartedAt } = this.runnables.suites[0].suites[0].tests[1].commands[0] + it('calculates correct width', function () { + const { wallClockStartedAt } = this.runnables.suites[0].suites[0].tests[1].commands[0] - // take the wallClockStartedAt of this command and add 2500 milliseconds to it - // in order to simulate the command having run for 2.5 seconds of the total 4000 timeout - const date = new Date(wallClockStartedAt).setMilliseconds(2500) + // take the wallClockStartedAt of this command and add 2500 milliseconds to it + // in order to simulate the command having run for 2.5 seconds of the total 4000 timeout + const date = new Date(wallClockStartedAt).setMilliseconds(2500) - cy.clock(date, ['Date']) - cy.get('.runnable-active').click() - cy.get('.command-progress > span').should(($span) => { - expect($span.attr('style')).to.contain('animation-duration: 1500ms') - expect($span.attr('style')).to.contain('width: 37.5%') + cy.clock(date, ['Date']) + cy.get('.runnable-active').click() + cy.get('.command-progress > span').should(($span) => { + expect($span.attr('style')).to.contain('animation-duration: 1500ms') + expect($span.attr('style')).to.contain('width: 37.5%') - // ensures that actual width hits 0 within default timeout - expect($span).to.have.css('width', '0px') + // ensures that actual width hits 0 within default timeout + expect($span).to.have.css('width', '0px') + }) }) - }) - it('recalculates correct width after being closed', function () { - const { wallClockStartedAt } = this.runnables.suites[0].suites[0].tests[1].commands[0] + it('recalculates correct width after being closed', function () { + const { wallClockStartedAt } = this.runnables.suites[0].suites[0].tests[1].commands[0] - // take the wallClockStartedAt of this command and add 1000 milliseconds to it - // in order to simulate the command having run for 1 second of the total 4000 timeout - const date = new Date(wallClockStartedAt).setMilliseconds(1000) + // take the wallClockStartedAt of this command and add 1000 milliseconds to it + // in order to simulate the command having run for 1 second of the total 4000 timeout + const date = new Date(wallClockStartedAt).setMilliseconds(1000) - cy.clock(date, ['Date']) - cy.get('.runnable-active').click() - cy.get('.command-progress > span').should(($span) => { - expect($span.attr('style')).to.contain('animation-duration: 3000ms') - expect($span.attr('style')).to.contain('width: 75%') - }) + cy.clock(date, ['Date']) + cy.get('.runnable-active').click() + cy.get('.command-progress > span').should(($span) => { + expect($span.attr('style')).to.contain('animation-duration: 3000ms') + expect($span.attr('style')).to.contain('width: 75%') + }) - // set the clock ahead as if time has passed - cy.tick(2000) + // set the clock ahead as if time has passed + cy.tick(2000) - cy.get('.runnable-active > .collapsible > .runnable-wrapper').click().click() - cy.get('.command-progress > span').should(($span) => { - expect($span.attr('style')).to.contain('animation-duration: 1000ms') - expect($span.attr('style')).to.contain('width: 25%') + cy.get('.runnable-active > .collapsible > .runnable-wrapper').click().click() + cy.get('.command-progress > span').should(($span) => { + expect($span.attr('style')).to.contain('animation-duration: 1000ms') + expect($span.attr('style')).to.contain('width: 25%') + }) }) }) }) diff --git a/packages/reporter/src/runnables/runnable-header.tsx b/packages/reporter/src/runnables/runnable-header.tsx index 2f57fd2e5708..42a8bbb69982 100644 --- a/packages/reporter/src/runnables/runnable-header.tsx +++ b/packages/reporter/src/runnables/runnable-header.tsx @@ -2,7 +2,7 @@ import React, { Component, ReactElement } from 'react' import FileNameOpener from '../lib/file-name-opener' -const renderRunnableHeader = (children:ReactElement) =>
{children}
+const renderRunnableHeader = (children: ReactElement) =>
{children}
interface RunnableHeaderProps { spec: Cypress.Cypress['spec'] @@ -11,9 +11,16 @@ interface RunnableHeaderProps { class RunnableHeader extends Component { render () { const { spec } = this.props + const relativeSpecPath = spec.relative if (spec.relative === '__all') { + if (spec.specFilter) { + return renderRunnableHeader( + Specs matching "{spec.specFilter}", + ) + } + return renderRunnableHeader( All Specs, ) diff --git a/packages/server/lib/controllers/files.js b/packages/server/lib/controllers/files.js index 6f7fe9ffa78a..8c0a95e64024 100644 --- a/packages/server/lib/controllers/files.js +++ b/packages/server/lib/controllers/files.js @@ -23,20 +23,25 @@ module.exports = { }) }, - handleIframe (req, res, config, getRemoteState) { + handleIframe (req, res, config, getRemoteState, extraOptions) { const test = req.params[0] const iframePath = cwd('lib', 'html', 'iframe.html') + const specFilter = _.get(extraOptions, 'specFilter') - debug('handle iframe %o', { test }) + debug('handle iframe %o', { test, specFilter }) - return this.getSpecs(test, config) + return this.getSpecs(test, config, extraOptions) .then((specs) => { return this.getJavascripts(config) .then((js) => { + const allFilesToSend = js.concat(specs) + + debug('all files to send %o', _.map(allFilesToSend, 'relative')) + const iframeOptions = { title: this.getTitle(test), domain: getRemoteState().domainName, - scripts: JSON.stringify(js.concat(specs)), + scripts: JSON.stringify(allFilesToSend), } debug('iframe %s options %o', test, iframeOptions) @@ -46,8 +51,8 @@ module.exports = { }) }, - getSpecs (spec, config) { - debug('get specs %o', { spec }) + getSpecs (spec, config, extraOptions = {}) { + debug('get specs %o', { spec, extraOptions }) const convertSpecPath = (spec) => { // get the absolute path to this spec and @@ -59,15 +64,30 @@ module.exports = { return this.prepareForBrowser(convertedSpec, config.projectRoot) } + const specFilter = _.get(extraOptions, 'specFilter') + + debug('specFilter %o', { specFilter }) + const specFilterContains = (spec) => { + // only makes sense if there is specFilter string + // the filter should match the logic in + // desktop-gui/src/specs/specs-store.js + return spec.relative.toLowerCase().includes(specFilter.toLowerCase()) + } + const specFilterFn = specFilter ? specFilterContains : R.T + const getSpecsHelper = () => { // grab all of the specs if this is ci const experimentalComponentTestingEnabled = _.get(config, 'resolved.experimentalComponentTesting.value', false) if (spec === '__all') { + debug('returning all specs') + return specsUtil.find(config) .then(R.tap((specs) => { return debug('found __all specs %o', specs) - })).filter((spec) => { + })) + .filter(specFilterFn) + .filter((spec) => { if (experimentalComponentTestingEnabled) { return spec.specType === 'integration' } diff --git a/packages/server/lib/gui/events.js b/packages/server/lib/gui/events.js index f034cef9ac77..6bf51c919b19 100644 --- a/packages/server/lib/gui/events.js +++ b/packages/server/lib/gui/events.js @@ -127,12 +127,18 @@ const handleEvent = function (options, bus, event, id, type, arg) { case 'launch:browser': // is there a way to lint the arguments received? debug('launching browser for \'%s\' spec: %o', arg.specType, arg.spec) + debug('full list of options %o', arg) + // the "arg" should have objects for // - browser // - spec (with fields) // name, absolute, relative // - specType: "integration" | "component" - const fullSpec = _.merge({}, arg.spec, { specType: arg.specType }) + // - specFilter (optional): the string user searched for + const fullSpec = _.merge({}, arg.spec, { + specType: arg.specType, + specFilter: arg.specFilter, + }) return openProject.launch(arg.browser, fullSpec, { projectRoot: options.projectRoot, diff --git a/packages/server/lib/project.js b/packages/server/lib/project.js index d18a16676451..0feeef31eed1 100644 --- a/packages/server/lib/project.js +++ b/packages/server/lib/project.js @@ -501,6 +501,8 @@ class Project extends EE { } getSpecUrl (absoluteSpecPath, specType) { + debug('get spec url: %s for spec type %s', absoluteSpecPath, specType) + return this.getConfig() .then((cfg) => { // if we don't have a absoluteSpecPath or its __all diff --git a/packages/server/lib/routes.js b/packages/server/lib/routes.js index 6c69630b8739..21b571c7c20b 100644 --- a/packages/server/lib/routes.js +++ b/packages/server/lib/routes.js @@ -1,6 +1,7 @@ const path = require('path') const la = require('lazy-ass') const check = require('check-more-types') +const _ = require('lodash') const debug = require('debug')('cypress:server:routes') const AppData = require('./util/app_data') @@ -46,7 +47,17 @@ module.exports = ({ app, config, getRemoteState, networkProxy, project, onError // routing for the dynamic iframe html app.get('/__cypress/iframes/*', (req, res) => { - files.handleIframe(req, res, config, getRemoteState) + const extraOptions = { + specFilter: _.get(project, 'spec.specFilter'), + } + + debug('project %o', project) + debug('handling iframe for project spec %o', { + spec: project.spec, + extraOptions, + }) + + files.handleIframe(req, res, config, getRemoteState, extraOptions) }) app.all('/__cypress/xhrs/*', (req, res, next) => { diff --git a/packages/server/test/integration/http_requests_spec.js b/packages/server/test/integration/http_requests_spec.js index 30b44bea47e6..5c2e6844bcf8 100644 --- a/packages/server/test/integration/http_requests_spec.js +++ b/packages/server/test/integration/http_requests_spec.js @@ -159,7 +159,7 @@ describe('Routes', () => { } const open = () => { - const project = new Project('/path/to/project') + this.project = new Project('/path/to/project') return Promise.all([ // open our https server @@ -168,7 +168,7 @@ describe('Routes', () => { // and open our cypress server (this.server = new Server(new Watchers())), - this.server.open(cfg, project) + this.server.open(cfg, this.project) .spread((port) => { if (initialUrl) { this.server._onDomainSet(initialUrl) @@ -202,6 +202,7 @@ describe('Routes', () => { Fixtures.remove() this.session.destroy() preprocessor.close() + this.project = null return Promise.join( this.server.close(), @@ -1137,6 +1138,26 @@ describe('Routes', () => { expect(body).to.eq(contents) }) }) + + it('can send back tests matching spec filter', function () { + // only returns tests with "sub_test" in their names + const contents = removeWhitespace(Fixtures.get('server/expected_todos_filtered_tests_iframe.html')) + + this.project.spec = { + specFilter: 'sub_test', + } + + return this.rp('http://localhost:2020/__cypress/iframes/__all') + .then((res) => { + expect(res.statusCode).to.eq(200) + + const body = cleanResponseBody(res.body) + + console.log(body) + + expect(body).to.eq(contents) + }) + }) }) describe('no-server', () => { diff --git a/packages/server/test/support/fixtures/server/expected_todos_filtered_tests_iframe.html b/packages/server/test/support/fixtures/server/expected_todos_filtered_tests_iframe.html new file mode 100644 index 000000000000..7cb5fb026838 --- /dev/null +++ b/packages/server/test/support/fixtures/server/expected_todos_filtered_tests_iframe.html @@ -0,0 +1,20 @@ + + + + + All Tests + + + + + diff --git a/packages/server/test/unit/gui/events_spec.js b/packages/server/test/unit/gui/events_spec.js index 8c21facd7ce5..af69794ef349 100644 --- a/packages/server/test/unit/gui/events_spec.js +++ b/packages/server/test/unit/gui/events_spec.js @@ -973,6 +973,7 @@ describe('lib/gui/events', () => { absolute: '/path/to/bar', relative: 'to/bar', specType: 'integration', + specFilter: undefined, }) opts.onBrowserOpen() @@ -999,6 +1000,43 @@ describe('lib/gui/events', () => { }) }) + it('passes specFilter', function () { + sinon.stub(openProject, 'launch').callsFake((browser, spec, opts) => { + debug('spec was %o', spec) + expect(browser, 'browser').to.eq('foo') + expect(spec, 'spec').to.deep.equal({ + name: 'bar', + absolute: '/path/to/bar', + relative: 'to/bar', + specType: 'integration', + specFilter: 'network', + }) + + opts.onBrowserOpen() + opts.onBrowserClose() + + return Promise.resolve() + }) + + const spec = { + name: 'bar', + absolute: '/path/to/bar', + relative: 'to/bar', + } + const arg = { + browser: 'foo', + spec, + specType: 'integration', + specFilter: 'network', + } + + return this.handleEvent('launch:browser', arg).then(() => { + expect(this.send.getCall(0).args[1].data).to.include({ browserOpened: true }) + + expect(this.send.getCall(1).args[1].data).to.include({ browserClosed: true }) + }) + }) + it('wraps error titles if not set', function () { const err = new Error('foo') From e1f9c80594f36f7856e54b5c58bb246506e847b3 Mon Sep 17 00:00:00 2001 From: Jennifer Shehane Date: Fri, 31 Jul 2020 02:38:21 +0630 Subject: [PATCH 18/36] docs: Update contributing to mention titling PRs with semantic-release (#8125) * Update contributing to mention titling PRs with semantic-release * Update CONTRIBUTING.md link --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3e27132ea97d..6cee6765db00 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -518,6 +518,7 @@ The repository is setup with two main (protected) branches. - When opening a PR for a specific issue already open, please name the branch you are working on using the convention `issue-[issue number]`. For example, if your PR fixes Issue #803, name your branch `issue-803`. If the PR is a larger issue, you can add more context like `issue-803-new-scrollable-area` If there is not an associated open issue, **create an issue using our [Issue Template](./.github/ISSUE_TEMPLATE.md)**. - PR's can be opened before all the work is finished. In fact we encourage this! Please create a [Draft Pull Request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests#draft-pull-requests) if your PR is not ready for review. [Mark the PR as **Ready for Review**](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/changing-the-stage-of-a-pull-request#marking-a-pull-request-as-ready-for-review) when you're ready for a Cypress team member to review the PR. +- Prefix the title of the Pull Request using [semantic-release](https://github.com/semantic-release/semantic-release)'s format as defined [here](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#type). For example, if your PR is fixing a bug, you should prefix the PR title with `fix:`. - Fill out the [Pull Request Template](./.github/PULL_REQUEST_TEMPLATE.md) completely within the body of the PR. If you feel some areas are not relevant add `N/A` as opposed to deleting those sections. PR's will not be reviewed if this template is not filled in. - Please check the "Allow edits from maintainers" checkbox when submitting your PR. This will make it easier for the maintainers to make minor adjustments, to help with tests or any other changes we may need. ![Allow edits from maintainers checkbox](https://user-images.githubusercontent.com/1271181/31393427-b3105d44-ada9-11e7-80f2-0dac51e3919e.png) From 497745037fb0b80601f7f937d04b3aa61ecb620b Mon Sep 17 00:00:00 2001 From: Matteo Maronati Date: Fri, 31 Jul 2020 17:48:30 +0200 Subject: [PATCH 19/36] fix: Cookie interface expiry prop (#8145) --- cli/types/cypress.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index 03133300343d..7031603da8fd 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -5110,7 +5110,7 @@ declare namespace Cypress { domain: string httpOnly: boolean secure: boolean - expiry?: string + expiry?: number sameSite?: SameSiteStatus } From 008f07a4db11702011fc172e0036671ea9bf4ed7 Mon Sep 17 00:00:00 2001 From: Josh Ribakoff Date: Sun, 2 Aug 2020 21:52:09 -0700 Subject: [PATCH 20/36] chore: a typo in comment (#8150) --- packages/driver/src/cy/commands/actions/click.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/driver/src/cy/commands/actions/click.js b/packages/driver/src/cy/commands/actions/click.js index b564e2f99350..db6ba8de67d3 100644 --- a/packages/driver/src/cy/commands/actions/click.js +++ b/packages/driver/src/cy/commands/actions/click.js @@ -143,7 +143,7 @@ module.exports = (Commands, Cypress, cy, state, config) => { } // must use callbacks here instead of .then() - // because we're issuing the clicks synchonrously + // because we're issuing the clicks synchronously // once we establish the coordinates and the element // passes all of the internal checks return $actionability.verify(cy, $el, options, { From 19393e09d14123aa65f21cdbde1ba9b25a77b3e2 Mon Sep 17 00:00:00 2001 From: Zach Panzarino Date: Mon, 3 Aug 2020 02:36:13 -0400 Subject: [PATCH 21/36] fix(reporter): minor UI fixes and improvements (#8153) --- packages/reporter/src/agents/agents.tsx | 2 +- packages/reporter/src/commands/commands.scss | 2 +- packages/reporter/src/routes/routes.tsx | 2 +- packages/reporter/src/runnables/runnables.scss | 1 + 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/reporter/src/agents/agents.tsx b/packages/reporter/src/agents/agents.tsx index 7a2db43a7f57..6e786ed81082 100644 --- a/packages/reporter/src/agents/agents.tsx +++ b/packages/reporter/src/agents/agents.tsx @@ -45,7 +45,7 @@ const Agents = observer(({ model }: AgentsProps) => (
  • diff --git a/packages/reporter/src/commands/commands.scss b/packages/reporter/src/commands/commands.scss index 032457d68618..3a5287a6a21a 100644 --- a/packages/reporter/src/commands/commands.scss +++ b/packages/reporter/src/commands/commands.scss @@ -40,7 +40,7 @@ padding: 4px 0; &:focus { - outline: 1px dotted #6c6c6c; + outline: none; } > .collapsible-header-inner:focus { diff --git a/packages/reporter/src/routes/routes.tsx b/packages/reporter/src/routes/routes.tsx index dfcb1bb7274e..9b4d1d8b1040 100644 --- a/packages/reporter/src/routes/routes.tsx +++ b/packages/reporter/src/routes/routes.tsx @@ -55,7 +55,7 @@ const Routes = observer(({ model }: RoutesProps) => (
  • diff --git a/packages/reporter/src/runnables/runnables.scss b/packages/reporter/src/runnables/runnables.scss index 299f1b173ac4..e0c445ff6162 100644 --- a/packages/reporter/src/runnables/runnables.scss +++ b/packages/reporter/src/runnables/runnables.scss @@ -111,6 +111,7 @@ &.runnable-pending > div > .runnable-wrapper, &.runnable-pending > div > .runnable-instruments { border-left: 5px solid lighten($pending, 25%); + padding-bottom: 0; } &.runnable-passed > div > .runnable-wrapper, From e0f587e5b74aa5217374547e5ce9b601b6472583 Mon Sep 17 00:00:00 2001 From: Martyn Chamberlin Date: Mon, 3 Aug 2020 03:34:03 -0500 Subject: [PATCH 22/36] fix: iFrame input focus should not cause blur if input already activeElement (#8112) Co-authored-by: Chris Breiding Co-authored-by: Jennifer Shehane --- packages/driver/src/cy/focused.js | 13 ++++++++----- packages/server/test/e2e/3_issue_8111_spec.js | 16 ++++++++++++++++ .../issue-8111-iframe-input/cypress.json | 3 +++ .../cypress/integration/iframe_input_spec.js | 8 ++++++++ .../cypress/plugins/index.js | 7 +++++++ .../projects/issue-8111-iframe-input/inner.html | 4 ++++ .../projects/issue-8111-iframe-input/outer.html | 1 + 7 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 packages/server/test/e2e/3_issue_8111_spec.js create mode 100644 packages/server/test/support/fixtures/projects/issue-8111-iframe-input/cypress.json create mode 100644 packages/server/test/support/fixtures/projects/issue-8111-iframe-input/cypress/integration/iframe_input_spec.js create mode 100644 packages/server/test/support/fixtures/projects/issue-8111-iframe-input/cypress/plugins/index.js create mode 100644 packages/server/test/support/fixtures/projects/issue-8111-iframe-input/inner.html create mode 100644 packages/server/test/support/fixtures/projects/issue-8111-iframe-input/outer.html diff --git a/packages/driver/src/cy/focused.js b/packages/driver/src/cy/focused.js index e0c3c224ef4c..913ddf369760 100644 --- a/packages/driver/src/cy/focused.js +++ b/packages/driver/src/cy/focused.js @@ -89,9 +89,12 @@ const create = (state) => { const win = $window.getWindowByElement(el) - // store the current focused element - // since when we call .focus() it will change - const $focused = getFocused() + // store the current focused element, since it will change when we call .focus() + // + // need to pass in el.ownerDocument to get the correct focused element + // when el is in an iframe and the browser is not + // in focus (https://github.com/cypress-io/cypress/issues/8111) + const $focused = getFocused(el.ownerDocument) let hasFocused = false @@ -220,8 +223,8 @@ const create = (state) => { return false } - const getFocused = () => { - const { activeElement } = state('document') + const getFocused = (document = state('document')) => { + const { activeElement } = document if ($dom.isFocused(activeElement)) { return $dom.wrap(activeElement) diff --git a/packages/server/test/e2e/3_issue_8111_spec.js b/packages/server/test/e2e/3_issue_8111_spec.js new file mode 100644 index 000000000000..f775270ef993 --- /dev/null +++ b/packages/server/test/e2e/3_issue_8111_spec.js @@ -0,0 +1,16 @@ +const e2e = require('../support/helpers/e2e').default +const Fixtures = require('../support/helpers/fixtures') + +describe('e2e issue 8111 iframe input focus', function () { + e2e.setup() + + e2e.it('iframe input retains focus when browser is out of focus', { + // this test is dependent on the browser being Chrome headed + // and also having --auto-open-devtools-for-tabs plugins option + // (which pulls focus from main browser window) + project: Fixtures.projectPath('issue-8111-iframe-input'), + spec: 'iframe_input_spec.js', + browser: 'chrome', + headed: true, + }) +}) diff --git a/packages/server/test/support/fixtures/projects/issue-8111-iframe-input/cypress.json b/packages/server/test/support/fixtures/projects/issue-8111-iframe-input/cypress.json new file mode 100644 index 000000000000..9c5417cd8268 --- /dev/null +++ b/packages/server/test/support/fixtures/projects/issue-8111-iframe-input/cypress.json @@ -0,0 +1,3 @@ +{ + "supportFolder": false +} diff --git a/packages/server/test/support/fixtures/projects/issue-8111-iframe-input/cypress/integration/iframe_input_spec.js b/packages/server/test/support/fixtures/projects/issue-8111-iframe-input/cypress/integration/iframe_input_spec.js new file mode 100644 index 000000000000..c605183f66e3 --- /dev/null +++ b/packages/server/test/support/fixtures/projects/issue-8111-iframe-input/cypress/integration/iframe_input_spec.js @@ -0,0 +1,8 @@ +it('can type into an input in an iframe that calls auto focus', () => { + cy.visit('/outer.html') + cy.get('iframe') + .its('0.contentDocument.body').should('not.be.empty') + .then(cy.wrap) + .find('input') + .type(42) +}) diff --git a/packages/server/test/support/fixtures/projects/issue-8111-iframe-input/cypress/plugins/index.js b/packages/server/test/support/fixtures/projects/issue-8111-iframe-input/cypress/plugins/index.js new file mode 100644 index 000000000000..f04098567ec3 --- /dev/null +++ b/packages/server/test/support/fixtures/projects/issue-8111-iframe-input/cypress/plugins/index.js @@ -0,0 +1,7 @@ +module.exports = (on) => { + on('before:browser:launch', (browser, launchOptions) => { + launchOptions.args.push('--auto-open-devtools-for-tabs') + + return launchOptions + }) +} diff --git a/packages/server/test/support/fixtures/projects/issue-8111-iframe-input/inner.html b/packages/server/test/support/fixtures/projects/issue-8111-iframe-input/inner.html new file mode 100644 index 000000000000..1394a7ef8fd2 --- /dev/null +++ b/packages/server/test/support/fixtures/projects/issue-8111-iframe-input/inner.html @@ -0,0 +1,4 @@ + + diff --git a/packages/server/test/support/fixtures/projects/issue-8111-iframe-input/outer.html b/packages/server/test/support/fixtures/projects/issue-8111-iframe-input/outer.html new file mode 100644 index 000000000000..7c17c2c77b97 --- /dev/null +++ b/packages/server/test/support/fixtures/projects/issue-8111-iframe-input/outer.html @@ -0,0 +1 @@ +