From 24e7689c1562a784c0ad1c63cc6ce561b98b2828 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 17 Mar 2025 12:01:25 -0400 Subject: [PATCH 01/13] chore: updating v8 snapshot cache (#31305) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> --- tooling/v8-snapshot/cache/linux/snapshot-meta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tooling/v8-snapshot/cache/linux/snapshot-meta.json b/tooling/v8-snapshot/cache/linux/snapshot-meta.json index fb81d7a7abc0..8fb44a456bd4 100644 --- a/tooling/v8-snapshot/cache/linux/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/linux/snapshot-meta.json @@ -4308,5 +4308,5 @@ "./tooling/v8-snapshot/cache/linux/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "b57a24164825fd631cca6f7216d6d7fbc323754f4d9e8ff1711834a26448a014" + "deferredHash": "2451ad189f6f86707fccfbe1ef60fab9d239c545c658d794930d4d4590984056" } \ No newline at end of file From be95849b3cb17a52cb308f9ec054cfa870f04755 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 17 Mar 2025 12:01:37 -0400 Subject: [PATCH 02/13] chore: updating v8 snapshot cache (#31306) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> --- tooling/v8-snapshot/cache/darwin/snapshot-meta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tooling/v8-snapshot/cache/darwin/snapshot-meta.json b/tooling/v8-snapshot/cache/darwin/snapshot-meta.json index bad0632bc53a..3aff3c6b7251 100644 --- a/tooling/v8-snapshot/cache/darwin/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/darwin/snapshot-meta.json @@ -4305,5 +4305,5 @@ "./tooling/v8-snapshot/cache/darwin/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "b57a24164825fd631cca6f7216d6d7fbc323754f4d9e8ff1711834a26448a014" + "deferredHash": "2451ad189f6f86707fccfbe1ef60fab9d239c545c658d794930d4d4590984056" } \ No newline at end of file From d3353d799ac9afae6962cb7213b5c8646ce96958 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 17 Mar 2025 12:32:24 -0400 Subject: [PATCH 03/13] chore: updating v8 snapshot cache (#31307) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> --- tooling/v8-snapshot/cache/win32/snapshot-meta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tooling/v8-snapshot/cache/win32/snapshot-meta.json b/tooling/v8-snapshot/cache/win32/snapshot-meta.json index 7383ffa4887c..3322b872ffc8 100644 --- a/tooling/v8-snapshot/cache/win32/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/win32/snapshot-meta.json @@ -4308,5 +4308,5 @@ "./tooling/v8-snapshot/cache/win32/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "74c76baf4c959330240a8be96360b45074a5915237c693e47b9939fd6eb3dfda" + "deferredHash": "46b5d52ea6ba75be3bd057c414fc9b69c83d5e638720081071ad6fe3ad03fb84" } \ No newline at end of file From 6fb101187e87f119a7be89bb0f56e5b7b5dd0816 Mon Sep 17 00:00:00 2001 From: Jennifer Shehane <jennifer@cypress.io> Date: Fri, 28 Mar 2025 15:39:41 -0400 Subject: [PATCH 04/13] breaking change commit BREAKING CHANGE: Cypress 15 breaking changes --- cli/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index e75bd10f5618..57f238d39106 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -1,4 +1,10 @@ <!-- See the ../guides/writing-the-cypress-changelog.md for details on writing the changelog. --> +## 15.0.0 + +_Released X/X/2025 (PENDING)_ + +**Breaking Changes:** + ## 14.2.2 _Released 4/8/2025 (PENDING)_ From 35b513195133c609a3f094312842150db236b44f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 09:15:56 -0400 Subject: [PATCH 05/13] chore: updating v8 snapshot cache (#31410) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> --- tooling/v8-snapshot/cache/linux/snapshot-meta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tooling/v8-snapshot/cache/linux/snapshot-meta.json b/tooling/v8-snapshot/cache/linux/snapshot-meta.json index 55bfbc2b7edb..5da8eece10d0 100644 --- a/tooling/v8-snapshot/cache/linux/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/linux/snapshot-meta.json @@ -4232,5 +4232,5 @@ "./tooling/v8-snapshot/cache/linux/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "a83ec07b936fc8a327f5d598ffadd5d272171e21824eabfe913646bf73ca4d43" + "deferredHash": "40a6f704a90094458c2c625cf736c94738ba46d08335929874eee29051455f00" } \ No newline at end of file From 4e44ccbc4161a42705aea54107cc99a66c582ce9 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 09:16:10 -0400 Subject: [PATCH 06/13] chore: updating v8 snapshot cache (#31411) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> --- tooling/v8-snapshot/cache/darwin/snapshot-meta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tooling/v8-snapshot/cache/darwin/snapshot-meta.json b/tooling/v8-snapshot/cache/darwin/snapshot-meta.json index c09de3d0c607..c61b4f6306fe 100644 --- a/tooling/v8-snapshot/cache/darwin/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/darwin/snapshot-meta.json @@ -4229,5 +4229,5 @@ "./tooling/v8-snapshot/cache/darwin/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "a83ec07b936fc8a327f5d598ffadd5d272171e21824eabfe913646bf73ca4d43" + "deferredHash": "40a6f704a90094458c2c625cf736c94738ba46d08335929874eee29051455f00" } \ No newline at end of file From fd6a923fa89534d9cd049e1db91bda030449315d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 31 Mar 2025 09:16:24 -0400 Subject: [PATCH 07/13] chore: updating v8 snapshot cache (#31412) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> --- tooling/v8-snapshot/cache/win32/snapshot-meta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tooling/v8-snapshot/cache/win32/snapshot-meta.json b/tooling/v8-snapshot/cache/win32/snapshot-meta.json index 658ac8ba3e6a..985b27017d49 100644 --- a/tooling/v8-snapshot/cache/win32/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/win32/snapshot-meta.json @@ -4232,5 +4232,5 @@ "./tooling/v8-snapshot/cache/win32/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "8314db54df0460f6d49850716cab3431b20fcf5dc94a69f6f5a6d87e071d0865" + "deferredHash": "c99978c5469ebdc6acd39c011a582e126351fe2778b3bb06b895792393b4f344" } \ No newline at end of file From 1f81595fdbfea0609f52405dbded6468aec4e3e8 Mon Sep 17 00:00:00 2001 From: Jennifer Shehane <jennifer@cypress.io> Date: Tue, 1 Apr 2025 10:35:51 -0400 Subject: [PATCH 08/13] breaking: Remove support for Node.js 18 & 23 (#31409) * remove support for Node.js 18 & 23 BREAKING CHANGE: remove support for Node.js 18 & 23 * remove binary tests for Node 18 * Add made up date * Update cli/package.json Co-authored-by: Mike McCready <66998419+MikeMcC399@users.noreply.github.com> --------- Co-authored-by: Mike McCready <66998419+MikeMcC399@users.noreply.github.com> --- cli/CHANGELOG.md | 4 +++- cli/package.json | 2 +- system-tests/test-binary/node_versions_spec.ts | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 57f238d39106..15b64c4a2238 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -1,10 +1,12 @@ <!-- See the ../guides/writing-the-cypress-changelog.md for details on writing the changelog. --> ## 15.0.0 -_Released X/X/2025 (PENDING)_ +_Released 7/1/2025 (PENDING)_ **Breaking Changes:** +- Removed support for Node.js 18 and Node.js 23. Addresses [#31302](https://github.com/cypress-io/cypress/issues/31302). + ## 14.2.2 _Released 4/8/2025 (PENDING)_ diff --git a/cli/package.json b/cli/package.json index 61b6583ff7c4..c7d15d2791cc 100644 --- a/cli/package.json +++ b/cli/package.json @@ -120,7 +120,7 @@ "cypress": "bin/cypress" }, "engines": { - "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + "node": "^20.0.0 || ^22.0.0" }, "types": "types", "exports": { diff --git a/system-tests/test-binary/node_versions_spec.ts b/system-tests/test-binary/node_versions_spec.ts index 90bf2f46eb7d..07bdd4f9f937 100644 --- a/system-tests/test-binary/node_versions_spec.ts +++ b/system-tests/test-binary/node_versions_spec.ts @@ -26,23 +26,23 @@ function smokeTestDockerImage (dockerImage: string) { describe('binary node versions', () => { [ - 'cypress/base:18.16.1', 'cypress/base:20.12.2', 'cypress/base:20.18.0', 'cypress/base:22.0.0', 'cypress/base:22.7.0', 'cypress/base:22.12.0', + 'cypress/base:22.14.0', ].forEach(smokeTestDockerImage) }) describe('type: module', () => { [ - 'cypress/base:18.16.1', 'cypress/base:20.12.2', 'cypress/base:20.18.0', 'cypress/base:22.0.0', 'cypress/base:22.7.0', 'cypress/base:22.12.0', + 'cypress/base:22.14.0', ].forEach((dockerImage) => { systemTests.it(`can run in ${dockerImage}`, { withBinary: true, From 707f8ee8777eee75e9f51a245e3c762980ac1cef Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 10:54:23 -0400 Subject: [PATCH 09/13] chore: updating v8 snapshot cache (#31420) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> --- tooling/v8-snapshot/cache/linux/snapshot-meta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tooling/v8-snapshot/cache/linux/snapshot-meta.json b/tooling/v8-snapshot/cache/linux/snapshot-meta.json index 5da8eece10d0..55bfbc2b7edb 100644 --- a/tooling/v8-snapshot/cache/linux/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/linux/snapshot-meta.json @@ -4232,5 +4232,5 @@ "./tooling/v8-snapshot/cache/linux/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "40a6f704a90094458c2c625cf736c94738ba46d08335929874eee29051455f00" + "deferredHash": "a83ec07b936fc8a327f5d598ffadd5d272171e21824eabfe913646bf73ca4d43" } \ No newline at end of file From f23f77981ee8665769ff93b95f3f2d09bceb75a8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 10:54:41 -0400 Subject: [PATCH 10/13] chore: updating v8 snapshot cache (#31421) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> --- tooling/v8-snapshot/cache/darwin/snapshot-meta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tooling/v8-snapshot/cache/darwin/snapshot-meta.json b/tooling/v8-snapshot/cache/darwin/snapshot-meta.json index c61b4f6306fe..c09de3d0c607 100644 --- a/tooling/v8-snapshot/cache/darwin/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/darwin/snapshot-meta.json @@ -4229,5 +4229,5 @@ "./tooling/v8-snapshot/cache/darwin/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "40a6f704a90094458c2c625cf736c94738ba46d08335929874eee29051455f00" + "deferredHash": "a83ec07b936fc8a327f5d598ffadd5d272171e21824eabfe913646bf73ca4d43" } \ No newline at end of file From 534324fe232bedf035673c452dd2770f9d6b3d21 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 1 Apr 2025 11:17:04 -0400 Subject: [PATCH 11/13] chore: updating v8 snapshot cache (#31422) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> --- tooling/v8-snapshot/cache/win32/snapshot-meta.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tooling/v8-snapshot/cache/win32/snapshot-meta.json b/tooling/v8-snapshot/cache/win32/snapshot-meta.json index 985b27017d49..658ac8ba3e6a 100644 --- a/tooling/v8-snapshot/cache/win32/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/win32/snapshot-meta.json @@ -4232,5 +4232,5 @@ "./tooling/v8-snapshot/cache/win32/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "c99978c5469ebdc6acd39c011a582e126351fe2778b3bb06b895792393b4f344" + "deferredHash": "8314db54df0460f6d49850716cab3431b20fcf5dc94a69f6f5a6d87e071d0865" } \ No newline at end of file From 25f0fd0a110959f5ce9ced78dad4f41e8919671d Mon Sep 17 00:00:00 2001 From: Bill Glesias <bglesias@gmail.com> Date: Thu, 3 Apr 2025 13:42:04 -0400 Subject: [PATCH 12/13] breaking: remove CDP from firefox with Cypress 15 (#31200) * chore: updating v8 snapshot cache (#31422) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> * breaking: remove CDP from firefox with Cypress 15 [run ci] * chore: code review updates --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> --- .circleci/workflows.yml | 31 -- cli/CHANGELOG.md | 3 +- packages/errors/src/errors.ts | 3 - .../test/unit/visualSnapshotErrors_spec.ts | 5 - packages/extension/app/v2/background.js | 48 --- .../test/integration/v2/background_spec.js | 114 ------- packages/graphql/schemas/schema.graphql | 1 - packages/launcher/lib/known-browsers.ts | 24 +- packages/launcher/test/unit/browsers_spec.ts | 19 ++ packages/launcher/test/unit/linux_spec.ts | 6 +- packages/server/lib/browsers/firefox-util.ts | 81 +---- packages/server/lib/browsers/firefox.ts | 115 +------ packages/server/lib/modes/run.ts | 21 +- packages/server/lib/socket-base.ts | 4 +- .../server/test/unit/browsers/firefox_spec.ts | 315 ++++-------------- .../cdp_deprecated_firefox_spec.ts.js | 55 --- .../test/cdp_deprecated_firefox_spec.ts | 18 - 17 files changed, 136 insertions(+), 727 deletions(-) delete mode 100644 system-tests/__snapshots__/cdp_deprecated_firefox_spec.ts.js delete mode 100644 system-tests/test/cdp_deprecated_firefox_spec.ts diff --git a/.circleci/workflows.yml b/.circleci/workflows.yml index 7dc5af95fa3b..ac41c6cffdca 100644 --- a/.circleci/workflows.yml +++ b/.circleci/workflows.yml @@ -656,11 +656,6 @@ commands: description: run subset of tests with injectDocumentDomain config enabled type: boolean default: false - is-firefox-cdp: - description: whether or not the group should be associated to the firefox CDP - run or not. This is determined by the browser version. - type: boolean - default: false steps: - restore_cached_workspace @@ -701,9 +696,6 @@ commands: if << parameters.inject-document-domain >> ; then YARN_CMD="cypress:run:inject-document-domain" PARALLEL="--parallel --group 5x-driver-inject-document-domain-<<parameters.browser>>" - elif << parameters.is-firefox-cdp >> ; then - YARN_CMD="cypress:run" - PARALLEL="--parallel --group 5x-driver-cdp-<<parameters.browser>>" else YARN_CMD="cypress:run" PARALLEL="--parallel --group 5x-driver-<<parameters.browser>>" @@ -2136,18 +2128,6 @@ jobs: - run-driver-integration-tests: browser: firefox - # Runs the driver tests using firefox 134, which does NOT use WebDriver BiDi - # This is to test and make sure there aren't regressions with the old CDP driver - driver-integration-tests-firefox-cdp: - <<: *defaults - resource_class: medium+ - parallelism: 5 - steps: - - run-driver-integration-tests: - browser: firefox - firefox-version: "134.0.2" - is-firefox-cdp: true - driver-integration-tests-electron: <<: *defaults parallelism: 5 @@ -2888,7 +2868,6 @@ linux-x64-workflow: &linux-x64-workflow - run-webpack-dev-server-integration-tests - run-vite-dev-server-integration-tests - driver-integration-tests-firefox - - driver-integration-tests-firefox-cdp - driver-integration-tests-chrome - driver-integration-tests-chrome-inject-document-domain - driver-integration-tests-chrome-beta-inject-document-domain @@ -2964,10 +2943,6 @@ linux-x64-workflow: &linux-x64-workflow context: test-runner:cypress-record-key requires: - build - - driver-integration-tests-firefox-cdp: - context: test-runner:cypress-record-key - requires: - - build - driver-integration-tests-electron: context: test-runner:cypress-record-key requires: @@ -3110,7 +3085,6 @@ linux-x64-workflow: &linux-x64-workflow - linux-lint - percy-finalize - driver-integration-tests-firefox - - driver-integration-tests-firefox-cdp - driver-integration-tests-chrome - driver-integration-tests-chrome-beta - driver-integration-tests-chrome-inject-document-domain @@ -3366,10 +3340,6 @@ linux-x64-contributor-workflow: &linux-x64-contributor-workflow context: test-runner:cypress-record-key requires: - contributor-pr - - driver-integration-tests-firefox-cdp: - context: test-runner:cypress-record-key - requires: - - contributor-pr - driver-integration-tests-electron: context: test-runner:cypress-record-key requires: @@ -3511,7 +3481,6 @@ linux-x64-contributor-workflow: &linux-x64-contributor-workflow - linux-lint - percy-finalize - driver-integration-tests-firefox - - driver-integration-tests-firefox-cdp - driver-integration-tests-chrome - driver-integration-tests-chrome-beta - driver-integration-tests-electron diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 3816f3e9e75e..403c189a195a 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -1,11 +1,12 @@ <!-- See the ../guides/writing-the-cypress-changelog.md for details on writing the changelog. --> ## 15.0.0 -_Released 7/1/2025 (PENDING)_ +_Released 07/01/2025 (PENDING)_ **Breaking Changes:** - Removed support for Node.js 18 and Node.js 23. Addresses [#31302](https://github.com/cypress-io/cypress/issues/31302). +- Removed support for [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol) with the [firefox](https://www.mozilla.org/) browser. Addresses [#31189](https://github.com/cypress-io/cypress/issues/31189). ## 14.2.2 diff --git a/packages/errors/src/errors.ts b/packages/errors/src/errors.ts index 0bad56e294a1..cb178f75b71e 100644 --- a/packages/errors/src/errors.ts +++ b/packages/errors/src/errors.ts @@ -1193,9 +1193,6 @@ export const AllCypressErrors = { CDP_RETRYING_CONNECTION: (attempt: string | number, browserName: string, connectRetryThreshold: number) => { return errTemplate`Still waiting to connect to ${fmt.off(_.capitalize(browserName))}, retrying in 1 second ${fmt.meta(`(attempt ${attempt}/${connectRetryThreshold})`)}` }, - CDP_FIREFOX_DEPRECATED: () => { - return errTemplate`Since Firefox 129, Chrome DevTools Protocol (CDP) has been deprecated in Firefox. In Firefox 135 and above, Cypress defaults to automating the Firefox browser with WebDriver BiDi. Cypress will no longer support CDP within Firefox in the future and is planned for removal in Cypress 15.` - }, BROWSER_PROCESS_CLOSED_UNEXPECTEDLY: (browserName: string) => { return errTemplate`\ We detected that the ${fmt.highlight(browserName)} browser process closed unexpectedly. diff --git a/packages/errors/test/unit/visualSnapshotErrors_spec.ts b/packages/errors/test/unit/visualSnapshotErrors_spec.ts index 5f9512adf1d7..aa77d2a70322 100644 --- a/packages/errors/test/unit/visualSnapshotErrors_spec.ts +++ b/packages/errors/test/unit/visualSnapshotErrors_spec.ts @@ -1112,11 +1112,6 @@ describe('visual error templates', () => { default: [1, 'chrome', 62], } }, - CDP_FIREFOX_DEPRECATED: () => { - return { - default: [], - } - }, BROWSER_PROCESS_CLOSED_UNEXPECTEDLY: () => { return { default: ['chrome'], diff --git a/packages/extension/app/v2/background.js b/packages/extension/app/v2/background.js index 7fd063288933..5a3bb0ca17c3 100644 --- a/packages/extension/app/v2/background.js +++ b/packages/extension/app/v2/background.js @@ -31,23 +31,6 @@ const checkIfFirefox = async () => { return name === 'Firefox' } -// this check only applies to firefox versioning! -const isBiDiEnabled = async (config) => { - if (!browser || !get(browser, 'runtime.getBrowserInfo') || config.IS_CDP_FORCED_FOR_FIREFOX) { - return false - } - - const { version } = await browser.runtime.getBrowserInfo() - - if (version) { - const [majorVersion] = version.split('.').map(Number) - - return majorVersion >= 135 - } - - return false -} - const connect = function (host, path, extraOpts) { const listenToCookieChanges = once(() => { return browser.cookies.onChanged.addListener((info) => { @@ -84,30 +67,6 @@ const connect = function (host, path, extraOpts) { }) }) - const listenToOnBeforeHeaders = once(() => { - // adds a header to the request to mark it as a request for the AUT frame - // itself, so the proxy can utilize that for injection purposes - browser.webRequest.onBeforeSendHeaders.addListener((details) => { - if ( - // parentFrameId: 0 means the parent is the top-level, so if it isn't - // 0, it's nested inside the AUT and can't be the AUT itself - details.parentFrameId !== 0 - // is the spec frame, not the AUT - || details.url.includes('__cypress') - ) return - - return { - requestHeaders: [ - ...details.requestHeaders, - { - name: 'X-Cypress-Is-AUT-Frame', - value: 'true', - }, - ], - } - }, { urls: ['<all_urls>'], types: ['sub_frame'] }, ['blocking', 'requestHeaders']) - }) - const fail = (id, err) => { return ws.emit('automation:response', id, { __error: err.message, @@ -167,13 +126,6 @@ const connect = function (host, path, extraOpts) { if (isFirefox) { // Non-Firefox browsers use CDP for this instead listenToDownloads() - // if BiDi is enabled, BiDi will handle the network interception. - // Otherwise, CDP does not support it for Firefox and we need to listen for it here. - const isBiDiTurnedOn = await isBiDiEnabled(config) - - if (!isBiDiTurnedOn) { - listenToOnBeforeHeaders() - } } }) diff --git a/packages/extension/test/integration/v2/background_spec.js b/packages/extension/test/integration/v2/background_spec.js index 11c1fc7ea595..1cd0e3591a3a 100644 --- a/packages/extension/test/integration/v2/background_spec.js +++ b/packages/extension/test/integration/v2/background_spec.js @@ -293,120 +293,6 @@ describe('app/background', () => { }) }) - context('add header to aut iframe requests', () => { - beforeEach(() => { - browser.runtime.getBrowserInfo = sinon.stub().resolves({ name: 'Firefox', version: '135.0.1' }) - }) - - it('allows for CDP to be used as an escape hatch if BiDi would otherwise be enabled', async function () { - sinon.stub(browser.webRequest.onBeforeSendHeaders, 'addListener') - - await this.connect({ - IS_CDP_FORCED_FOR_FIREFOX: true, - }) - - expect(browser.webRequest.onBeforeSendHeaders.addListener).to.be.called - }) - - context('BiDi enabled', () => { - it('does not attach onBeforeSendHeaders listener if BiDi is enabled', async function () { - sinon.stub(browser.webRequest.onBeforeSendHeaders, 'addListener') - - await this.connect() - - expect(browser.webRequest.onBeforeSendHeaders.addListener).not.to.be.called - }) - }) - - context('CDP enabled', () => { - beforeEach(() => { - browser.runtime.getBrowserInfo = sinon.stub().resolves({ name: 'Firefox', version: '134' }) - }) - - it('does not add header if it is the top frame', async function () { - const details = { - parentFrameId: -1, - } - - sinon.stub(browser.webRequest.onBeforeSendHeaders, 'addListener') - - await this.connect() - - const result = browser.webRequest.onBeforeSendHeaders.addListener.lastCall.args[0](details) - - expect(result).to.be.undefined - }) - - it('does not add header if it is a nested frame', async function () { - const details = { - parentFrameId: 12345, - } - - sinon.stub(browser.webRequest.onBeforeSendHeaders, 'addListener') - - await this.connect() - - const result = browser.webRequest.onBeforeSendHeaders.addListener.lastCall.args[0](details) - - expect(result).to.be.undefined - }) - - it('does not add header if it is a spec frame request', async function () { - const details = { - parentFrameId: 0, - type: 'sub_frame', - url: '/__cypress/integration/spec.js', - } - - sinon.stub(browser.webRequest.onBeforeSendHeaders, 'addListener') - - await this.connect() - const result = browser.webRequest.onBeforeSendHeaders.addListener.lastCall.args[0](details) - - expect(result).to.be.undefined - }) - - it('appends X-Cypress-Is-AUT-Frame header to AUT iframe request', async function () { - const details = { - parentFrameId: 0, - type: 'sub_frame', - url: 'http://localhost:3000/index.html', - requestHeaders: [ - { name: 'X-Foo', value: 'Bar' }, - ], - } - - sinon.stub(browser.webRequest.onBeforeSendHeaders, 'addListener') - - await this.connect() - const result = browser.webRequest.onBeforeSendHeaders.addListener.lastCall.args[0](details) - - expect(result).to.deep.equal({ - requestHeaders: [ - { - name: 'X-Foo', - value: 'Bar', - }, - { - name: 'X-Cypress-Is-AUT-Frame', - value: 'true', - }, - ], - }) - }) - - it('does not add before-headers listener if in non-Firefox browser', async function () { - browser.runtime.getBrowserInfo = undefined - - const onBeforeSendHeaders = sinon.stub(browser.webRequest.onBeforeSendHeaders, 'addListener') - - await this.connect() - - expect(onBeforeSendHeaders).not.to.be.called - }) - }) - }) - context('.getAll', () => { it('resolves with specific cookie properties', () => { sinon.stub(browser.cookies, 'getAll').resolves([ diff --git a/packages/graphql/schemas/schema.graphql b/packages/graphql/schemas/schema.graphql index 5480f28267a6..45cc21d69e33 100644 --- a/packages/graphql/schemas/schema.graphql +++ b/packages/graphql/schemas/schema.graphql @@ -1129,7 +1129,6 @@ enum ErrorTypeEnum { CANNOT_TRASH_ASSETS CDP_COULD_NOT_CONNECT CDP_COULD_NOT_RECONNECT - CDP_FIREFOX_DEPRECATED CDP_RETRYING_CONNECTION CDP_VERSION_TOO_OLD CHROME_WEB_SECURITY_NOT_SUPPORTED diff --git a/packages/launcher/lib/known-browsers.ts b/packages/launcher/lib/known-browsers.ts index 0d1fa044fa23..ea6b9fca19a7 100644 --- a/packages/launcher/lib/known-browsers.ts +++ b/packages/launcher/lib/known-browsers.ts @@ -1,5 +1,24 @@ import type { Browser, BrowserValidatorResult, FoundBrowser } from '@packages/types' +const firefoxValidatorFn = (browser: FoundBrowser, platform: NodeJS.Platform): BrowserValidatorResult => { + try { + if (browser.majorVersion) { + const majorVersion = Number(browser.majorVersion) + + if (majorVersion < 135) { + return { + isSupported: false, + warningMessage: `Cypress does not support running ${browser.displayName} version ${browser.majorVersion} due to lack of WebDriver BiDi support. To use ${browser.displayName} with Cypress, install version 135 or newer.`, + } + } + } + } catch (e) { /* empty */ } + + return { + isSupported: true, + } +} + /** list of the browsers we can detect and use by default */ export const knownBrowsers: Browser[] = [ { @@ -62,9 +81,10 @@ export const knownBrowsers: Browser[] = [ family: 'firefox', channel: 'stable', displayName: 'Firefox', - // Mozilla Firefox 70.0.1 + // Mozilla Firefox 135.0.1 versionRegex: /^Mozilla Firefox ([^\sab]+)$/m, binary: 'firefox', + validator: firefoxValidatorFn, }, { name: 'firefox', @@ -75,6 +95,7 @@ export const knownBrowsers: Browser[] = [ versionRegex: /^Mozilla Firefox (\S+b\S*)$/m, // ubuntu PPAs install it as firefox binary: ['firefox-developer-edition', 'firefox'], + validator: firefoxValidatorFn, }, { name: 'firefox', @@ -85,6 +106,7 @@ export const knownBrowsers: Browser[] = [ versionRegex: /^Mozilla Firefox (\S+a\S*)$/m, // ubuntu PPAs install it as firefox-trunk binary: ['firefox-nightly', 'firefox-trunk'], + validator: firefoxValidatorFn, }, { name: 'edge', diff --git a/packages/launcher/test/unit/browsers_spec.ts b/packages/launcher/test/unit/browsers_spec.ts index 79ec5514b3c3..19f8f9ba808d 100644 --- a/packages/launcher/test/unit/browsers_spec.ts +++ b/packages/launcher/test/unit/browsers_spec.ts @@ -71,6 +71,25 @@ describe('browsers', () => { expect(result.isSupported).to.be.true expect(result.warningMessage).to.be.undefined }) + + describe('firefox validation', () => { + const FIREFOX_KNOWN_BROWSER_CHANNELS = knownBrowsers.filter((browser) => { + return browser.family === 'firefox' + }) + + FIREFOX_KNOWN_BROWSER_CHANNELS.forEach((browser) => { + it(`${browser.channel}: fails validation when Firefox major version is below 135`, () => { + // @ts-expect-error + const result = browser.validator({ + majorVersion: '134', + displayName: 'Firefox', + }) + + expect(result.isSupported).to.be.false + expect(result.warningMessage).to.equal('Cypress does not support running Firefox version 134 due to lack of WebDriver BiDi support. To use Firefox with Cypress, install version 135 or newer.') + }) + }) + }) }) }) }) diff --git a/packages/launcher/test/unit/linux_spec.ts b/packages/launcher/test/unit/linux_spec.ts index 1f030b2e2b8a..429894fc9d69 100644 --- a/packages/launcher/test/unit/linux_spec.ts +++ b/packages/launcher/test/unit/linux_spec.ts @@ -85,15 +85,15 @@ describe('linux browser detection', () => { name: 'firefox', family: 'firefox', displayName: 'Firefox', - majorVersion: '99', + majorVersion: '135', path: 'firefox', profilePath: '/home/foo/snap/firefox/current', - version: '99.2.3', + version: '135.0.1', } beforeEach(() => { execa.withArgs('firefox', ['--version']) - .resolves({ stdout: 'Mozilla Firefox 99.2.3' }) + .resolves({ stdout: 'Mozilla Firefox 135.0.1' }) sinon.stub(os, 'homedir').returns('/home/foo') }) diff --git a/packages/server/lib/browsers/firefox-util.ts b/packages/server/lib/browsers/firefox-util.ts index 620260224cec..f3a3dcf6842f 100644 --- a/packages/server/lib/browsers/firefox-util.ts +++ b/packages/server/lib/browsers/firefox-util.ts @@ -1,10 +1,7 @@ import Debug from 'debug' -import { CdpAutomation } from './cdp_automation' import { BidiAutomation } from './bidi_automation' -import { BrowserCriClient } from './browser-cri-client' import type { Client as WebDriverClient } from 'webdriver' import type { Automation } from '../automation' -import type { CypressError } from '@packages/errors' const debug = Debug('cypress:server:browsers:firefox-util') @@ -27,36 +24,6 @@ async function connectToNewSpecBiDi (options, automation: Automation, browserBiD }) } -async function connectToNewSpecCDP (options, automation: Automation, browserCriClient: BrowserCriClient) { - debug('firefox: reconnecting to blank tab') - - // Firefox keeps a blank tab open in versions of Firefox 123 and lower when the last tab is closed. - // For versions 124 and above, a new tab is not created, so @packages/extension creates one for us. - // Since the tab is always available on our behalf, - // we can connect to it here and navigate it to about:blank to set it up for CDP connection - const handles = await webdriverClient.getWindowHandles() - - await webdriverClient.switchToWindow(handles[0]) - - await webdriverClient.navigateTo('about:blank') - - debug('firefox: reconnecting CDP') - - if (browserCriClient) { - await browserCriClient.currentlyAttachedTarget?.close().catch(() => {}) - // Strictly speaking this shouldn't ever happen in firefox, but to future proof adding it in case. - await browserCriClient.currentlyAttachedProtocolTarget?.close().catch(() => {}) - const pageCriClient = await browserCriClient.attachToTargetUrl('about:blank') - - await CdpAutomation.create(pageCriClient.send, pageCriClient.on, pageCriClient.off, browserCriClient.resetBrowserTargets, automation) - } - - await options.onInitializeNewBrowserTab() - - debug(`firefox: navigating to ${options.url}`) - await webdriverClient.navigateTo(options.url) -} - async function setupBiDi (webdriverClient: WebDriverClient, automation: Automation) { // webdriver needs to subscribe to the correct BiDi events or else the events we are expecting to stream in will not be sent await webdriverClient.sessionSubscribe({ events: BidiAutomation.BIDI_EVENTS }) @@ -66,63 +33,39 @@ async function setupBiDi (webdriverClient: WebDriverClient, automation: Automati return biDiClient } -async function setupCDP (remotePort: number, automation: Automation, onError?: (err: Error) => void): Promise<BrowserCriClient> { - const browserCriClient = await BrowserCriClient.create({ hosts: ['127.0.0.1', '::1'], port: remotePort, browserName: 'Firefox', onAsynchronousError: onError as (err: CypressError) => void, onServiceWorkerClientEvent: automation.onServiceWorkerClientEvent }) - const pageCriClient = await browserCriClient.attachToTargetUrl('about:blank') - - await CdpAutomation.create(pageCriClient.send, pageCriClient.on, pageCriClient.off, browserCriClient.resetBrowserTargets, automation) - - return browserCriClient -} - export default { async setup ({ automation, - onError, url, - remotePort, webdriverClient: wdInstance, - useWebDriverBiDi, }: { automation: Automation - onError?: (err: Error) => void url: string - remotePort: number | undefined webdriverClient: WebDriverClient - useWebDriverBiDi: boolean - }): Promise<BrowserCriClient | BidiAutomation> { + }): Promise<BidiAutomation> { // set the WebDriver classic instance instantiated from geckodriver webdriverClient = wdInstance - let client: BrowserCriClient | BidiAutomation + let client: BidiAutomation - if (useWebDriverBiDi) { - client = await setupBiDi(webdriverClient, automation) - // use the BiDi commands to visit the url as opposed to classic webdriver - const { contexts } = await webdriverClient.browsingContextGetTree({}) + client = await setupBiDi(webdriverClient, automation) + // use the BiDi commands to visit the url as opposed to classic webdriver + const { contexts } = await webdriverClient.browsingContextGetTree({}) - // at this point there should only be one context: the top level context. - // we need to set this to bind our AUT intercepts correctly. Hopefully we can move this in the future on a more sure implementation - client.setTopLevelContextId(contexts[0].context) + // at this point there should only be one context: the top level context. + // we need to set this to bind our AUT intercepts correctly. Hopefully we can move this in the future on a more sure implementation + client.setTopLevelContextId(contexts[0].context) - await webdriverClient.browsingContextNavigate({ - context: contexts[0].context, - url, - }) - } else { - client = await setupCDP(remotePort as number, automation, onError) - // uses webdriver classic to navigate - await webdriverClient.navigateTo(url) - } + await webdriverClient.browsingContextNavigate({ + context: contexts[0].context, + url, + }) return client }, connectToNewSpecBiDi, - connectToNewSpecCDP, - setupBiDi, - setupCDP, } diff --git a/packages/server/lib/browsers/firefox.ts b/packages/server/lib/browsers/firefox.ts index abc57a9bbf76..aa5fe8ba8181 100644 --- a/packages/server/lib/browsers/firefox.ts +++ b/packages/server/lib/browsers/firefox.ts @@ -14,28 +14,15 @@ import utils from './utils' import type { Browser, BrowserInstance, GracefulShutdownOptions } from './types' import os from 'os' import mimeDb from 'mime-db' -import { BrowserCriClient } from './browser-cri-client' import type { BidiAutomation } from './bidi_automation' import type { Automation } from '../automation' import { getCtx } from '@packages/data-context' -import { getError, SerializedError, CypressError } from '@packages/errors' +import { getError, CypressError } from '@packages/errors' import type { BrowserLaunchOpts, BrowserNewTabOpts, RunModeVideoApi } from '@packages/types' import type { RemoteConfig } from 'webdriver' import type { GeckodriverParameters } from 'geckodriver' import { WebDriver } from './webdriver' -export class CDPFailedToStartFirefox extends Error { - private static readonly ERROR_NAME = 'CDPFailedToStartFirefox' - constructor (message) { - super(message) - this.name = CDPFailedToStartFirefox.ERROR_NAME - } - - public static isCDPFailedToStartFirefoxError (error?: SerializedError): error is CDPFailedToStartFirefox { - return error?.name === CDPFailedToStartFirefox.ERROR_NAME - } -} - const debug = Debug('cypress:server:browsers:firefox') const debugVerbose = Debug('cypress-verbose:server:browsers:firefox') @@ -335,20 +322,18 @@ const defaultPreferences = { 'browser.helperApps.neverAsk.saveToDisk': downloadMimeTypes, } -// CDP is deprecated in Firefox 129 and up. +// CDP was deprecated in Firefox 129 and up and was removed in Firefox 141. // To enable BiDi (without CDP), we need to set // remote.active-protocol=1 -// In order to enable CDP (without BiDi), we need to set +// Cypress no longer supports CDP within Firefox. However, it can be enabled if needed (but only on Firefox 141 and lower) by setting // remote.active-protocol=2 // both can be enabled via // remote.active-protocol=3 // @see https://fxdx.dev/deprecating-cdp-support-in-firefox-embracing-the-future-with-webdriver-bidi/ +// @see https://fxdx.dev/webdriver-bidi-becomes-the-default-for-cypress-in-firefox/ // @see https://github.com/cypress-io/cypress/issues/29713 const ACTIVE_PROTOCOLS = Object.freeze({ BIDI: 1, - CDP: 2, - // this key isn't actively used but checked in here if we need to turn it on for internal debugging - CDP_AND_BIDI: 3, }) const FIREFOX_HEADED_USERCSS = `\ @@ -387,7 +372,6 @@ toolbox { } ` -let browserCriClient: BrowserCriClient | undefined let browserBidiClient: BidiAutomation | undefined /** @@ -396,12 +380,6 @@ let browserBidiClient: BidiAutomation | undefined export function clearInstanceState (options: GracefulShutdownOptions = {}) { debug('clearing instance state') - if (browserCriClient) { - debug('closing remote interface client') - browserCriClient.close(options.gracefulShutdown).catch(() => {}) - browserCriClient = undefined - } - if (browserBidiClient) { debug('unbinding bidi client events') browserBidiClient.close() @@ -409,21 +387,8 @@ export function clearInstanceState (options: GracefulShutdownOptions = {}) { } } -function shouldUseBiDi (browser: Browser): boolean { - try { - // Gating on firefox version 135 to turn on BiDi as this is when all of our internal Cypress tests were able to pass. - return (browser.family === 'firefox' && !process.env.FORCE_FIREFOX_CDP && Number(browser.majorVersion) >= 135) - } catch (err: unknown) { - return false - } -} - export async function connectToNewSpec (browser: Browser, options: BrowserNewTabOpts, automation: Automation) { - if (shouldUseBiDi(browser)) { - await firefoxUtil.connectToNewSpecBiDi(options, automation, browserBidiClient!) - } else { - await firefoxUtil.connectToNewSpecCDP(options, automation, browserCriClient!) - } + await firefoxUtil.connectToNewSpecBiDi(options, automation, browserBidiClient!) } export function connectToExisting () { @@ -445,12 +410,6 @@ async function recordVideo (videoApi: RunModeVideoApi) { } export async function open (browser: Browser, url: string, options: BrowserLaunchOpts, automation: Automation): Promise<BrowserInstance> { - const USE_WEBDRIVER_BIDI = shouldUseBiDi(browser) - - if (!USE_WEBDRIVER_BIDI) { - errors.warning('CDP_FIREFOX_DEPRECATED') - } - const defaultLaunchOptions = utils.getDefaultLaunchOptions({ extensions: [] as string[], preferences: _.extend({}, defaultPreferences), @@ -463,7 +422,7 @@ export async function open (browser: Browser, url: string, options: BrowserLaunc ], }) - defaultLaunchOptions.preferences['remote.active-protocols'] = USE_WEBDRIVER_BIDI ? ACTIVE_PROTOCOLS.BIDI : ACTIVE_PROTOCOLS.CDP + defaultLaunchOptions.preferences['remote.active-protocols'] = ACTIVE_PROTOCOLS.BIDI if (browser.isHeadless) { defaultLaunchOptions.args.push('-headless') @@ -558,26 +517,6 @@ export async function open (browser: Browser, url: string, options: BrowserLaunc debug('firefox directories %o', { path: profile.path(), cacheDir, extensionDest }) - const xulStorePath = path.join(profile.path(), 'xulstore.json') - - // if user has set custom window.sizemode pref or it's the first time launching on this profile, write to xulStore. - if (!await fs.pathExists(xulStorePath)) { - // this causes the browser to launch maximized, which chrome does by default - // otherwise an arbitrary size will be picked for the window size - - // this used to not have an effect after first launch in 'interactive' mode. - // However, since Cypress 13.15.1, - // geckodriver creates unique profile names that copy over the xulstore.json to the used profile. - // The copy is ultimately updated on the unique profile name and is destroyed when the browser is torn down, - // so the values are not persisted. Cypress could hypothetically determine the profile is in use, copy the xulstore.json - // out of the profile and try to persist it in the next created profile, but this method is likely error prone as it requires - // moving/copying of files while creation/deletion of profiles occur, plus the ability to correlate the correct profile to the current run, - // which there are not guarantees we can deterministically do this in open mode. - const sizemode = 'maximized' - - await fs.writeJSON(xulStorePath, { 'chrome://browser/content/browser.xhtml': { 'main-window': { 'width': 1280, 'height': 1024, sizemode } } }) - } - launchOptions.preferences['browser.cache.disk.parent_directory'] = cacheDir const userCSSPath = path.join(profileDir, 'chrome') @@ -669,7 +608,7 @@ export async function open (browser: Browser, url: string, options: BrowserLaunc alwaysMatch: { browserName: 'firefox', acceptInsecureCerts: true, - webSocketUrl: USE_WEBDRIVER_BIDI, + webSocketUrl: true, // @see https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions 'moz:firefoxOptions': { profile: base64EncodedProfile, @@ -677,9 +616,6 @@ export async function open (browser: Browser, url: string, options: BrowserLaunc args: launchOptions.args, prefs: launchOptions.preferences, }, - // @see https://firefox-source-docs.mozilla.org/testing/geckodriver/Capabilities.html#moz-debuggeraddress - // we specify the debugger address option for Webdriver, which will return us the CDP address when the capability is returned. - 'moz:debuggerAddress': !USE_WEBDRIVER_BIDI, // @see https://webdriver.io/docs/capabilities/#wdiogeckodriveroptions // webdriver starts geckodriver with the correct options on behalf of Cypress 'wdio:geckodriverOptions': geckoDriverOptions, @@ -749,26 +685,12 @@ export async function open (browser: Browser, url: string, options: BrowserLaunc return browserReturnStatus || driverReturnStatus } - let cdpPort: number | undefined - - if (!USE_WEBDRIVER_BIDI) { - // In some cases, the webdriver session will NOT return the moz:debuggerAddress capability even though - // we set it to true in the capabilities. This is out of our control, so when this happens, we fail the browser - // and gracefully terminate the related processes and attempt to relaunch the browser in the hopes we get a - // CDP address. @see https://github.com/cypress-io/cypress/issues/30352#issuecomment-2405701867 for more details. - if (!webdriverClient.capabilities['moz:debuggerAddress']) { - debugVerbose(`firefox failed to spawn with CDP connection. Failing current instance and retrying`) - // since this fails before the instance is created, we need to kill the processes here or else they will stay open - browserInstanceWrapper.kill() - throw new CDPFailedToStartFirefox(`webdriver session failed to start CDP even though "moz:debuggerAddress" was provided. Please try to relaunch the browser`) - } - - cdpPort = parseInt(new URL(`ws://${webdriverClient.capabilities['moz:debuggerAddress']}`).port) - - debug(`CDP running on port ${cdpPort}`) - - // makes it so get getRemoteDebuggingPort() is calculated correctly - process.env.CYPRESS_REMOTE_DEBUGGING_PORT = cdpPort.toString() + // maximize the window if running headful and no width or height args are provided. + // NOTE: We used to do this with xulstore.json, but this is no longer possible with geckodriver + // as firefox will create the profile under the profile root that we cannot control and we cannot consistently provide + // a base 64 encoded profile. + if (!browser.isHeadless && (!launchOptions.args.includes('-width') || !launchOptions.args.includes('-height'))) { + await webdriverClient.maximizeWindow() } // install the browser extensions @@ -782,16 +704,7 @@ export async function open (browser: Browser, url: string, options: BrowserLaunc })) debug('setting up firefox utils') - const client = await firefoxUtil.setup({ automation, url, webdriverClient, remotePort: cdpPort, useWebDriverBiDi: USE_WEBDRIVER_BIDI, onError: options.onError }) - - if (client instanceof BrowserCriClient) { - browserCriClient = client - await utils.executeAfterBrowserLaunch(browser, { - webSocketDebuggerUrl: browserCriClient.getWebSocketDebuggerUrl(), - }) - } else { - browserBidiClient = client - } + browserBidiClient = await firefoxUtil.setup({ automation, url, webdriverClient }) } catch (err: unknown) { errors.throwErr('FIREFOX_COULD_NOT_CONNECT', err as Error) } diff --git a/packages/server/lib/modes/run.ts b/packages/server/lib/modes/run.ts index 0f97e38e97ae..12660cd83e0a 100644 --- a/packages/server/lib/modes/run.ts +++ b/packages/server/lib/modes/run.ts @@ -27,7 +27,6 @@ import * as printResults from '../util/print-run' import { telemetry } from '@packages/telemetry' import { CypressRunResult, createPublicBrowser, createPublicConfig, createPublicRunResults, createPublicSpec, createPublicSpecResults } from './results' import { EarlyExitTerminator } from '../util/graceful_crash_handling' -import { CDPFailedToStartFirefox } from '../browsers/firefox' import type { CypressError } from '@packages/errors' type SetScreenshotMetadata = (data: TakeScreenshotProps) => void @@ -513,11 +512,7 @@ async function waitForBrowserToConnect (options: { project: Project, socketId: s // try again up to 3 attempts const word = browserLaunchAttempt === 1 ? 'Retrying...' : 'Retrying again...' - if (CDPFailedToStartFirefox.isCDPFailedToStartFirefoxError(err?.originalError)) { - errors.warning('FIREFOX_CDP_FAILED_TO_CONNECT', word) - } else { - errors.warning('TESTS_DID_NOT_START_RETRYING', word) - } + errors.warning('TESTS_DID_NOT_START_RETRYING', word) browserLaunchAttempt += 1 @@ -534,19 +529,7 @@ async function waitForBrowserToConnect (options: { project: Project, socketId: s waitForSocketConnection(project, socketId), // TODO: remove the need to extend options and coerce this type launchBrowser(options as typeof options & { setScreenshotMetadata: SetScreenshotMetadata }), - ]).catch((e: CypressError) => { - // if the error wrapped is a CDPFailedToStartFirefox, try to relaunch the browser - if (CDPFailedToStartFirefox.isCDPFailedToStartFirefoxError(e?.originalError)) { - // if CDP fails to connect, which is ultimately out of our control and in the hands of webdriver - // we retry launching the browser in the hopes the session is spawned correctly - debug(`Caught in launchBrowser: ${e.details}`) - - return retryOnError(e) - } - - // otherwise, fail - throw e - }) + ]) .timeout(browserTimeout) .then(() => { telemetry.getSpan(`waitForBrowserToConnect:attempt:${browserLaunchAttempt}`)?.end() diff --git a/packages/server/lib/socket-base.ts b/packages/server/lib/socket-base.ts index 7b14f55d94c1..cd2a86e217f0 100644 --- a/packages/server/lib/socket-base.ts +++ b/packages/server/lib/socket-base.ts @@ -226,9 +226,7 @@ export class SocketBase { debug('automation:client connected') // only send the necessary config - automationClient.emit('automation:config', { - IS_CDP_FORCED_FOR_FIREFOX: !!process.env.FORCE_FIREFOX_CDP, - }) + automationClient.emit('automation:config', {}) // if our automation disconnects then we're // in trouble and should probably bomb everything diff --git a/packages/server/test/unit/browsers/firefox_spec.ts b/packages/server/test/unit/browsers/firefox_spec.ts index a9b9e61ff749..41eb5534e8ac 100644 --- a/packages/server/test/unit/browsers/firefox_spec.ts +++ b/packages/server/test/unit/browsers/firefox_spec.ts @@ -6,10 +6,6 @@ import os from 'os' import sinon from 'sinon' import fsExtra from 'fs-extra' import * as firefox from '../../../lib/browsers/firefox' -import firefoxUtil from '../../../lib/browsers/firefox-util' -import { CdpAutomation } from '../../../lib/browsers/cdp_automation' -import { BrowserCriClient } from '../../../lib/browsers/browser-cri-client' -import { ICriClient } from '../../../lib/browsers/cri-client' import { type Client as WebDriverClient, default as webdriver } from 'webdriver' import { EventEmitter } from 'stream' import { BidiAutomation } from '../../../lib/browsers/bidi_automation' @@ -22,23 +18,13 @@ const plugins = require('../../../lib/plugins') const specUtil = require('../../specUtils') describe('lib/browsers/firefox', () => { - const port = 3333 const mockContextId = '1234-5678' let wdInstance: sinon.SinonStubbedInstance<WebDriverClient> - let browserCriClient: BrowserCriClient let bidiAutomationClient: BidiAutomation - afterEach(() => { - return mockfs.restore() - }) - beforeEach(function () { sinon.stub(utils, 'getProfileDir').returns('/path/to/appData/firefox-stable/interactive') - mockfs({ - '/path/to/appData/firefox-stable/interactive': {}, - }) - wdInstance = { maximizeWindow: sinon.stub(), installAddOn: sinon.stub(), @@ -49,7 +35,6 @@ describe('lib/browsers/firefox', () => { browsingContextGetTree: sinon.stub(), browsingContextNavigate: sinon.stub(), capabilities: { - 'moz:debuggerAddress': '127.0.0.1:12345', // @ts-expect-error 'moz:processID': 1234, 'wdio:driverPID': 5678, @@ -79,9 +64,8 @@ describe('lib/browsers/firefox', () => { context('#open', () => { beforeEach(function () { - // majorVersion >= 86 indicates CDP support for Firefox, which provides - // the CDP debugger URL for the after:browser:launch tests - this.browser = { name: 'firefox', channel: 'stable', majorVersion: 100, path: '/path/to/binary' } + // majorVersion >= 135 indicates BiDi support for Firefox + this.browser = { name: 'firefox', channel: 'stable', majorVersion: 135, path: '/path/to/binary' } this.automation = { use: sinon.stub().returns({}), } @@ -107,14 +91,6 @@ describe('lib/browsers/firefox', () => { sinon.stub(fsExtra, 'writeJSON').resolves(undefined) sinon.stub(fsExtra, 'writeFile').returns(undefined) - browserCriClient = sinon.createStubInstance(BrowserCriClient) - - browserCriClient.attachToTargetUrl = sinon.stub().resolves({}) - browserCriClient.getWebSocketDebuggerUrl = sinon.stub().returns('ws://debugger') - browserCriClient.close = sinon.stub().resolves() - - sinon.stub(BrowserCriClient, 'create').resolves(browserCriClient) - sinon.stub(CdpAutomation, 'create').resolves() bidiAutomationClient = sinon.createStubInstance(BidiAutomation) bidiAutomationClient.setTopLevelContextId = sinon.stub().returns(undefined) @@ -122,32 +98,13 @@ describe('lib/browsers/firefox', () => { sinon.stub(BidiAutomation, 'create').returns(bidiAutomationClient) }) - context('#connectToNewSpec', () => { + context('#connectToNewSpecBiDi', () => { beforeEach(function () { this.options.onError = () => {} this.options.onInitializeNewBrowserTab = sinon.stub() }) - it('CDP: calls connectToNewSpecCDP in firefoxUtil', async function () { - wdInstance.getWindowHandles.resolves(['mock-context-id']) - await firefox.open(this.browser, 'http://', this.options, this.automation) - - this.options.url = 'next-spec-url' - await firefox.connectToNewSpec(this.browser, this.options, this.automation) - - expect(this.options.onInitializeNewBrowserTab).to.have.been.called - expect(wdInstance.getWindowHandles).to.have.been.called - expect(wdInstance.switchToWindow).to.have.been.calledWith('mock-context-id') - - // first time when connecting a new tab - expect(wdInstance.navigateTo).to.have.been.calledWith('about:blank') - // second time when navigating to the spec - expect(wdInstance.navigateTo).to.have.been.calledWith('next-spec-url') - }) - it('BiDi: calls connectToNewSpecBiDi in firefoxUtil', async function () { - this.browser.family = 'firefox' - this.browser.majorVersion = '135' await firefox.open(this.browser, 'http://', this.options, this.automation) this.options.url = 'next-spec-url' @@ -247,13 +204,10 @@ describe('lib/browsers/firefox', () => { describe(`webdriver capabilities`, () => { const getExpectedCapabilities = ({ - shouldUseBiDi, isDebugEnabled, }: { - shouldUseBiDi?: boolean isDebugEnabled?: boolean } = { - shouldUseBiDi: false, isDebugEnabled: false, }) => { return { @@ -261,7 +215,7 @@ describe('lib/browsers/firefox', () => { capabilities: sinon.match({ alwaysMatch: { browserName: 'firefox', - webSocketUrl: !!shouldUseBiDi, + webSocketUrl: true, acceptInsecureCerts: true, // @see https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions 'moz:firefoxOptions': { @@ -274,11 +228,10 @@ describe('lib/browsers/firefox', () => { ], // only partially match the preferences object because it is so large prefs: { - 'remote.active-protocols': shouldUseBiDi ? 1 : 2, + 'remote.active-protocols': 1, 'remote.enabled': true, }, }, - 'moz:debuggerAddress': !shouldUseBiDi, 'wdio:geckodriverOptions': { host: '127.0.0.1', marionetteHost: '127.0.0.1', @@ -304,71 +257,47 @@ describe('lib/browsers/firefox', () => { } } - describe(`creates the WebDriver session and geckodriver instance through capabilities, installs the extension, and passes the correct port to CDP`, function () { - it('for CDP', async function () { - await firefox.open(this.browser, 'http://', this.options, this.automation) - expect(webdriver.newSession).to.have.been.calledWith((getExpectedCapabilities({ shouldUseBiDi: false }))) - - expect(wdInstance.installAddOn).to.have.been.calledWith('/path/to/ext', true) + it('creates the WebDriver session and geckodriver instance through capabilities and installs the extension', async function () { + this.browser.family = 'firefox' + this.browser.majorVersion = '135' + await firefox.open(this.browser, 'http://', this.options, this.automation) + expect(webdriver.newSession).to.have.been.calledWith((getExpectedCapabilities())) - expect(wdInstance.navigateTo).to.have.been.calledWith('http://') + expect(wdInstance.installAddOn).to.have.been.calledWith('/path/to/ext', true) - // make sure CDP gets the expected port - expect(BrowserCriClient.create).to.be.calledWith({ hosts: ['127.0.0.1', '::1'], port: 12345, browserName: 'Firefox', onAsynchronousError: undefined, onServiceWorkerClientEvent: undefined }) - }) + expect(wdInstance.sessionSubscribe).to.be.calledWith({ events: [ + 'network.beforeRequestSent', + 'network.responseStarted', + 'network.responseCompleted', + 'network.fetchError', + 'browsingContext.contextCreated', + 'browsingContext.contextDestroyed', + ] }) - it('for BiDi', async function () { - this.browser.family = 'firefox' - this.browser.majorVersion = '135' - await firefox.open(this.browser, 'http://', this.options, this.automation) - expect(webdriver.newSession).to.have.been.calledWith((getExpectedCapabilities({ shouldUseBiDi: true }))) - - expect(wdInstance.installAddOn).to.have.been.calledWith('/path/to/ext', true) - - expect(wdInstance.sessionSubscribe).to.be.calledWith({ events: [ - 'network.beforeRequestSent', - 'network.responseStarted', - 'network.responseCompleted', - 'network.fetchError', - 'browsingContext.contextCreated', - 'browsingContext.contextDestroyed', - ] }) - - expect(wdInstance.browsingContextGetTree).to.be.calledWith({}) - - expect(wdInstance.browsingContextNavigate).to.have.been.calledWith({ - context: mockContextId, - url: 'http://', - }) - - // make sure Bidi gets created - expect(BidiAutomation.create).to.be.calledWith(wdInstance, this.automation) - expect(bidiAutomationClient.setTopLevelContextId).to.be.calledWith(mockContextId) - }) - }) + expect(wdInstance.browsingContextGetTree).to.be.calledWith({}) - describe('debugging: sets additional arguments if "DEBUG=cypress-verbose:server:browsers:geckodriver" and "DEBUG=cypress-verbose:server:browsers:webdriver" is set', () => { - afterEach(() => { - debug.disable() + expect(wdInstance.browsingContextNavigate).to.have.been.calledWith({ + context: mockContextId, + url: 'http://', }) - it('for CDP', async function () { - debug.enable('cypress-verbose:server:browsers:geckodriver,cypress-verbose:server:browsers:webdriver') - - await firefox.open(this.browser, 'http://', this.options, this.automation) + // make sure Bidi gets created + expect(BidiAutomation.create).to.be.calledWith(wdInstance, this.automation) + expect(bidiAutomationClient.setTopLevelContextId).to.be.calledWith(mockContextId) + }) - expect(webdriver.newSession).to.have.been.calledWith((getExpectedCapabilities({ isDebugEnabled: true }))) - }) + afterEach(() => { + debug.disable() + }) - it('for BiDi', async function () { - this.browser.family = 'firefox' - this.browser.majorVersion = '135' - debug.enable('cypress-verbose:server:browsers:geckodriver,cypress-verbose:server:browsers:webdriver') + it('debugging: sets additional arguments if "DEBUG=cypress-verbose:server:browsers:geckodriver" and "DEBUG=cypress-verbose:server:browsers:webdriver" is set', async function () { + this.browser.family = 'firefox' + this.browser.majorVersion = '135' + debug.enable('cypress-verbose:server:browsers:geckodriver,cypress-verbose:server:browsers:webdriver') - await firefox.open(this.browser, 'http://', this.options, this.automation) + await firefox.open(this.browser, 'http://', this.options, this.automation) - expect(webdriver.newSession).to.have.been.calledWith((getExpectedCapabilities({ isDebugEnabled: true, shouldUseBiDi: true }))) - }) + expect(webdriver.newSession).to.have.been.calledWith((getExpectedCapabilities({ isDebugEnabled: true }))) }) }) @@ -418,7 +347,6 @@ describe('lib/browsers/firefox', () => { }, [path.resolve(`${__dirname }/../../extension`)]: { 'abc': 'test' }, '/path/to/appData/firefox-stable/interactive': { - 'xulstore.json': '[foo xulstore.json]', 'chrome': { 'userChrome.css': '[foo userChrome.css]' }, }, }) @@ -493,26 +421,11 @@ describe('lib/browsers/firefox', () => { }) describe('sets "remote.active-protocols"', function () { - // CDP is deprecated in Firefox 129 and up. - // In order to enable CDP, we need to set - // remote.active-protocol=2 + // CDP was deprecated in Firefox 129 and up and was removed in Firefox 141. // @see https://fxdx.dev/deprecating-cdp-support-in-firefox-embracing-the-future-with-webdriver-bidi/ + // @see https://fxdx.dev/webdriver-bidi-becomes-the-default-for-cypress-in-firefox/ // @see https://github.com/cypress-io/cypress/issues/29713 - it('=2 to enable only CDP', async function () { - const executeBeforeBrowserLaunchSpy = sinon.spy(utils, 'executeBeforeBrowserLaunch') - - await firefox.open(this.browser, 'http://', this.options, this.automation) - - expect(executeBeforeBrowserLaunchSpy).to.have.been.calledWith(this.browser, sinon.match({ - preferences: { - 'remote.active-protocols': 2, - }, - }), this.options) - }) - it('=1 to enable only BiDi', async function () { - this.browser.family = 'firefox' - this.browser.majorVersion = '135' const executeBeforeBrowserLaunchSpy = sinon.spy(utils, 'executeBeforeBrowserLaunch') await firefox.open(this.browser, 'http://', this.options, this.automation) @@ -532,78 +445,40 @@ describe('lib/browsers/firefox', () => { expect(result.kill).to.be.an.instanceof(Function) }) - it('always clear user profile if it already exists', async function () { - mockfs({ - '/path/to/appData/firefox-stable/interactive/': { - 'xulstore.json': '[foo xulstore.json]', - 'chrome': { 'userChrome.css': '[foo userChrome.css]' }, - }, + context('profile/extension', () => { + afterEach(() => { + return mockfs.restore() }) - await firefox.open(this.browser, 'http://', this.options, this.automation) - - expect(specUtil.getFsPath('/path/to/appData/firefox-stable/interactive')).to.be.undefined - }) - - it('creates xulstore.json if not exist', async function () { - await firefox.open(this.browser, 'http://', this.options, this.automation) - expect(fsExtra.writeJSON).to.have.been.calledWith('/path/to/appData/firefox-stable/interactive/xulstore.json', { - 'chrome://browser/content/browser.xhtml': - { - 'main-window': - { - 'width': 1280, - 'height': 1024, - 'sizemode': 'maximized', - }, + it('always clear user profile if it already exists', async function () { + mockfs({ + '/path/to/appData/firefox-stable/interactive/': { + 'chrome': { 'userChrome.css': '[foo userChrome.css]' }, }, + }) - }) - }) - - it('creates chrome/userChrome.css if not exist', async function () { - await firefox.open(this.browser, 'http://', this.options, this.automation) - - expect(fsExtra.writeFile).to.have.been.calledWith('/path/to/appData/firefox-stable/interactive/chrome/userChrome.css') - }) + await firefox.open(this.browser, 'http://', this.options, this.automation) - it('clears browser cache', async function () { - mockfs({ - '/path/to/appData/firefox-stable/interactive/': { - 'CypressCache': { 'foo': 'bar' }, - }, + expect(specUtil.getFsPath('/path/to/appData/firefox-stable/interactive')).to.be.undefined }) - this.options.isTextTerminal = false - - await firefox.open(this.browser, 'http://', this.options, this.automation) - expect(specUtil.getFsPath('/path/to/appData/firefox-stable/interactive')).to.be.undefined - }) - - it('wraps errors when failing to connect to firefox (CDP failure)', async function () { - const err = new Error('failed to connect to CDP') - - // BrowserCriClient.create is stubbed above. restore it and re-stub BrowserCriClient.create - // @ts-expect-error - BrowserCriClient.create.restore() - - sinon.stub(BrowserCriClient, 'create').rejects(err) + it('creates chrome/userChrome.css if not exist', async function () { + await firefox.open(this.browser, 'http://', this.options, this.automation) - await expect(firefox.open(this.browser, 'http://', this.options, this.automation)).to.be.rejectedWith() - .then((wrapperErr) => { - expect(wrapperErr.message).to.include('Cypress failed to make a connection to Firefox.') - expect(wrapperErr.details).to.include(err.message) + expect(fsExtra.writeFile).to.have.been.calledWith('/path/to/appData/firefox-stable/interactive/chrome/userChrome.css') }) - }) - it('executes after:browser:launch if registered', async function () { - plugins.has.withArgs('after:browser:launch').returns(true) - plugins.execute.resolves(null) + it('clears browser cache', async function () { + mockfs({ + '/path/to/appData/firefox-stable/interactive/': { + 'CypressCache': { 'foo': 'bar' }, + }, + }) - await firefox.open(this.browser, 'http://', this.options, this.automation) + this.options.isTextTerminal = false - expect(plugins.execute).to.be.calledWith('after:browser:launch', this.browser, { - webSocketDebuggerUrl: 'ws://debugger', + await firefox.open(this.browser, 'http://', this.options, this.automation) + expect(specUtil.getFsPath('/path/to/appData/firefox-stable/interactive')).to.be.undefined }) }) @@ -633,7 +508,6 @@ describe('lib/browsers/firefox', () => { expect(process.kill).to.have.been.calledWith(1234) // kills the webdriver process/ geckodriver process expect(process.kill).to.have.been.calledWith(5678) - expect(browserCriClient.close).to.have.been.called // makes sure the exit event is called to signal to the rest of cypress server that the processes are killed expect(instance.emit).to.have.been.calledWith('exit') }) @@ -653,26 +527,9 @@ describe('lib/browsers/firefox', () => { expect(process.kill).to.have.been.calledWith(1234) // kills the webdriver process/ geckodriver process expect(process.kill).to.have.been.calledWith(5678) - expect(browserCriClient.close).to.have.been.called // makes sure the exit event is called to signal to the rest of cypress server that the processes are killed expect(instance.emit).to.have.been.calledWith('exit') }) - - it('throws CDPFailedToStartFirefox if the mox:debuggerAddress capability is not returned by webdriver', function () { - delete wdInstance.capabilities['moz:debuggerAddress'] - sinon.stub(process, 'kill').returns(true) - - return firefox.open(this.browser, 'http://', this.options, this.automation).catch((err) => { - // make sure we through the correct error here to prompt @packages/server/lib/modes/run.ts - // to retry the browser connection - expect(err.details).to.include('CDPFailedToStartFirefox: webdriver session failed to start CDP even though "moz:debuggerAddress" was provided. Please try to relaunch the browser') - expect(err.type).to.equal('FIREFOX_COULD_NOT_CONNECT') - // kills the browser - expect(process.kill).to.have.been.calledWith(1234) - // kills the webdriver process / geckodriver process - expect(process.kill).to.have.been.calledWith(5678) - }) - }) }) }) @@ -681,56 +538,4 @@ describe('lib/browsers/firefox', () => { expect(firefox.connectProtocolToBrowser).to.throw('Protocol is not yet supported in firefox.') }) }) - - context('#closeProtocolConnection', () => { - it('throws error', () => { - expect(firefox.closeProtocolConnection).to.throw('Protocol is not yet supported in firefox.') - }) - }) - - context('firefox-util', () => { - context('#setupCDP', function () { - it('correctly sets up the remote agent', async function () { - const criClientStub: ICriClient = { - targetId: '', - send: sinon.stub(), - on: sinon.stub(), - off: sinon.stub(), - close: sinon.stub(), - ws: sinon.stub() as any, - queue: { - enableCommands: [], - enqueuedCommands: [], - subscriptions: [], - }, - closed: false, - connected: false, - } - - const automationStub = { - onServiceWorkerClientEvent: sinon.stub(), - } - - const browserCriClient: BrowserCriClient = sinon.createStubInstance(BrowserCriClient) - - browserCriClient.attachToTargetUrl = sinon.stub().resolves(criClientStub) - - sinon.stub(BrowserCriClient, 'create').resolves(browserCriClient) - sinon.stub(CdpAutomation, 'create').resolves() - - const actual = await firefoxUtil.setupCDP(port, automationStub, null) - - expect(actual).to.equal(browserCriClient) - expect(browserCriClient.attachToTargetUrl).to.be.calledWith('about:blank') - expect(BrowserCriClient.create).to.be.calledWith({ hosts: ['127.0.0.1', '::1'], port, browserName: 'Firefox', onAsynchronousError: null, onServiceWorkerClientEvent: automationStub.onServiceWorkerClientEvent }) - expect(CdpAutomation.create).to.be.calledWith( - criClientStub.send, - criClientStub.on, - criClientStub.off, - browserCriClient.resetBrowserTargets, - automationStub, - ) - }) - }) - }) }) diff --git a/system-tests/__snapshots__/cdp_deprecated_firefox_spec.ts.js b/system-tests/__snapshots__/cdp_deprecated_firefox_spec.ts.js deleted file mode 100644 index e9c80eb32a4b..000000000000 --- a/system-tests/__snapshots__/cdp_deprecated_firefox_spec.ts.js +++ /dev/null @@ -1,55 +0,0 @@ -exports['CDP deprecated in Firefox / logs a warning to the user that CDP is deprecated and will be removed in Cypress 15'] = ` - -==================================================================================================== - - (Run Starting) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Cypress: 1.2.3 │ - │ Browser: FooBrowser 88 │ - │ Specs: 1 found (simple_passing.cy.js) │ - │ Searched: cypress/e2e/simple_passing.cy.js │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - -──────────────────────────────────────────────────────────────────────────────────────────────────── - - Running: simple_passing.cy.js (1 of 1) -Since Firefox 129, Chrome DevTools Protocol (CDP) has been deprecated in Firefox. In Firefox 135 and above, Cypress defaults to automating the Firefox browser with WebDriver BiDi. Cypress will no longer support CDP within Firefox in the future and is planned for removal in Cypress 15. - - - simple passing spec - ✓ passes - - - 1 passing - - - (Results) - - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ Tests: 1 │ - │ Passing: 1 │ - │ Failing: 0 │ - │ Pending: 0 │ - │ Skipped: 0 │ - │ Screenshots: 0 │ - │ Video: false │ - │ Duration: X seconds │ - │ Spec Ran: simple_passing.cy.js │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - - -==================================================================================================== - - (Run Finished) - - - Spec Tests Passing Failing Pending Skipped - ┌────────────────────────────────────────────────────────────────────────────────────────────────┐ - │ ✔ simple_passing.cy.js XX:XX 1 1 - - - │ - └────────────────────────────────────────────────────────────────────────────────────────────────┘ - ✔ All specs passed! XX:XX 1 1 - - - - - -` diff --git a/system-tests/test/cdp_deprecated_firefox_spec.ts b/system-tests/test/cdp_deprecated_firefox_spec.ts deleted file mode 100644 index b9eb8706e4f7..000000000000 --- a/system-tests/test/cdp_deprecated_firefox_spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import systemTests from '../lib/system-tests' - -describe('CDP deprecated in Firefox', () => { - systemTests.setup() - - systemTests.it('logs a warning to the user that CDP is deprecated and will be removed in Cypress 15', { - browser: 'firefox', - processEnv: { - FORCE_FIREFOX_CDP: '1', - }, - expectedExitCode: 0, - snapshot: true, - spec: 'simple_passing.cy.js', - onStdout: (stdout) => { - expect(stdout).to.include('Since Firefox 129, Chrome DevTools Protocol (CDP) has been deprecated in Firefox. In Firefox 135 and above, Cypress defaults to automating the Firefox browser with WebDriver BiDi. Cypress will no longer support CDP within Firefox in the future and is planned for removal in Cypress 15.') - }, - }) -}) From 346e80110aa61eb8c7afdc143e88b68c9b5be38d Mon Sep 17 00:00:00 2001 From: Bill Glesias <bglesias@gmail.com> Date: Tue, 8 Apr 2025 14:46:30 -0400 Subject: [PATCH 13/13] chore: merge develop into cypress release 15 branch (#31464) * dependency: upgrade mocha to 7.2.0 (#31423) * dependency: upgrade mocha to 7.2.0 * changelog entry * remove the it.only from the mocha patch changelog that is triggering our stop-only check from passing * skip patches folder with stop-only check * remove extra bracket * Update protocol_spec to reflect new mocha line number for error stack trace * chore: updating v8 snapshot cache (#31424) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> * chore: updating v8 snapshot cache (#31425) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> * chore: updating v8 snapshot cache (#31426) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> * chore: migrates plugin system test to a v3 extension (#31434) * chore: Update Chrome (stable) to 135.0.7049.52 (#31428) * chore: Update Chrome (stable) to 135.0.7049.52 * empty commit --------- Co-authored-by: cypress-bot[bot] <41898282+cypress-bot[bot]@users.noreply.github.com> Co-authored-by: Jennifer Shehane <jennifer@cypress.io> Co-authored-by: Cacie Prins <cacieprins@users.noreply.github.com> * chore: bump Firefox to 137 (#31431) * chore: bump Firefox to 137 * use 137 version? weird. * just kidding, major version only has 1 zero after it................ * dependency: update server to mocha 7.2.0 (#31432) * dependency: update server to mocha 7.2.0 * Add PR to changelog * chore: updating v8 snapshot cache (#31437) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> * chore: updating v8 snapshot cache (#31438) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> * chore: updating v8 snapshot cache (#31439) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> * chore: Update Chrome (beta) to 136.0.7103.17 (#31448) * chore: Update Chrome (beta) to 136.0.7103.17 * empty commit --------- Co-authored-by: cypress-bot[bot] <41898282+cypress-bot[bot]@users.noreply.github.com> Co-authored-by: Jennifer Shehane <jennifer@cypress.io> * refactor: lifts toPosix to its own file, removes circular dependency between stack_utils and source_map_utils (#30983) * refactor: lifts toPosix to remove circular dependency between stack_utils and source_map_utils * camelCase to snake_case * rm duplicated file * internal: (studio) make the protocol database accessible to studio (#31443) * internal: (studio) make the protocol database accessible to studio * PR comment * chore(deps): update dependency patch-package to v8 (#31451) * chore(deps): update dependency patch-package to v8 * empty commit * add types to handle json-stable-stringify dep change --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jennifer Shehane <jennifer@cypress.io> * chore: fix deprecation warnings and refactor react reporter to use functional components and hooks (#31284) * chore: fix deprecation warnings and refactor react reporter to use functional components with hooks * chore: update code to reflect feedback from code review * fix issues with scrollIntoView() on updated component and refactor isOpen logic in collapsible to not attempt to sync state * fix issues with tests after refactor * see if event registration fixes windows flake * chore: update snap-shot-core patch package file to match version (#31449) * chore: update snap-shot-core patch package file to match version * update circle cache * experiment with removing .md from yarnclean * add .md back to yarnclean * bust circle cache * remove .md files being cleaned from yarn to get around patch-package issue * print size of cache * try out the size of the .md * remove md from yarnclean * UPdate to version without removal of markdown files * chore: updating v8 snapshot cache (#31460) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> * chore: updating v8 snapshot cache (#31462) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> * chore: updating v8 snapshot cache (#31461) Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> * feat: cy.press() (#31398) * wip - cy.press() command * cy command for dispatching key press/down/up events * unit tests and failure cases for cy.press() * Cypress.Keyboard.Keys definition; fix command log message * add keys to the internal keyboard type * auto-focus in cdp * ensure aut iframe is focused before dispatching key events in bidi browsers * update tests for cdp focus * fixed tests for bidi * lint * fix type ref in .d.ts * linting * skip press() driver test in ff below v135 * try all contexts for frame before failing due to missing/invalid context id * ensure error is error before accessing props * skip press driver test in webkit * changelog * debug automation middleware invocation for firefox flake * debug * cache update * use bidi automation middleware from connectToNewSpec rather than constructor * more comprehensive logging * debug socket base, additional debug in automation * install firefox automation middleware on setup as well as connectToNewSpec * unit tests for firefox-utils * proper calledWith --------- Co-authored-by: Jennifer Shehane <jennifer@cypress.io> * docs: update contributing requirements for corepack (#31463) * chore: remove `du` check (#31465) * chore: use different args for `du` in win * rm du command for build * chore: release 14.3.0 (#31467) --------- Co-authored-by: Jennifer Shehane <jennifer@cypress.io> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: cypress-bot[bot] <+cypress-bot[bot]@users.noreply.github.com> Co-authored-by: Cacie Prins <cacieprins@users.noreply.github.com> Co-authored-by: cypress-bot[bot] <41898282+cypress-bot[bot]@users.noreply.github.com> Co-authored-by: Ryan Manuel <ryanm@cypress.io> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Mike McCready <66998419+MikeMcC399@users.noreply.github.com> --- .circleci/cache-version.txt | 2 +- .circleci/workflows.yml | 24 +- .yarnclean | 5 +- CONTRIBUTING.md | 6 +- cli/CHANGELOG.md | 10 +- cli/types/cypress.d.ts | 201 ++++++++------- cli/types/tslint.json | 4 +- package.json | 6 +- .../cypress/e2e/cypress-in-cypress-e2e.cy.ts | 17 +- packages/app/cypress/e2e/specs_list_e2e.cy.ts | 7 + packages/app/src/runner/index.ts | 7 + packages/app/src/runner/reporter.ts | 10 +- packages/app/src/runner/useEventManager.ts | 6 +- .../cypress/e2e/commands/actions/press.cy.ts | 28 +- .../e2e/e2e/origin/commands/misc.cy.ts | 2 +- .../driver/cypress/fixtures/input_events.html | 1 - packages/driver/cypress/support/utils.ts | 18 +- packages/driver/package.json | 2 +- ...+7.1.2.dev.patch => mocha+7.2.0.dev.patch} | 54 +++- .../driver/src/cy/commands/actions/index.ts | 2 + .../driver/src/cy/commands/actions/press.ts | 77 ++++++ .../driver/src/cy/commands/sessions/index.ts | 4 +- packages/driver/src/cy/keyboard.ts | 6 + packages/driver/src/cypress.ts | 1 + packages/driver/src/cypress/commands.ts | 8 +- packages/driver/src/cypress/error_messages.ts | 12 + .../driver/src/cypress/source_map_utils.ts | 8 +- packages/driver/src/cypress/stack_utils.ts | 9 +- packages/driver/src/cypress/util/to_posix.ts | 5 + packages/driver/test/__setup__/setupMocks.ts | 11 + .../unit/cy/commands/actions/press.spec.ts | 187 ++++++++++++++ .../test/unit/cypress/util/toPosix.spec.ts | 40 +++ packages/driver/types/internal-types.d.ts | 3 + packages/driver/vitest.config.mjs | 1 + packages/frontend-shared/package.json | 2 +- packages/reporter/cypress/e2e/agents.cy.ts | 2 +- packages/reporter/cypress/e2e/aliases.cy.ts | 2 +- packages/reporter/cypress/e2e/commands.cy.ts | 2 +- packages/reporter/cypress/e2e/header.cy.ts | 2 +- packages/reporter/cypress/e2e/hooks.cy.ts | 2 +- packages/reporter/cypress/e2e/memory.cy.ts | 2 +- packages/reporter/cypress/e2e/routes.cy.ts | 2 +- packages/reporter/cypress/e2e/runnables.cy.ts | 2 +- packages/reporter/cypress/e2e/shortcuts.cy.ts | 2 +- .../reporter/cypress/e2e/spec_title.cy.ts | 2 +- packages/reporter/cypress/e2e/suites.cy.ts | 2 +- .../reporter/cypress/e2e/test_errors.cy.ts | 2 +- packages/reporter/cypress/e2e/tests.cy.ts | 2 +- .../reporter/src/attempts/attempt-model.ts | 4 + packages/reporter/src/attempts/attempts.tsx | 107 ++++---- .../reporter/src/collapsible/collapsible.tsx | 109 +++----- packages/reporter/src/commands/command.tsx | 236 ++++++++--------- .../reporter/src/errors/error-code-frame.tsx | 47 ++-- packages/reporter/src/errors/test-error.tsx | 31 +-- packages/reporter/src/lib/flash-on-click.tsx | 69 ++--- packages/reporter/src/lib/switch.tsx | 46 ++-- packages/reporter/src/main.tsx | 152 ++++++----- .../src/runnables/runnable-and-suite.tsx | 45 ++-- .../src/runnables/runnable-header.tsx | 73 +++--- packages/reporter/src/runnables/runnables.tsx | 49 ++-- packages/reporter/src/test/test-model.ts | 4 + packages/reporter/src/test/test.cy.tsx | 6 + packages/reporter/src/test/test.tsx | 240 +++++++----------- packages/server/lib/automation/automation.ts | 8 +- .../lib/automation/commands/key_press.ts | 71 +++++- .../server/lib/browsers/bidi_automation.ts | 11 +- .../server/lib/browsers/cdp_automation.ts | 24 +- packages/server/lib/browsers/firefox-util.ts | 2 + packages/server/lib/browsers/firefox.ts | 4 + packages/server/lib/cloud/protocol.ts | 4 + packages/server/lib/cloud/studio.ts | 6 + packages/server/lib/project-base.ts | 4 + packages/server/lib/reporter.js | 8 +- packages/server/lib/socket-base.ts | 2 + packages/server/package.json | 2 +- .../fixtures/cloud/protocol/test-protocol.ts | 4 +- .../fixtures/cloud/studio/test-studio.ts | 4 + .../automation/commands/key_press.spec.ts | 207 +++++++++++++-- .../unit/browsers/bidi_automation_spec.ts | 3 +- .../test/unit/browsers/firefox-util_spec.ts | 58 +++++ .../server/test/unit/browsers/firefox_spec.ts | 2 + .../server/test/unit/cloud/protocol_spec.ts | 14 + .../server/test/unit/cloud/studio_spec.ts | 18 ++ packages/server/test/unit/project_spec.js | 4 + packages/types/src/protocol.ts | 5 +- .../types/src/studio/studio-server-types.ts | 2 + ....patch => snap-shot-core+10.2.4.dev.patch} | 0 scripts/binary/binary-cleanup.js | 2 +- system-tests/__snapshots__/protocol_spec.js | 224 ++++++++-------- .../ext/{background.js => content.js} | 0 .../plugin-extension/ext/manifest.json | 11 +- .../cache/darwin/snapshot-meta.json | 117 ++++----- .../cache/linux/snapshot-meta.json | 117 ++++----- .../cache/win32/snapshot-meta.json | 117 ++++----- .../v8-snapshot/src/setup/force-no-rewrite.ts | 4 +- yarn.lock | 92 ++++--- 96 files changed, 1908 insertions(+), 1273 deletions(-) rename packages/driver/patches/{mocha+7.1.2.dev.patch => mocha+7.2.0.dev.patch} (95%) create mode 100644 packages/driver/src/cy/commands/actions/press.ts create mode 100644 packages/driver/src/cypress/util/to_posix.ts create mode 100644 packages/driver/test/__setup__/setupMocks.ts create mode 100644 packages/driver/test/unit/cy/commands/actions/press.spec.ts create mode 100644 packages/driver/test/unit/cypress/util/toPosix.spec.ts create mode 100644 packages/server/test/unit/browsers/firefox-util_spec.ts rename patches/{snap-shot-core+10.2.0.dev.patch => snap-shot-core+10.2.4.dev.patch} (100%) rename system-tests/projects/plugin-extension/ext/{background.js => content.js} (100%) diff --git a/.circleci/cache-version.txt b/.circleci/cache-version.txt index dde0da7113dc..37a73411403f 100644 --- a/.circleci/cache-version.txt +++ b/.circleci/cache-version.txt @@ -1,3 +1,3 @@ # Bump this version to force CI to re-create the cache from scratch. -3-18-2024:4:25 +4-7-2025-v1 diff --git a/.circleci/workflows.yml b/.circleci/workflows.yml index ac41c6cffdca..ac0b50e9e192 100644 --- a/.circleci/workflows.yml +++ b/.circleci/workflows.yml @@ -1,8 +1,8 @@ version: 2.1 -chrome-stable-version: &chrome-stable-version "134.0.6998.165" -chrome-beta-version: &chrome-beta-version "135.0.7049.41" -firefox-stable-version: &firefox-stable-version "136.0.3" +chrome-stable-version: &chrome-stable-version "135.0.7049.52" +chrome-beta-version: &chrome-beta-version "136.0.7103.17" +firefox-stable-version: &firefox-stable-version "137.0" orbs: browser-tools: circleci/browser-tools@1.5.2 @@ -38,7 +38,7 @@ mainBuildFilters: &mainBuildFilters - /^release\/\d+\.\d+\.\d+$/ # use the following branch as well to ensure that v8 snapshot cache updates are fully tested - 'update-v8-snapshot-cache-on-develop' - - 'renovate/webdriverio-monorepo' + - 'chore/fix_react_18_deprecation_warnings' # usually we don't build Mac app - it takes a long time # but sometimes we want to really confirm we are doing the right thing @@ -49,7 +49,7 @@ macWorkflowFilters: &darwin-workflow-filters - equal: [ develop, << pipeline.git.branch >> ] # use the following branch as well to ensure that v8 snapshot cache updates are fully tested - equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ] - - equal: [ 'renovate/webdriverio-monorepo', << pipeline.git.branch >> ] + - equal: [ 'chore/fix_react_18_deprecation_warnings', << pipeline.git.branch >> ] - matches: pattern: /^release\/\d+\.\d+\.\d+$/ value: << pipeline.git.branch >> @@ -60,7 +60,7 @@ linuxArm64WorkflowFilters: &linux-arm64-workflow-filters - equal: [ develop, << pipeline.git.branch >> ] # use the following branch as well to ensure that v8 snapshot cache updates are fully tested - equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ] - - equal: [ 'renovate/webdriverio-monorepo', << pipeline.git.branch >> ] + - equal: [ 'chore/fix_react_18_deprecation_warnings', << pipeline.git.branch >> ] - matches: pattern: /^release\/\d+\.\d+\.\d+$/ value: << pipeline.git.branch >> @@ -83,7 +83,8 @@ windowsWorkflowFilters: &windows-workflow-filters - equal: [ develop, << pipeline.git.branch >> ] # use the following branch as well to ensure that v8 snapshot cache updates are fully tested - equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ] - - equal: [ 'renovate/webdriverio-monorepo', << pipeline.git.branch >> ] + - equal: [ 'chore/fix_react_18_deprecation_warnings', << pipeline.git.branch >> ] + - equal: [ 'cacie/fix-du', << pipeline.git.branch >> ] - matches: pattern: /^release\/\d+\.\d+\.\d+$/ value: << pipeline.git.branch >> @@ -157,7 +158,7 @@ commands: name: Set environment variable to determine whether or not to persist artifacts command: | echo "Setting SHOULD_PERSIST_ARTIFACTS variable" - echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "bump-win-version-info" ]]; then + echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "chore/fix_react_18_deprecation_warnings" ]]; then export SHOULD_PERSIST_ARTIFACTS=true fi' >> "$BASH_ENV" # You must run `setup_should_persist_artifacts` command and be using bash before running this command @@ -497,9 +498,9 @@ commands: default: cy-doc steps: - run: pwd - - run: - name: print global yarn cache path - command: echo $(yarn global bin) + ##- run: + ## name: print global yarn cache path and size + ## command: du -sh $(yarn global bin) - run: name: print yarn version command: yarn versions @@ -776,6 +777,7 @@ commands: - windows-install-chrome: browser: <<parameters.browser>> - run: + name: Run <<parameters.package>> UI tests command: | echo Current working directory is $PWD echo Total containers $CIRCLE_NODE_TOTAL diff --git a/.yarnclean b/.yarnclean index 1b0696546cd6..410da765e3aa 100644 --- a/.yarnclean +++ b/.yarnclean @@ -44,7 +44,4 @@ wercker.yml .flowconfig .documentup.json .yarn-metadata.json -.travis.yml - -# misc -*.md +.travis.yml \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6324370c43c1..d000512fbb18 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -201,7 +201,7 @@ We try to tag all issues with a `pkg/` or `npm/` tag describing the appropriate You must have the following installed on your system to contribute locally: - [`Node.js`](https://nodejs.org/en/) (See the root [.node-version](.node-version) file for the required version. You can find a list of tools on [node-version-usage](https://github.com/shadowspawn/node-version-usage) to switch the version of [`Node.js`](https://nodejs.org/en/) based on [.node-version](.node-version).) -- [`Yarn v1 Classic`](https://yarnpkg.com/en/docs/install). If you have [`Node.js`](https://nodejs.org/en/) experimental [corepack](https://nodejs.org/docs/latest/api/corepack.html) enabled, installation of the Yarn package manager will be handled automatically. Attempting to install Yarn globally with npm will fail if [corepack](https://nodejs.org/docs/latest/api/corepack.html) is enabled. +- [`Yarn v1 Classic`](https://yarnpkg.com/en/docs/install) (See also [Corepack](#corepack) below.) - [`python`](https://www.python.org/downloads/) (since we use `node-gyp`. See their [repo](https://github.com/nodejs/node-gyp) for Python version requirements.) #### Debian/Ubuntu @@ -216,6 +216,10 @@ For Ubuntu `24.04` and above, refer also to the [Ubuntu 24.04 Release notes](htt Currently no additional instructions for installation requirements. +#### Corepack + +The Cypress repo is compatible with Corepack and contains a `packageManager` field in the root [package.json](./package.json) file to automatically install Yarn. Cypress does not however require you to enable Corepack. It is classed as experimental and not suitable for production by the Node.js organization. Refer to the repo [corepack](https://github.com/nodejs/corepack#readme) for instructions, known issues and workarounds. + ### Getting Started The project utilizes [yarn workspaces](https://yarnpkg.com/lang/en/docs/workspaces/) and leverages [lerna](https://lerna.js.org/) to orchestrate running within the context of one or more packages. While it is not as important to understand lerna or yarn workspaces, it **is important** to note that running scripts or installing new dependencies should always happen from the repo's root directory. diff --git a/cli/CHANGELOG.md b/cli/CHANGELOG.md index 403c189a195a..4815b89d8206 100644 --- a/cli/CHANGELOG.md +++ b/cli/CHANGELOG.md @@ -8,9 +8,13 @@ _Released 07/01/2025 (PENDING)_ - Removed support for Node.js 18 and Node.js 23. Addresses [#31302](https://github.com/cypress-io/cypress/issues/31302). - Removed support for [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol) with the [firefox](https://www.mozilla.org/) browser. Addresses [#31189](https://github.com/cypress-io/cypress/issues/31189). -## 14.2.2 +## 14.3.0 -_Released 4/8/2025 (PENDING)_ +_Released 4/8/2025_ + +**Features:** + +- The [`cy.press()`](https://on.cypress.io/api/press) command is now available. It supports dispatching native Tab keyboard events to the browser. Addresses [#31050](https://github.com/cypress-io/cypress/issues/31050). Addresses [#299](https://github.com/cypress-io/cypress/issues/299). Addressed in [#31398](https://github.com/cypress-io/cypress/pull/31398). **Bugfixes:** @@ -25,7 +29,7 @@ _Released 4/8/2025 (PENDING)_ **Dependency Updates:** -- Upgraded `mocha` from `7.0.1` to `7.1.2`. Addressed in [#31416](https://github.com/cypress-io/cypress/pull/31416). +- Upgraded `mocha` from `7.0.1` to `7.2.0`. Addressed in [#31423](https://github.com/cypress-io/cypress/pull/31423) and [#31432](https://github.com/cypress-io/cypress/pull/31432). - Upgraded `webdriver` from `9.7.3` to `9.11.0`. Addressed in [#31315](https://github.com/cypress-io/cypress/pull/31315). - Upgraded `win-version-info` from `5.0.1` to `6.0.1`. Addressed in [#31358](https://github.com/cypress-io/cypress/pull/31358). diff --git a/cli/types/cypress.d.ts b/cli/types/cypress.d.ts index b70d58397441..54d69512bc5a 100644 --- a/cli/types/cypress.d.ts +++ b/cli/types/cypress.d.ts @@ -578,99 +578,7 @@ declare namespace Cypress { */ stop(): void - Commands: { - /** - * Add a custom command - * @see https://on.cypress.io/api/commands - */ - add<T extends keyof Chainable>(name: T, fn: CommandFn<T>): void - - /** - * Add a custom parent command - * @see https://on.cypress.io/api/commands#Parent-Commands - */ - add<T extends keyof Chainable>(name: T, options: CommandOptions & { prevSubject: false }, fn: CommandFn<T>): void - - /** - * Add a custom child command - * @see https://on.cypress.io/api/commands#Child-Commands - */ - add<T extends keyof Chainable, S = any>(name: T, options: CommandOptions & { prevSubject: true }, fn: CommandFnWithSubject<T, S>): void - - /** - * Add a custom child or dual command - * @see https://on.cypress.io/api/commands#Validations - */ - add<T extends keyof Chainable, S extends PrevSubject>( - name: T, options: CommandOptions & { prevSubject: S | ['optional'] }, fn: CommandFnWithSubject<T, PrevSubjectMap[S]>, - ): void - - /** - * Add a custom command that allows multiple types as the prevSubject - * @see https://on.cypress.io/api/commands#Validations#Allow-Multiple-Types - */ - add<T extends keyof Chainable, S extends PrevSubject>( - name: T, options: CommandOptions & { prevSubject: S[] }, fn: CommandFnWithSubject<T, PrevSubjectMap<void>[S]>, - ): void - - /** - * Add one or more custom commands - * @see https://on.cypress.io/api/commands - */ - addAll<T extends keyof Chainable>(fns: CommandFns): void - - /** - * Add one or more custom parent commands - * @see https://on.cypress.io/api/commands#Parent-Commands - */ - addAll<T extends keyof Chainable>(options: CommandOptions & { prevSubject: false }, fns: CommandFns): void - - /** - * Add one or more custom child commands - * @see https://on.cypress.io/api/commands#Child-Commands - */ - addAll<T extends keyof Chainable, S = any>(options: CommandOptions & { prevSubject: true }, fns: CommandFnsWithSubject<S>): void - - /** - * Add one or more custom commands that validate their prevSubject - * @see https://on.cypress.io/api/commands#Validations - */ - addAll<T extends keyof Chainable, S extends PrevSubject>( - options: CommandOptions & { prevSubject: S | ['optional'] }, fns: CommandFnsWithSubject<PrevSubjectMap[S]>, - ): void - - /** - * Add one or more custom commands that allow multiple types as their prevSubject - * @see https://on.cypress.io/api/commands#Allow-Multiple-Types - */ - addAll<T extends keyof Chainable, S extends PrevSubject>( - options: CommandOptions & { prevSubject: S[] }, fns: CommandFnsWithSubject<PrevSubjectMap<void>[S]>, - ): void - - /** - * Overwrite an existing Cypress command with a new implementation - * @see https://on.cypress.io/api/commands#Overwrite-Existing-Commands - */ - overwrite<T extends keyof Chainable>(name: T, fn: CommandFnWithOriginalFn<T>): void - - /** - * Overwrite an existing Cypress command with a new implementation - * @see https://on.cypress.io/api/commands#Overwrite-Existing-Commands - */ - overwrite<T extends keyof Chainable, S extends PrevSubject>(name: T, fn: CommandFnWithOriginalFnAndSubject<T, PrevSubjectMap[S]>): void - - /** - * Add a custom query - * @see https://on.cypress.io/api/custom-queries - */ - addQuery<T extends keyof Chainable>(name: T, fn: QueryFn<T>): void - - /** - * Overwrite an existing Cypress query with a new implementation - * @see https://on.cypress.io/api/custom-queries - */ - overwriteQuery<T extends keyof Chainable>(name: T, fn: QueryFnWithOriginalFn<T>): void - } + Commands: Commands /** * @see https://on.cypress.io/cookies @@ -775,6 +683,9 @@ declare namespace Cypress { */ Keyboard: { defaults(options: Partial<KeyboardDefaultsOptions>): void + Keys: { + TAB: 'Tab', + }, } /** @@ -829,6 +740,100 @@ declare namespace Cypress { onSpecWindow: (window: Window, specList: string[] | Array<() => Promise<void>>) => void } + interface Commands { + /** + * Add a custom command + * @see https://on.cypress.io/api/commands + */ + add<T extends keyof Chainable>(name: T, fn: CommandFn<T>): void + + /** + * Add a custom parent command + * @see https://on.cypress.io/api/commands#Parent-Commands + */ + add<T extends keyof Chainable>(name: T, options: CommandOptions & { prevSubject: false }, fn: CommandFn<T>): void + + /** + * Add a custom child command + * @see https://on.cypress.io/api/commands#Child-Commands + */ + add<T extends keyof Chainable, S = any>(name: T, options: CommandOptions & { prevSubject: true }, fn: CommandFnWithSubject<T, S>): void + + /** + * Add a custom child or dual command + * @see https://on.cypress.io/api/commands#Validations + */ + add<T extends keyof Chainable, S extends PrevSubject>( + name: T, options: CommandOptions & { prevSubject: S | ['optional'] }, fn: CommandFnWithSubject<T, PrevSubjectMap[S]>, + ): void + + /** + * Add a custom command that allows multiple types as the prevSubject + * @see https://on.cypress.io/api/commands#Validations#Allow-Multiple-Types + */ + add<T extends keyof Chainable, S extends PrevSubject>( + name: T, options: CommandOptions & { prevSubject: S[] }, fn: CommandFnWithSubject<T, PrevSubjectMap<void>[S]>, + ): void + + /** + * Add one or more custom commands + * @see https://on.cypress.io/api/commands + */ + addAll<T extends keyof Chainable>(fns: CommandFns): void + + /** + * Add one or more custom parent commands + * @see https://on.cypress.io/api/commands#Parent-Commands + */ + addAll<T extends keyof Chainable>(options: CommandOptions & { prevSubject: false }, fns: CommandFns): void + + /** + * Add one or more custom child commands + * @see https://on.cypress.io/api/commands#Child-Commands + */ + addAll<T extends keyof Chainable, S = any>(options: CommandOptions & { prevSubject: true }, fns: CommandFnsWithSubject<S>): void + + /** + * Add one or more custom commands that validate their prevSubject + * @see https://on.cypress.io/api/commands#Validations + */ + addAll<T extends keyof Chainable, S extends PrevSubject>( + options: CommandOptions & { prevSubject: S | ['optional'] }, fns: CommandFnsWithSubject<PrevSubjectMap[S]>, + ): void + + /** + * Add one or more custom commands that allow multiple types as their prevSubject + * @see https://on.cypress.io/api/commands#Allow-Multiple-Types + */ + addAll<T extends keyof Chainable, S extends PrevSubject>( + options: CommandOptions & { prevSubject: S[] }, fns: CommandFnsWithSubject<PrevSubjectMap<void>[S]>, + ): void + + /** + * Overwrite an existing Cypress command with a new implementation + * @see https://on.cypress.io/api/commands#Overwrite-Existing-Commands + */ + overwrite<T extends keyof Chainable>(name: T, fn: CommandFnWithOriginalFn<T>): void + + /** + * Overwrite an existing Cypress command with a new implementation + * @see https://on.cypress.io/api/commands#Overwrite-Existing-Commands + */ + overwrite<T extends keyof Chainable, S extends PrevSubject>(name: T, fn: CommandFnWithOriginalFnAndSubject<T, PrevSubjectMap[S]>): void + + /** + * Add a custom query + * @see https://on.cypress.io/api/custom-queries + */ + addQuery<T extends keyof Chainable>(name: T, fn: QueryFn<T>): void + + /** + * Overwrite an existing Cypress query with a new implementation + * @see https://on.cypress.io/api/custom-queries + */ + overwriteQuery<T extends keyof Chainable>(name: T, fn: QueryFnWithOriginalFn<T>): void + } + type CanReturnChainable = void | Chainable | Promise<unknown> type ThenReturn<S, R> = R extends void ? Chainable<S> : @@ -1742,6 +1747,16 @@ declare namespace Cypress { */ pause(options?: Partial<Loggable>): Chainable<Subject> + /** + * Send a native sequence of keyboard events: keydown & press, followed by keyup, for the provided key. + * Supported keys index the Cypress.Keyboard.Keys record. + * + * @example + * cy.press(Cypress.Keyboard.Keys.TAB) // dispatches a keydown and press event to the browser, followed by a keyup event. + * @see https://on.cypress.io/press + */ + press(key: typeof Cypress.Keyboard.Keys[keyof typeof Cypress.Keyboard.Keys], options?: Partial<Loggable & Timeoutable>): void + /** * Get the immediately preceding sibling of each element in a set of the elements. * diff --git a/cli/types/tslint.json b/cli/types/tslint.json index 017eb3c2e3f8..5e53c4842cf6 100644 --- a/cli/types/tslint.json +++ b/cli/types/tslint.json @@ -24,7 +24,9 @@ "jsdoc-format": false, // for now keep the Cypress NPM module API // in its own file for simplicity - "no-single-declare-module": false + "no-single-declare-module": false, + // This is detecting necessary qualifiers as unnecessary + "no-unnecessary-qualifier": false }, "linterOptions": { "exclude": [ diff --git a/package.json b/package.json index 668d046c7fc5..4a7d120d0e67 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cypress", - "version": "14.2.1", + "version": "14.3.0", "description": "Cypress is a next generation front end testing tool built for the modern web", "private": true, "scripts": { @@ -52,7 +52,7 @@ "sanitize:mocha:results": "node ./scripts/sanitize-mocha-results.js", "prestart": "yarn ensure-deps", "start": "cypress open --dev --global", - "stop-only": "npx stop-only --skip .cy,.publish,.projects,node_modules,dist,dist-test,fixtures,lib,bower_components,src,__snapshots__ --exclude cypress-tests.ts,*only.cy.js", + "stop-only": "npx stop-only --skip .cy,.publish,.projects,node_modules,dist,dist-test,fixtures,lib,bower_components,src,__snapshots__,patches --exclude cypress-tests.ts,*only.cy.js", "stop-only-all": "yarn stop-only --folder packages", "pretest": "yarn ensure-deps", "test": "yarn lerna exec yarn test --scope=cypress --scope=@packages/{config,data-context,driver,electron,errors,extension,https-proxy,launcher,net-stubbing,network,packherd-require,proxy,rewriter,scaffold-config,socket,v8-snapshot-require,telemetry} --scope=@tooling/{electron-mksnapshot,v8-snapshot}", @@ -187,7 +187,7 @@ "mock-fs": "5.4.0", "npm-packlist": "9.0.0", "p-defer": "^3.0.0", - "patch-package": "6.4.7", + "patch-package": "8.0.0", "playwright-webkit": "1.24.2", "pluralize": "8.0.0", "print-arch": "1.0.0", diff --git a/packages/app/cypress/e2e/cypress-in-cypress-e2e.cy.ts b/packages/app/cypress/e2e/cypress-in-cypress-e2e.cy.ts index 0921ad6ca1dc..8636836d07be 100644 --- a/packages/app/cypress/e2e/cypress-in-cypress-e2e.cy.ts +++ b/packages/app/cypress/e2e/cypress-in-cypress-e2e.cy.ts @@ -72,7 +72,9 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout: cy.get('.hook-open-in-ide').should('exist') - cy.get('#unified-runner').should('have.attr', 'style', 'width: 1000px; height: 660px; transform: scale(0.769697); position: absolute; margin-left: -25px;') + cy.get('#unified-runner').then((el) => { + expect(el[0].getAttribute('style')).to.match(/width: 1000px; height: 660px; transform: scale\(0.769\d+\); position: absolute; margin-left: -25px;/) + }) }) it('navigation between specs and other parts of the app works', () => { @@ -168,7 +170,7 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout: cy.contains('SyntaxError') .should('be.visible') .invoke('outerHeight') - .should('eq', expectedAutHeight) + .should('be.closeTo', expectedAutHeight, 1) // Checking the height here might seem excessive // but we really want some warning if this changes @@ -199,8 +201,12 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout: cy.get('.toggle-specs-wrapper').click() - cy.get('#unified-runner').should('have.css', 'width', '333px') - cy.get('#unified-runner').should('have.css', 'height', '333px') + cy.get('#unified-runner').then((el) => { + // CSS properties are calculated over inline styles, which means we get a close representation + // of the actual values, but not the exact values (+/- 1 pixel), hence the use of matching the style + // attribute. + expect(el[0].getAttribute('style')).to.match(/width: 333px; height: 333px/) + }) }) it('stops correctly running spec while switching specs', () => { @@ -208,6 +214,9 @@ describe('Cypress In Cypress E2E', { viewportWidth: 1500, defaultCommandTimeout: cy.specsPageIsVisible() cy.contains('withFailure.spec').click() cy.contains('[aria-controls=reporter-inline-specs-list]', 'Specs') + // A bit of a hack, but our cy-in-cy test needs to wait for the reporter to fully render before pressing the "f" key to expand the "Search specs" menu. + // Otherwise, the "f" keypress happens before the event is registered, which causes the "Search Specs" menu to not expand. + cy.get('[data-cy="runnable-header"]').should('be.visible') cy.get('body').type('f') cy.contains('Search specs') cy.contains('withWait.spec').click() diff --git a/packages/app/cypress/e2e/specs_list_e2e.cy.ts b/packages/app/cypress/e2e/specs_list_e2e.cy.ts index 51fbd1734f0f..e0083cea4222 100644 --- a/packages/app/cypress/e2e/specs_list_e2e.cy.ts +++ b/packages/app/cypress/e2e/specs_list_e2e.cy.ts @@ -135,6 +135,10 @@ describe('App: Spec List (E2E)', () => { cy.contains('[aria-controls=reporter-inline-specs-list]', 'Specs') cy.findByText('Your tests are loading...').should('not.be.visible') + cy.contains('[aria-controls=reporter-inline-specs-list]', 'Specs') + // A bit of a hack, but our cy-in-cy test needs to wait for the reporter to fully render before pressing the "f" key to expand the "Search specs" menu. + // Otherwise, the "f" keypress happens before the event is registered, which causes the "Search Specs" menu to not expand. + cy.get('[data-cy="runnable-header"]').should('be.visible') // open the inline spec list cy.get('body').type('f') @@ -363,6 +367,9 @@ describe('App: Spec List (E2E)', () => { cy.contains('input', targetSpecFile).should('not.exist') + // A bit of a hack, but our cy-in-cy test needs to wait for the reporter to fully render before expanding the "Search specs" menu. + // Otherwise, the click happens before the event is registered, which causes the "Search Specs" menu to not expand. + cy.get('[data-cy="runnable-header"]').should('be.visible') cy.contains('button', 'Specs').click({ force: true }) // wait until specs list is visible diff --git a/packages/app/src/runner/index.ts b/packages/app/src/runner/index.ts index 3df4950325f7..a5f810b3e647 100644 --- a/packages/app/src/runner/index.ts +++ b/packages/app/src/runner/index.ts @@ -421,6 +421,13 @@ async function executeSpec (spec: SpecFile, isRerun: boolean = false) { // initializes a bunch of listeners watches spec file for changes. await getEventManager().setup(config) + if (!_eventManager) { + // with functional react components and bridging the unified runner between Vue and React, + // we sometimes get into a state where the runner has torn down the reporter, which in turn tears down the event manager, + // while we are in the process of executing the next spec. In this case, we have a no-op execute spec and need to exit early without error. + return + } + if (window.__CYPRESS_TESTING_TYPE__ === 'e2e') { return runSpecE2E(config, spec) } diff --git a/packages/app/src/runner/reporter.ts b/packages/app/src/runner/reporter.ts index b2c88002534d..495ff90db76a 100644 --- a/packages/app/src/runner/reporter.ts +++ b/packages/app/src/runner/reporter.ts @@ -6,11 +6,19 @@ import type { EventManager } from './event-manager' import { useRunnerUiStore } from '../store/runner-ui-store' let hasInitializeReporter = false +let reactDomRoot: any = null export function setInitializedReporter (val: boolean) { hasInitializeReporter = val } +export function unmountReporter () { + if (reactDomRoot) { + reactDomRoot.unmount() + reactDomRoot = null + } +} + async function resetReporter () { if (hasInitializeReporter) { await getEventManager().resetReporter() @@ -50,7 +58,7 @@ function renderReporter ( testFilter: specsStore.testFilter, }) - const reactDomRoot = window.UnifiedRunner.ReactDOM.createRoot(root) + reactDomRoot = window.UnifiedRunner.ReactDOM.createRoot(root) reactDomRoot.render(reporter) } diff --git a/packages/app/src/runner/useEventManager.ts b/packages/app/src/runner/useEventManager.ts index 3a56d712cf20..f039b561ee6d 100644 --- a/packages/app/src/runner/useEventManager.ts +++ b/packages/app/src/runner/useEventManager.ts @@ -4,6 +4,7 @@ import { addCrossOriginIframe, getAutIframeModel, getEventManager, UnifiedRunner import { useAutStore, useSpecStore } from '../store' import { useStudioStore } from '../store/studio-store' import { empty, getReporterElement, getRunnerElement } from './utils' +import { unmountReporter } from './reporter' export function useEventManager () { const eventManager = getEventManager() @@ -85,13 +86,14 @@ export function useEventManager () { // TODO: UNIFY-1318 - this should be handled by whoever starts it, reporter? window.UnifiedRunner.shortcuts.stop() - const reporterElement = getReporterElement() if (reporterElement) { // reporter can be disabled by the user, // so sometimes will not exist to be cleaned up - empty(reporterElement) + // NOTE: we do not use empty() on the reporter as it is written in react. + // As of React 18, its better to call unmount on the root, which effectively does the same thing as empty(). + unmountReporter() } } diff --git a/packages/driver/cypress/e2e/commands/actions/press.cy.ts b/packages/driver/cypress/e2e/commands/actions/press.cy.ts index 7fc5f8694dc1..1fcf76f5257f 100644 --- a/packages/driver/cypress/e2e/commands/actions/press.cy.ts +++ b/packages/driver/cypress/e2e/commands/actions/press.cy.ts @@ -1,23 +1,21 @@ -describe('__placeholder__/commands/actions/press', () => { +describe('src/cy/commands/actions/press', () => { it('dispatches the tab keypress to the AUT', () => { - cy.visit('/fixtures/input_events.html') + // Non-BiDi firefox is not supported + if (Cypress.browser.family === 'firefox' && Cypress.browserMajorVersion() < 135) { + return + } - cy.get('#focus').focus().then(async () => { - try { - await Cypress.automation('key:press', { key: 'Tab' }) - } catch (e) { - if (e.message && (e.message as string).includes('key:press')) { - cy.log(e.message) + // TODO: Webkit is not supported. https://github.com/cypress-io/cypress/issues/31054 + if (Cypress.isBrowser('webkit')) { + return + } - return - } + cy.visit('/fixtures/input_events.html') - throw e - } + cy.press(Cypress.Keyboard.Keys.TAB) - cy.get('#keyup').should('have.value', 'Tab') + cy.get('#keydown').should('have.value', 'Tab') - cy.get('#keydown').should('have.value', 'Tab') - }) + cy.get('#keyup').should('have.value', 'Tab') }) }) diff --git a/packages/driver/cypress/e2e/e2e/origin/commands/misc.cy.ts b/packages/driver/cypress/e2e/e2e/origin/commands/misc.cy.ts index 464813e4f3d7..a58e07bda1e2 100644 --- a/packages/driver/cypress/e2e/e2e/origin/commands/misc.cy.ts +++ b/packages/driver/cypress/e2e/e2e/origin/commands/misc.cy.ts @@ -223,7 +223,7 @@ it('verifies number of cy commands', () => { 'invoke', 'its', 'getCookie', 'getCookies', 'setCookie', 'clearCookie', 'clearCookies', 'pause', 'debug', 'exec', 'readFile', 'writeFile', 'fixture', 'clearLocalStorage', 'url', 'hash', 'location', 'end', 'noop', 'log', 'wrap', 'reload', 'go', 'visit', 'focused', 'get', 'contains', 'shadow', 'within', 'request', 'session', 'screenshot', 'task', 'find', 'filter', 'not', - 'children', 'eq', 'closest', 'first', 'last', 'next', 'nextAll', 'nextUntil', 'parent', 'parents', 'parentsUntil', 'prev', + 'children', 'eq', 'closest', 'first', 'last', 'next', 'nextAll', 'nextUntil', 'parent', 'parents', 'parentsUntil', 'prev', 'press', 'prevAll', 'prevUntil', 'siblings', 'wait', 'title', 'window', 'document', 'viewport', 'server', 'route', 'intercept', 'origin', 'mount', 'as', 'root', 'getAllLocalStorage', 'clearAllLocalStorage', 'getAllSessionStorage', 'clearAllSessionStorage', 'getAllCookies', 'clearAllCookies', diff --git a/packages/driver/cypress/fixtures/input_events.html b/packages/driver/cypress/fixtures/input_events.html index 568e4d8cb021..2a23c656452a 100644 --- a/packages/driver/cypress/fixtures/input_events.html +++ b/packages/driver/cypress/fixtures/input_events.html @@ -12,7 +12,6 @@ </head> <body> - <input type="text" id="focus" /> <input type="text" id="keyup" /> <input type="text" id="keydown" /> </body> diff --git a/packages/driver/cypress/support/utils.ts b/packages/driver/cypress/support/utils.ts index d96a83a96c47..473b8afbea93 100644 --- a/packages/driver/cypress/support/utils.ts +++ b/packages/driver/cypress/support/utils.ts @@ -13,15 +13,17 @@ export const getCommandLogWithText = (command, type?) => { .closest('.command') } -export const findReactInstance = function (dom) { +// This work around is super hacky to get the appState from the Test Mobx Observable Model +// this is needed to pause the runner to assert on the test +export const findAppStateFromTest = function (dom) { let key = _.keys(dom).find((key) => key.startsWith('__reactFiber')) as string let internalInstance = dom[key] if (internalInstance == null) return null return internalInstance._debugOwner - ? internalInstance._debugOwner.stateNode - : internalInstance.return.stateNode + ? internalInstance._debugOwner.memoizedProps.model.store.appState + : internalInstance.return.memoizedProps.model.store.appState } export const clickCommandLog = (sel, type?) => { @@ -31,13 +33,17 @@ export const clickCommandLog = (sel, type?) => { .then(() => { const commandLogEl = getCommandLogWithText(sel, type) - const reactCommandInstance = findReactInstance(commandLogEl[0]) + const activeTestEl = commandLogEl[0].closest('li.test.runnable.runnable-active') - if (!reactCommandInstance) { + // We are manually manipulating the state of the appState to stop the runner. + // This does NOT happen in the wild and is only for testing purposes. + const appStateInstance = findAppStateFromTest(activeTestEl) + + if (!appStateInstance) { assert(false, 'failed to get command log React instance') } - reactCommandInstance.props.appState.isRunning = false + appStateInstance.isRunning = false const inner = $(commandLogEl).find('.command-wrapper-text') inner.get(0).click() diff --git a/packages/driver/package.json b/packages/driver/package.json index 21170ff396ed..748721e84c33 100644 --- a/packages/driver/package.json +++ b/packages/driver/package.json @@ -77,7 +77,7 @@ "methods": "1.1.2", "mime": "^3.0.0", "minimatch": "3.1.2", - "mocha": "7.1.2", + "mocha": "7.2.0", "multer": "1.4.4", "ordinal": "1.0.3", "react-15.6.1": "npm:react@15.6.1", diff --git a/packages/driver/patches/mocha+7.1.2.dev.patch b/packages/driver/patches/mocha+7.2.0.dev.patch similarity index 95% rename from packages/driver/patches/mocha+7.1.2.dev.patch rename to packages/driver/patches/mocha+7.2.0.dev.patch index fe3df2dae385..2932bd044bc0 100644 --- a/packages/driver/patches/mocha+7.1.2.dev.patch +++ b/packages/driver/patches/mocha+7.2.0.dev.patch @@ -1,9 +1,40 @@ diff --git a/node_modules/mocha/CHANGELOG.md b/node_modules/mocha/CHANGELOG.md deleted file mode 100644 -index c3b33f1..0000000 +index 71ef0fc..0000000 --- a/node_modules/mocha/CHANGELOG.md +++ /dev/null -@@ -1,634 +0,0 @@ +@@ -1,665 +0,0 @@ +-# 7.2.0 / 2020-05-22 +- +-## :tada: Enhancements +- +-- [#4234](https://github.com/mochajs/mocha/issues/4234): Add ability to run tests in a mocha instance multiple times ([**@nicojs**](https://github.com/nicojs)) +-- [#4219](https://github.com/mochajs/mocha/issues/4219): Exposing filename in JSON, doc, and json-stream reporters ([**@Daniel0113**](https://github.com/Daniel0113)) +-- [#4244](https://github.com/mochajs/mocha/issues/4244): Add Root Hook Plugins ([**@boneskull**](https://github.com/boneskull)) +- +-## :bug: Fixes +- +-- [#4258](https://github.com/mochajs/mocha/issues/4258): Fix missing dot in name of configuration file ([**@sonicdoe**](https://github.com/sonicdoe)) +-- [#4194](https://github.com/mochajs/mocha/issues/4194): Check if module.paths really exists ([**@ematipico**](https://github.com/ematipico)) +-- [#4256](https://github.com/mochajs/mocha/issues/4256): `--forbid-only` does not recognize `it.only` when `before` crashes ([**@arvidOtt**](https://github.com/arvidOtt)) +-- [#4152](https://github.com/mochajs/mocha/issues/4152): Bug with multiple async done() calls ([**@boneskull**](https://github.com/boneskull)) +-- [#4275](https://github.com/mochajs/mocha/issues/4275): Improper warnings for invalid reporters ([**@boneskull**](https://github.com/boneskull)) +-- [#4288](https://github.com/mochajs/mocha/issues/4288): Broken hook.spec.js test for IE11 ([**@boneskull**](https://github.com/boneskull)) +- +-## :book: Documentation +- +-- [#4081](https://github.com/mochajs/mocha/issues/4081): Insufficient white space for API docs in view on mobile ([**@HyunSangHan**](https://github.com/HyunSangHan)) +-- [#4255](https://github.com/mochajs/mocha/issues/4255): Update mocha-docdash for UI fixes on API docs ([**@craigtaub**](https://github.com/craigtaub)) +-- [#4235](https://github.com/mochajs/mocha/issues/4235): Enable emoji on website; enable normal ul elements ([**@boneskull**](https://github.com/boneskull)) +-- [#4272](https://github.com/mochajs/mocha/issues/4272): Fetch sponsors at build time, show ALL non-skeevy sponsors ([**@boneskull**](https://github.com/boneskull)) +- +-## :nut_and_bolt: Other +- +-- [#4249](https://github.com/mochajs/mocha/issues/4249): Refactoring improving encapsulation ([**@arvidOtt**](https://github.com/arvidOtt)) +-- [#4242](https://github.com/mochajs/mocha/issues/4242): CI add job names, add Node.js v14 to matrix ([**@boneskull**](https://github.com/boneskull)) +-- [#4237](https://github.com/mochajs/mocha/issues/4237): Refactor validatePlugins to throw coded errors ([**@boneskull**](https://github.com/boneskull)) +-- [#4236](https://github.com/mochajs/mocha/issues/4236): Better debug output ([**@boneskull**](https://github.com/boneskull)) +- -# 7.1.2 / 2020-04-26 - -## :nut_and_bolt: Other @@ -552,7 +583,7 @@ index c3b33f1..0000000 - -- [#3226](https://github.com/mochajs/mocha/issues/3226): Do not swallow errors that are thrown asynchronously from passing tests ([@boneskull](https://github.com/boneskull)). Example: - -- \```js +- \`\`\`js - it('should actually fail, sorry!', function (done) { - // passing assertion - assert(true === true); @@ -565,7 +596,7 @@ index c3b33f1..0000000 - throw new Error('chaos!'); - }, 100); - }); -- \``` +- \`\`\` - - Previously to this version, Mocha would have _silently swallowed_ the `chaos!` exception, and you wouldn't know. Well, _now you know_. Mocha cannot recover from this gracefully, so it will exit with a nonzero code. - @@ -758,12 +789,12 @@ deleted file mode 100644 index b3623a5..0000000 Binary files a/node_modules/mocha/assets/growl/ok.png and /dev/null differ diff --git a/node_modules/mocha/lib/mocha.js b/node_modules/mocha/lib/mocha.js -index 740e1fd..0cd2769 100644 +index 1983690..ee096a3 100644 --- a/node_modules/mocha/lib/mocha.js +++ b/node_modules/mocha/lib/mocha.js -@@ -904,7 +904,7 @@ Mocha.prototype.run = function(fn) { - options.files = this.files; - var runner = new exports.Runner(suite, options.delay); +@@ -1014,7 +1014,7 @@ Mocha.prototype.run = function(fn) { + cleanReferencesAfterRun: this._cleanReferencesAfterRun + }); createStatsCollector(runner); - var reporter = new this._reporter(runner, options); + var reporter = this._reporter(runner, options); @@ -771,10 +802,10 @@ index 740e1fd..0cd2769 100644 runner.fullStackTrace = options.fullTrace; runner.asyncOnly = options.asyncOnly; diff --git a/node_modules/mocha/lib/runner.js b/node_modules/mocha/lib/runner.js -index 25c03b9..f71c992 100644 +index 20a6af2..2123646 100644 --- a/node_modules/mocha/lib/runner.js +++ b/node_modules/mocha/lib/runner.js -@@ -677,9 +677,43 @@ Runner.prototype.runTests = function(suite, fn) { +@@ -755,9 +755,42 @@ Runner.prototype.runTests = function(suite, fn) { } self.emit(constants.EVENT_TEST_END, test); return self.hookUp(HOOK_TYPE_AFTER_EACH, next); @@ -814,13 +845,12 @@ index 25c03b9..f71c992 100644 + var retry = test.currentRetry(); - if (retry < test.retries()) { -+ + // requeue the test if we have retries and haven't satisfied our retry configuration. + if (retry < test.retries() && testStatusInfo.shouldAttemptsContinue) { var clonedTest = test.clone(); clonedTest.currentRetry(retry + 1); tests.unshift(clonedTest); -@@ -689,8 +723,25 @@ Runner.prototype.runTests = function(suite, fn) { +@@ -767,8 +800,25 @@ Runner.prototype.runTests = function(suite, fn) { // Early return + hook trigger so that it doesn't // increment the count wrong return self.hookUp(HOOK_TYPE_AFTER_EACH, next); diff --git a/packages/driver/src/cy/commands/actions/index.ts b/packages/driver/src/cy/commands/actions/index.ts index fe8eb2123d0d..18a11fd773e4 100644 --- a/packages/driver/src/cy/commands/actions/index.ts +++ b/packages/driver/src/cy/commands/actions/index.ts @@ -9,6 +9,7 @@ import * as Submit from './submit' import * as Type from './type' import * as Trigger from './trigger' import * as Mount from './mount' +import Press from './press' export { Check, @@ -22,4 +23,5 @@ export { Type, Trigger, Mount, + Press, } diff --git a/packages/driver/src/cy/commands/actions/press.ts b/packages/driver/src/cy/commands/actions/press.ts new file mode 100644 index 000000000000..5e96fa503264 --- /dev/null +++ b/packages/driver/src/cy/commands/actions/press.ts @@ -0,0 +1,77 @@ +import type { $Cy } from '../../../cypress/cy' +import type { StateFunc } from '../../../cypress/state' +import type { KeyPressSupportedKeys, AutomationCommands } from '@packages/types' +import { defaults } from 'lodash' +import { isSupportedKey } from '@packages/server/lib/automation/commands/key_press' +import $errUtils from '../../../cypress/error_utils' +import $utils from '../../../cypress/utils' + +export interface PressCommand { + (key: KeyPressSupportedKeys, userOptions?: Partial<Cypress.Loggable> & Partial<Cypress.Timeoutable>): void +} + +export default function (Commands: Cypress.Commands, Cypress: Cypress.Cypress, cy: $Cy, state: StateFunc, config: any) { + async function pressCommand (key: KeyPressSupportedKeys, userOptions?: Partial<Cypress.Loggable> & Partial<Cypress.Timeoutable>) { + const options: Cypress.Loggable & Partial<Cypress.Timeoutable> = defaults({}, userOptions, { + log: true, + }) + const deltaOptions = $utils.filterOutOptions(options) + + const log = Cypress.log({ + timeout: options.timeout, + hidden: options.log === false, + message: [key, deltaOptions], + consoleProps () { + return { + 'Key': key, + } + }, + }) + + if (!isSupportedKey(key)) { + $errUtils.throwErrByPath('press.invalid_key', { + onFail: log, + args: { key }, + }) + + // throwErrByPath always throws, but there's no way to indicate that + // code beyond this point is unreachable to typescript / linters + return + } + + if (Cypress.browser.family === 'webkit') { + $errUtils.throwErrByPath('press.unsupported_browser', { + onFail: log, + args: { + family: Cypress.browser.family, + }, + }) + + return + } + + if (Cypress.browser.name === 'firefox' && Number(Cypress.browser.majorVersion) < 135) { + $errUtils.throwErrByPath('press.unsupported_browser_version', { + onFail: log, + args: { + browser: Cypress.browser.name, + version: Cypress.browser.majorVersion, + minimumVersion: 135, + }, + }) + } + + try { + const command: 'key:press' = 'key:press' + const args: AutomationCommands[typeof command]['dataType'] = { + key, + } + + await Cypress.automation('key:press', args) + } catch (err) { + $errUtils.throwErr(err, { onFail: log }) + } + } + + return Commands.add('press', pressCommand) +} diff --git a/packages/driver/src/cy/commands/sessions/index.ts b/packages/driver/src/cy/commands/sessions/index.ts index 8c116c8870ed..3a72d0f98e10 100644 --- a/packages/driver/src/cy/commands/sessions/index.ts +++ b/packages/driver/src/cy/commands/sessions/index.ts @@ -57,7 +57,7 @@ export default function (Commands, Cypress, cy) { } // stringify deterministically if we were given an object - id = _.isString(id) ? id : stringifyStable(id) + id = _.isString(id) ? id : stringifyStable(id) as string if (!setup || !_.isFunction(setup)) { $errUtils.throwErrByPath('sessions.session.wrongArgSetup') @@ -92,7 +92,7 @@ export default function (Commands, Cypress, cy) { }) } - let session: Cypress.SessionData = sessionsManager.getActiveSession(id) + let session: Cypress.SessionData = sessionsManager.getActiveSession(id as string) const isRegisteredSessionForSpec = sessionsManager.registeredSessions.has(id) if (session) { diff --git a/packages/driver/src/cy/keyboard.ts b/packages/driver/src/cy/keyboard.ts index fbeb454fe78d..3256d9f951c2 100644 --- a/packages/driver/src/cy/keyboard.ts +++ b/packages/driver/src/cy/keyboard.ts @@ -14,6 +14,7 @@ import $utils from '../cypress/utils' import $window from '../dom/window' import type { Log } from '../cypress/log' import type { StateFunc } from '../cypress/state' +import type { KeyPressSupportedKeys } from '@packages/types' const debug = Debug('cypress:driver:keyboard') @@ -1397,6 +1398,10 @@ const defaults = (props: Partial<Cypress.KeyboardDefaultsOptions>) => { return getConfig() } +const Keys: Record<string, KeyPressSupportedKeys> = { + TAB: 'Tab', +} + export default { defaults, getConfig, @@ -1405,4 +1410,5 @@ export default { reset, toModifiersEventOptions, fromModifierEventOptions, + Keys, } diff --git a/packages/driver/src/cypress.ts b/packages/driver/src/cypress.ts index ea62efa511a6..c8657904fae7 100644 --- a/packages/driver/src/cypress.ts +++ b/packages/driver/src/cypress.ts @@ -348,6 +348,7 @@ class $Cypress { this.downloads = $Downloads.create(this) // wire up command create to cy + // @ts-expect-error this.Commands = $Commands.create(this, this.cy, this.state, this.config) this.events.proxyTo(this.cy) diff --git a/packages/driver/src/cypress/commands.ts b/packages/driver/src/cypress/commands.ts index 36bf924f3085..9039c1186d7f 100644 --- a/packages/driver/src/cypress/commands.ts +++ b/packages/driver/src/cypress/commands.ts @@ -3,7 +3,7 @@ import { allCommands } from '../cy/commands' import { addCommand as addNetstubbingCommand } from '../cy/net-stubbing' import $errUtils from './error_utils' import $stackUtils from './stack_utils' - +import type { $Cy } from './cy' import type { QueryFunction } from './state' const PLACEHOLDER_COMMANDS = ['mount', 'hover'] @@ -40,7 +40,7 @@ const internalError = (path, args) => { } export default { - create: (Cypress, cy, state, config) => { + create: (Cypress: Cypress.Cypress, cy: $Cy, state, config) => { const reservedCommandNames = new Set(Object.keys(cy)) const commands = {} const queries = {} @@ -63,11 +63,11 @@ export default { return null }, - addSync (name, fn) { + addSync (name: string, fn: (...args: any[]) => any) { return cy.addCommandSync(name, fn) }, - addAll (options = {}, obj) { + addAll (options, obj) { if (!obj) { obj = options options = {} diff --git a/packages/driver/src/cypress/error_messages.ts b/packages/driver/src/cypress/error_messages.ts index 34e998fe8d6b..a82d7a419084 100644 --- a/packages/driver/src/cypress/error_messages.ts +++ b/packages/driver/src/cypress/error_messages.ts @@ -1310,6 +1310,18 @@ export default { }, }, + press: { + invalid_key: stripIndent`\ + \`{{key}}\` is not supported by ${cmd('press')}. See \`Cypress.Keyboard.Keys\` for keys that are supported. + `, + unsupported_browser_version: stripIndent`\ + ${cmd('press')} is not supported in {{browser}} version {{version}}. Upgrade to version {{minimumVersion}} to use \`cy.press()\`. + `, + unsupported_browser: stripIndent`\ + ${cmd('press')} is not supported in {{family}} browsers. + `, + }, + proxy: { js_rewriting_failed: stripIndent`\ An error occurred in the Cypress proxy layer while rewriting your source code. This is a bug in Cypress. Open an issue if you see this message. diff --git a/packages/driver/src/cypress/source_map_utils.ts b/packages/driver/src/cypress/source_map_utils.ts index 035e4db11dd2..a6a5b2f31b91 100644 --- a/packages/driver/src/cypress/source_map_utils.ts +++ b/packages/driver/src/cypress/source_map_utils.ts @@ -6,7 +6,7 @@ import type { BasicSourceMapConsumer } from 'source-map' import mappingsWasm from 'source-map/lib/mappings.wasm' import $utils from './utils' -import stackUtils from './stack_utils' +import { toPosix } from './util/to_posix' const sourceMapExtractionRegex = /\/\/\s*[@#]\s*sourceMappingURL\s*=\s*(data:[^\s]*)/g const regexDataUrl = /data:[^;\n]+(?:;charset=[^;\n]+)?;base64,([a-zA-Z0-9+/]+={0,2})/ // matches data urls @@ -23,7 +23,7 @@ const initializeSourceMapConsumer = async (script, sourceMap): Promise<BasicSour const consumer = await new SourceMapConsumer(sourceMap) - sourceMapConsumers[stackUtils.toPosix(script.fullyQualifiedUrl)] = consumer + sourceMapConsumers[toPosix(script.fullyQualifiedUrl)] = consumer return consumer } @@ -56,7 +56,7 @@ const extractSourceMap = (fileContents) => { } const getSourceContents = (filePath, sourceFile) => { - const posixFilePath = stackUtils.toPosix(filePath) + const posixFilePath = toPosix(filePath) if (!sourceMapConsumers[posixFilePath]) return null @@ -72,7 +72,7 @@ const getSourceContents = (filePath, sourceFile) => { } const getSourcePosition = (filePath, position) => { - const posixFilePath = stackUtils.toPosix(filePath) + const posixFilePath = toPosix(filePath) const sourceMapConsumer = sourceMapConsumers[posixFilePath] if (!sourceMapConsumer) return null diff --git a/packages/driver/src/cypress/stack_utils.ts b/packages/driver/src/cypress/stack_utils.ts index 3da82879709f..ae4875a4eaf0 100644 --- a/packages/driver/src/cypress/stack_utils.ts +++ b/packages/driver/src/cypress/stack_utils.ts @@ -15,7 +15,7 @@ import { codeFrameColumns } from '@babel/code-frame' import $utils from './utils' import $sourceMapUtils from './source_map_utils' - +import { toPosix } from './util/to_posix' // Intentionally deep-importing from @packages/errors so as to not bundle the entire @packages/errors in the client unnecessarily import { getStackLines, replacedStack, stackWithoutMessage, splitStack, unsplitStack, stackLineRegex } from '@packages/errors/src/stackUtils' @@ -184,12 +184,6 @@ const getCodeFrameFromSource = (sourceCode, { line, column: originalColumn, rela } } -export const toPosix = (file: string) => { - return Cypress.config('platform') === 'win32' - ? file.replaceAll('\\', '/') - : file -} - const getRelativePathFromRoot = (relativeFile: string, absoluteFile?: string) => { // at this point relativeFile is relative to the cypress config // we need it to be relative to the repo root, which is different for monorepos @@ -549,5 +543,4 @@ export default { stackWithUserInvocationStackSpliced, captureUserInvocationStack, getInvocationDetails, - toPosix, } diff --git a/packages/driver/src/cypress/util/to_posix.ts b/packages/driver/src/cypress/util/to_posix.ts new file mode 100644 index 000000000000..4361abd46bee --- /dev/null +++ b/packages/driver/src/cypress/util/to_posix.ts @@ -0,0 +1,5 @@ +export const toPosix = (file: string) => { + return Cypress.config('platform') === 'win32' + ? file.replaceAll('\\', '/') + : file +} diff --git a/packages/driver/test/__setup__/setupMocks.ts b/packages/driver/test/__setup__/setupMocks.ts new file mode 100644 index 000000000000..282cd6cf1507 --- /dev/null +++ b/packages/driver/test/__setup__/setupMocks.ts @@ -0,0 +1,11 @@ +import { vi } from 'vitest' +import type sourceMapUtils from '../../src/cypress/source_map_utils' + +// This is mocked in the setup file because vitest chokes on loading the .wasm file +// from the 'source-map' module. A solution to that should be found before unit testing +// source_map_utils. +vi.mock('../../src/cypress/source_map_utils', () => { + return { + getSourcePosition: vi.fn<typeof sourceMapUtils.getSourcePosition>(), + } +}) diff --git a/packages/driver/test/unit/cy/commands/actions/press.spec.ts b/packages/driver/test/unit/cy/commands/actions/press.spec.ts new file mode 100644 index 000000000000..2e77adae79f2 --- /dev/null +++ b/packages/driver/test/unit/cy/commands/actions/press.spec.ts @@ -0,0 +1,187 @@ +/** + * @vitest-environment jsdom + */ +import { vi, describe, it, expect, beforeEach, Mock, MockedObject } from 'vitest' +import type { KeyPressSupportedKeys } from '@packages/types' +import addCommand, { PressCommand } from '../../../../../src/cy/commands/actions/press' +import type { $Cy } from '../../../../../src/cypress/cy' +import type { StateFunc } from '../../../../../src/cypress/state' +import $errUtils from '../../../../../src/cypress/error_utils' +import Keyboard from '../../../../../src/cy/keyboard' + +vi.mock('../../../../../src/cypress/error_utils', async () => { + const original = await vi.importActual('../../../../../src/cypress/error_utils') + + return { + default: { + // @ts-expect-error + ...original.default, + // @ts-expect-error + throwErr: vi.fn().mockImplementation(original.default.throwErr), + // @ts-expect-error + throwErrByPath: vi.fn().mockImplementation(original.default.throwErrByPath), + }, + } +}) + +describe('cy/commands/actions/press', () => { + let log: Mock<typeof Cypress['log']> + let automation: Mock<typeof Cypress['automation']> + let press: PressCommand + let Cypress: MockedObject<Cypress.Cypress> + let Commands: MockedObject<Cypress.Commands> + let cy: MockedObject<$Cy> + let state: MockedObject<StateFunc> + let config: any + let logReturnValue: Cypress.Log + + beforeEach(() => { + log = vi.fn<typeof Cypress['log']>() + automation = vi.fn<typeof Cypress['automation']>() + + Cypress = { + // The overloads for `log` don't get applied correctly here + // @ts-expect-error + log, + automation, + // @ts-expect-error + browser: { + family: 'chromium', + name: 'Chrome', + }, + } + + // @ts-expect-error - this is a generic mock impl + Commands = { + add: vi.fn(), + } + + // @ts-expect-error + cy = {} + + state = { + ...vi.fn<StateFunc>(), + // @ts-expect-error - this is a recursive definition, so we're only defining the mock one level deep + state: vi.fn<StateFunc>(), + reset: vi.fn<() => Record<string, any>>(), + } + + config = {} + + logReturnValue = { + id: 'log_id', + end: vi.fn(), + error: vi.fn(), + finish: vi.fn(), + get: vi.fn(), + set: vi.fn(), + snapshot: vi.fn(), + _hasInitiallyLogged: false, + groupEnd: vi.fn(), + } + + Cypress.log.mockReturnValue(logReturnValue) + + addCommand(Commands, Cypress, cy, state, config) + + expect(Commands.add).toHaveBeenCalledOnce() + + // @ts-expect-error + const [[cmdName, cmd]]: [[string, PressCommand]] = Commands.add.mock.calls + + expect(cmdName).toEqual('press') + + press = cmd as PressCommand + }) + + describe('with a valid key', () => { + const key: KeyPressSupportedKeys = Keyboard.Keys.TAB + + it('dispatches a key:press automation command', async () => { + await press(key) + expect(automation).toHaveBeenCalledWith('key:press', { key }) + }) + + describe('with options', () => { + let options: Cypress.Loggable & Cypress.Timeoutable + + beforeEach(() => { + options = { + log: false, + timeout: 2000, + } + }) + + it('sets timeout and hidden on the log', async () => { + await press(key, options) + expect(Cypress.log).toBeCalledWith({ + timeout: options.timeout, + hidden: true, + message: [key, { timeout: 2000 }], + consoleProps: expect.any(Function), + }) + }) + }) + }) + + describe('with an invalid key', () => { + it('throws an invalid key error', async () => { + // @ts-expect-error + const key: KeyPressSupportedKeys = 'Foo' + + await expect(press(key)).rejects.toThrow(`\`${key}\` is not supported by \`cy.press()\``) + expect($errUtils.throwErrByPath).toHaveBeenCalledWith('press.invalid_key', { + onFail: logReturnValue, + args: { + key, + }, + }) + }) + }) + + describe('when in webkit', () => { + it('throws an unsupported browser error', async () => { + Cypress.browser.family = 'webkit' + await expect(press('Tab')).rejects.toThrow('`cy.press()` is not supported in webkit browsers.') + expect($errUtils.throwErrByPath).toHaveBeenCalledWith('press.unsupported_browser', { + onFail: logReturnValue, + args: { + family: Cypress.browser.family, + }, + }) + }) + }) + + describe('when in firefox below 135', () => { + it('throws an unsupported browser version error', async () => { + Cypress.browser.name = 'firefox' + Cypress.browser.majorVersion = '134' + await expect(press('Tab')).rejects.toThrow('`cy.press()` is not supported in firefox version 134. Upgrade to version 135 to use `cy.press()`.') + + expect($errUtils.throwErrByPath).toHaveBeenCalledWith('press.unsupported_browser_version', { + onFail: logReturnValue, + args: { + browser: Cypress.browser.name, + version: Cypress.browser.majorVersion, + minimumVersion: 135, + }, + }) + }) + }) + + describe('when automation throws', () => { + it('throws via $errUtils, passing in the results from Cypress.log', async () => { + const thrown = new Error('Some error') + + // @ts-expect-error async is not bluebird, but that's fine + Cypress.automation.mockImplementation(async () => { + throw thrown + }) + + await expect(press('Tab')).rejects.toThrow(thrown) + expect($errUtils.throwErr).toHaveBeenCalledWith(thrown, { + onFail: logReturnValue, + }) + }) + }) +}) diff --git a/packages/driver/test/unit/cypress/util/toPosix.spec.ts b/packages/driver/test/unit/cypress/util/toPosix.spec.ts new file mode 100644 index 000000000000..b1c76f821471 --- /dev/null +++ b/packages/driver/test/unit/cypress/util/toPosix.spec.ts @@ -0,0 +1,40 @@ +/** + * @vitest-environment jsdom + */ + +import { vi, describe, it, expect, beforeEach, MockedFunction } from 'vitest' + +import { toPosix } from '../../../../src/cypress/util/to_posix' + +describe('toPosix', () => { + let config: MockedFunction<any> + + beforeEach(() => { + config = vi.fn() + + // @ts-expect-error + global.Cypress = { + config, + } + }) + + describe('on windows', () => { + beforeEach(() => { + config.mockReturnValue('win32') + }) + + it('replaces backslashes with forward slashes', () => { + expect(toPosix('C:\\some\\file')).toEqual('C:/some/file') + }) + }) + + describe(`on other OS'`, () => { + beforeEach(() => { + config.mockReturnValue('darwin64') + }) + + it('performs as an identity function', () => { + expect(toPosix('/some/file')).toEqual('/some/file') + }) + }) +}) diff --git a/packages/driver/types/internal-types.d.ts b/packages/driver/types/internal-types.d.ts index 8c9a5c32bfee..a190a2a8e60c 100644 --- a/packages/driver/types/internal-types.d.ts +++ b/packages/driver/types/internal-types.d.ts @@ -31,6 +31,9 @@ interface InternalCheckOptions extends Partial<Cypress.CheckClearOptions> { interface InternalKeyboard extends Partial<Keyboard> { getMap: () => object reset: () => void + Keys: { + TAB: 'Tab' + } } declare namespace Cypress { diff --git a/packages/driver/vitest.config.mjs b/packages/driver/vitest.config.mjs index 0549d3593ad6..3f8f02a7a2d8 100644 --- a/packages/driver/vitest.config.mjs +++ b/packages/driver/vitest.config.mjs @@ -5,6 +5,7 @@ export default defineConfig({ include: ['test/unit/**/*.spec.ts'], environment: 'jsdom', exclude: ['**/__fixtures__/**/*'], + setupFiles: 'test/__setup__/setupMocks.ts', reporters: [ 'default', ['junit', { suiteName: 'Driver Unit Tests', outputFile: '/tmp/cypress/junit/driver-test-results.xml' }], diff --git a/packages/frontend-shared/package.json b/packages/frontend-shared/package.json index 69d8ac1b5586..c936939929fd 100644 --- a/packages/frontend-shared/package.json +++ b/packages/frontend-shared/package.json @@ -90,7 +90,7 @@ "markdown-it": "13.0.1", "modern-normalize": "1.1.0", "p-defer": "^3.0.0", - "patch-package": "6.4.7", + "patch-package": "8.0.0", "postcss": "^8.4.22", "shiki": "^0.9.12", "sinon": "13.0.2", diff --git a/packages/reporter/cypress/e2e/agents.cy.ts b/packages/reporter/cypress/e2e/agents.cy.ts index 5a11678763b5..afc1e6ce0e38 100644 --- a/packages/reporter/cypress/e2e/agents.cy.ts +++ b/packages/reporter/cypress/e2e/agents.cy.ts @@ -27,7 +27,7 @@ describe('agents', () => { }) start = () => { - cy.get('.reporter').then(() => { + cy.get('.reporter.mounted').then(() => { runner.emit('runnables:ready', runnables) runner.emit('reporter:start', {}) }) diff --git a/packages/reporter/cypress/e2e/aliases.cy.ts b/packages/reporter/cypress/e2e/aliases.cy.ts index 370b53421335..c6b61a2f1a09 100644 --- a/packages/reporter/cypress/e2e/aliases.cy.ts +++ b/packages/reporter/cypress/e2e/aliases.cy.ts @@ -26,7 +26,7 @@ describe('aliases', () => { }) }) - cy.get('.reporter').then(() => { + cy.get('.reporter.mounted').then(() => { runner.emit('runnables:ready', runnables) runner.emit('reporter:start', {}) }) diff --git a/packages/reporter/cypress/e2e/commands.cy.ts b/packages/reporter/cypress/e2e/commands.cy.ts index 3b793d02e54e..ce0267afb0ad 100644 --- a/packages/reporter/cypress/e2e/commands.cy.ts +++ b/packages/reporter/cypress/e2e/commands.cy.ts @@ -27,7 +27,7 @@ describe('commands', { viewportHeight: 1000 }, () => { }) }) - cy.get('.reporter').then(() => { + cy.get('.reporter.mounted').then(() => { runner.emit('runnables:ready', runnables) runner.emit('reporter:start', {}) addCommand(runner, { diff --git a/packages/reporter/cypress/e2e/header.cy.ts b/packages/reporter/cypress/e2e/header.cy.ts index 6f057d33ca52..4e4c8cc1b2d5 100755 --- a/packages/reporter/cypress/e2e/header.cy.ts +++ b/packages/reporter/cypress/e2e/header.cy.ts @@ -32,7 +32,7 @@ describe('header', () => { }) }) - cy.get('.reporter').then(() => { + cy.get('.reporter.mounted').then(() => { runner.emit('runnables:ready', { ...runnables, testFilter: opts?.testFilter, totalUnfilteredTests: opts?.totalUnfilteredTests }) runner.emit('reporter:start', {}) }) diff --git a/packages/reporter/cypress/e2e/hooks.cy.ts b/packages/reporter/cypress/e2e/hooks.cy.ts index 8e5e95b50cf8..62e37ff4c126 100644 --- a/packages/reporter/cypress/e2e/hooks.cy.ts +++ b/packages/reporter/cypress/e2e/hooks.cy.ts @@ -26,7 +26,7 @@ describe('hooks', () => { }) }) - cy.get('.reporter').then(() => { + cy.get('.reporter.mounted').then(() => { runner.emit('runnables:ready', runnables) runner.emit('reporter:start', {}) }) diff --git a/packages/reporter/cypress/e2e/memory.cy.ts b/packages/reporter/cypress/e2e/memory.cy.ts index 0e11fc21e462..a14903235f47 100644 --- a/packages/reporter/cypress/e2e/memory.cy.ts +++ b/packages/reporter/cypress/e2e/memory.cy.ts @@ -29,7 +29,7 @@ function visitAndRenderReporter (studioEnabled: boolean = false, studioActive: b }) }) - cy.get('.reporter').then(() => { + cy.get('.reporter.mounted').then(() => { runner.emit('runnables:ready', runnables) runner.emit('reporter:start', { studioActive }) }) diff --git a/packages/reporter/cypress/e2e/routes.cy.ts b/packages/reporter/cypress/e2e/routes.cy.ts index 5fbd7796df22..587adb018718 100644 --- a/packages/reporter/cypress/e2e/routes.cy.ts +++ b/packages/reporter/cypress/e2e/routes.cy.ts @@ -27,7 +27,7 @@ describe('routes', () => { }) start = () => { - cy.get('.reporter').then(() => { + cy.get('.reporter.mounted').then(() => { runner.emit('runnables:ready', runnables) runner.emit('reporter:start', {}) }) diff --git a/packages/reporter/cypress/e2e/runnables.cy.ts b/packages/reporter/cypress/e2e/runnables.cy.ts index 93fd70651b42..eb108faa239d 100644 --- a/packages/reporter/cypress/e2e/runnables.cy.ts +++ b/packages/reporter/cypress/e2e/runnables.cy.ts @@ -45,7 +45,7 @@ describe('runnables', () => { start = (renderProps?: Partial<BaseReporterProps>) => { render(renderProps) - return cy.get('.reporter').then(() => { + return cy.get('.reporter.mounted').then(() => { runner.emit('runnables:ready', runnables) runner.emit('reporter:start', {}) }) diff --git a/packages/reporter/cypress/e2e/shortcuts.cy.ts b/packages/reporter/cypress/e2e/shortcuts.cy.ts index 0c1d152dcaec..4ada861cb4ff 100755 --- a/packages/reporter/cypress/e2e/shortcuts.cy.ts +++ b/packages/reporter/cypress/e2e/shortcuts.cy.ts @@ -36,7 +36,7 @@ describe('shortcuts', function () { }) }) - cy.get('.reporter').then(() => { + cy.get('.reporter.mounted').then(() => { runner.emit('runnables:ready', this.runnables) runner.emit('reporter:start', {}) }) diff --git a/packages/reporter/cypress/e2e/spec_title.cy.ts b/packages/reporter/cypress/e2e/spec_title.cy.ts index 07520189a102..51f89915d69c 100644 --- a/packages/reporter/cypress/e2e/spec_title.cy.ts +++ b/packages/reporter/cypress/e2e/spec_title.cy.ts @@ -13,7 +13,7 @@ describe('spec title', () => { win.render({ runner, runnerStore: { spec } }) }) - cy.get('.reporter').then(() => { + cy.get('.reporter.mounted').then(() => { runner.emit('runnables:ready', {}) runner.emit('reporter:start', {}) }) diff --git a/packages/reporter/cypress/e2e/suites.cy.ts b/packages/reporter/cypress/e2e/suites.cy.ts index fc3ce4972452..ba91185ab3e7 100644 --- a/packages/reporter/cypress/e2e/suites.cy.ts +++ b/packages/reporter/cypress/e2e/suites.cy.ts @@ -29,7 +29,7 @@ describe('suites', () => { }) }) - cy.get('.reporter').then(() => { + cy.get('.reporter.mounted').then(() => { runner.emit('runnables:ready', runnables) runner.emit('reporter:start', {}) }) diff --git a/packages/reporter/cypress/e2e/test_errors.cy.ts b/packages/reporter/cypress/e2e/test_errors.cy.ts index f9a6ad35b3df..a9f797e01e39 100644 --- a/packages/reporter/cypress/e2e/test_errors.cy.ts +++ b/packages/reporter/cypress/e2e/test_errors.cy.ts @@ -20,7 +20,7 @@ describe('test errors', () => { // @ts-ignore runnablesWithErr.suites[0].tests[0].err = err - cy.get('.reporter').then(() => { + cy.get('.reporter.mounted').then(() => { runner.emit('runnables:ready', runnablesWithErr) runner.emit('reporter:start', {}) }) diff --git a/packages/reporter/cypress/e2e/tests.cy.ts b/packages/reporter/cypress/e2e/tests.cy.ts index bb5081ccbaf4..b1ba923e33fa 100644 --- a/packages/reporter/cypress/e2e/tests.cy.ts +++ b/packages/reporter/cypress/e2e/tests.cy.ts @@ -28,7 +28,7 @@ function visitAndRenderReporter (studioEnabled: boolean = false, studioActive: b }) }) - cy.get('.reporter').then(() => { + cy.get('.reporter.mounted').then(() => { runner.emit('runnables:ready', runnables) runner.emit('reporter:start', { studioActive }) }) diff --git a/packages/reporter/src/attempts/attempt-model.ts b/packages/reporter/src/attempts/attempt-model.ts index 5367b51c804a..674640b1ab8c 100644 --- a/packages/reporter/src/attempts/attempt-model.ts +++ b/packages/reporter/src/attempts/attempt-model.ts @@ -200,6 +200,10 @@ export default class Attempt { } } + @action setIsOpen (isOpen: boolean) { + this._isOpen = isOpen + } + @action finish (props: UpdatableTestProps, isInteractive: boolean) { this.update(props) this.isActive = false diff --git a/packages/reporter/src/attempts/attempts.tsx b/packages/reporter/src/attempts/attempts.tsx index a1b974872986..09502ff9514b 100644 --- a/packages/reporter/src/attempts/attempts.tsx +++ b/packages/reporter/src/attempts/attempts.tsx @@ -1,6 +1,6 @@ import cs from 'classnames' import { observer } from 'mobx-react' -import React, { Component } from 'react' +import React, { useEffect, useState } from 'react' import type { TestState } from '@packages/types' import Agents from '../agents/agents' @@ -35,73 +35,62 @@ const AttemptHeader = ({ index, state }: {index: number, state: TestState }) => </span> ) -const StudioError = () => ( - <div className='runnable-err-wrapper studio-err-wrapper'> - <div className='runnable-err'> - <div className='runnable-err-message'> - Studio cannot add commands to a failing test. - </div> - </div> - </div> -) - -function renderAttemptContent (model: AttemptModel, studioActive: boolean) { - // performance optimization - don't render contents if not open - return ( - <div className={`attempt-${model.id + 1}`}> - <Sessions model={model.sessions} /> - <Agents model={model} /> - <Routes model={model} /> - <div ref='commands' className='runnable-commands-region'> - {model.hasCommands ? <Hooks model={model} /> : <NoCommands />} - </div> - {model.state === 'failed' && ( - <div className='attempt-error-region'> - <TestError {...model.error} /> - {studioActive && <StudioError />} - </div> - )} - </div> - ) -} - interface AttemptProps { model: AttemptModel scrollIntoView: Function studioActive: boolean } -@observer -class Attempt extends Component<AttemptProps> { - componentDidUpdate () { - this.props.scrollIntoView() - } +const Attempt: React.FC<AttemptProps> = observer(({ model, scrollIntoView, studioActive }) => { + const [isMounted, setIsMounted] = useState(false) - render () { - const { model, studioActive } = this.props + useEffect(() => { + if (isMounted) { + scrollIntoView() + } else { + setIsMounted(true) + } + }) - // HACK: causes component update when command log is added - model.commands.length - - return ( - <li - key={model.id} - className={cs('attempt-item', `attempt-state-${model.state}`)} - ref="container" + return ( + <li + key={model.id} + className={cs('attempt-item', `attempt-state-${model.state}`)} + > + <Collapsible + header={<AttemptHeader index={model.id} state={model.state} />} + hideExpander + headerClass='attempt-name' + contentClass='attempt-content' + isOpen={model.isOpen} + onOpenStateChangeRequested={(isOpen: boolean) => model.setIsOpen(isOpen)} > - <Collapsible - header={<AttemptHeader index={model.id} state={model.state} />} - hideExpander - headerClass='attempt-name' - contentClass='attempt-content' - isOpen={model.isOpen} - > - {renderAttemptContent(model, studioActive)} - </Collapsible> - </li> - ) - } -} + <div className={`attempt-${model.id + 1}`}> + <Sessions model={model.sessions} /> + <Agents model={model} /> + <Routes model={model} /> + <div className='runnable-commands-region'> + {model.hasCommands ? <Hooks model={model} /> : <NoCommands />} + </div> + {model.state === 'failed' && ( + <div className='attempt-error-region'> + <TestError {...model.error} /> + {studioActive && ( + <div className='runnable-err-wrapper studio-err-wrapper'> + <div className='runnable-err'> + <div className='runnable-err-message'> + Studio cannot add commands to a failing test. + </div> + </div> + </div> + )} + </div> + )} + </div> + </Collapsible> + </li> + ) +}) const Attempts = observer(({ test, scrollIntoView, studioActive }: {test: TestModel, scrollIntoView: Function, studioActive: boolean}) => { return (<ul className={cs('attempts', { diff --git a/packages/reporter/src/collapsible/collapsible.tsx b/packages/reporter/src/collapsible/collapsible.tsx index da688e58403e..7c2125a13207 100644 --- a/packages/reporter/src/collapsible/collapsible.tsx +++ b/packages/reporter/src/collapsible/collapsible.tsx @@ -1,11 +1,9 @@ import cs from 'classnames' -import React, { Component, CSSProperties, MouseEvent, ReactNode, RefObject } from 'react' - +import React, { CSSProperties, MouseEvent, ReactNode, RefObject, useCallback, useState } from 'react' import { onEnterOrSpace } from '../lib/util' - import ChevronIcon from '@packages/frontend-shared/src/assets/icons/chevron-down-small_x8.svg' -interface Props { +interface CollapsibleProps { isOpen?: boolean headerClass?: string headerStyle?: CSSProperties @@ -13,81 +11,56 @@ interface Props { headerExtras?: ReactNode containerRef?: RefObject<HTMLDivElement> contentClass?: string - hideExpander: boolean + hideExpander?: boolean children?: ReactNode + onOpenStateChangeRequested?: (isOpen: boolean) => void } -interface State { - isOpen: boolean -} - -class Collapsible extends Component<Props, State> { - static defaultProps = { - isOpen: false, - headerClass: '', - headerStyle: {}, - contentClass: '', - hideExpander: false, - } - - constructor (props: Props) { - super(props) - - this.state = { isOpen: props.isOpen || false } - } +const Collapsible: React.FC<CollapsibleProps> = ({ isOpen: isOpenAsProp = false, header, headerClass = '', headerStyle = {}, headerExtras, contentClass = '', hideExpander = false, containerRef = null, onOpenStateChangeRequested, children }) => { + const [isOpenState, setIsOpenState] = useState(isOpenAsProp) - componentDidUpdate (prevProps: Props) { - if (this.props.isOpen != null && this.props.isOpen !== prevProps.isOpen) { - this.setState({ isOpen: this.props.isOpen }) + const toggleOpenState = useCallback((e?: MouseEvent) => { + e?.stopPropagation() + if (onOpenStateChangeRequested) { + onOpenStateChangeRequested(!isOpen) + } else { + setIsOpenState(!isOpen) } - } + }, [isOpenState, onOpenStateChangeRequested]) - render () { - return ( - <div className={cs('collapsible', { 'is-open': this.state.isOpen })} ref={this.props.containerRef}> - <div className={cs('collapsible-header-wrapper', this.props.headerClass)}> + const isOpen = onOpenStateChangeRequested ? isOpenAsProp : isOpenState + + return ( + <div className={cs('collapsible', { 'is-open': isOpen })} ref={containerRef}> + <div className={cs('collapsible-header-wrapper', headerClass)}> + <div + aria-expanded={isOpen} + className='collapsible-header' + onClick={toggleOpenState} + onKeyUp={onEnterOrSpace(toggleOpenState)} + role='button' + tabIndex={0} + > <div - aria-expanded={this.state.isOpen} - className='collapsible-header' - onClick={this._onClick} - onKeyPress={onEnterOrSpace(this._onKeyPress)} - role='button' - tabIndex={0} + className='collapsible-header-inner' + style={headerStyle} + tabIndex={-1} > - <div - className='collapsible-header-inner' - style={this.props.headerStyle} - tabIndex={-1} - > - {!this.props.hideExpander && <ChevronIcon className='collapsible-indicator' />} - <span className='collapsible-header-text'> - {this.props.header} - </span> - </div> + {!hideExpander && <ChevronIcon className='collapsible-indicator' />} + <span className='collapsible-header-text'> + {header} + </span> </div> - {this.props.headerExtras} </div> - {this.state.isOpen && ( - <div className={cs('collapsible-content', this.props.contentClass)}> - {this.props.children} - </div> - )} + {headerExtras} </div> - ) - } - - _toggleOpen = () => { - this.setState({ isOpen: !this.state.isOpen }) - } - - _onClick = (e: MouseEvent) => { - e.stopPropagation() - this._toggleOpen() - } - - _onKeyPress = () => { - this._toggleOpen() - } + {isOpen && ( + <div className={cs('collapsible-content', contentClass)}> + {children} + </div> + )} + </div> + ) } export default Collapsible diff --git a/packages/reporter/src/commands/command.tsx b/packages/reporter/src/commands/command.tsx index d518fddcd715..4bc8c883b8fb 100644 --- a/packages/reporter/src/commands/command.tsx +++ b/packages/reporter/src/commands/command.tsx @@ -1,18 +1,17 @@ import _ from 'lodash' import cs from 'classnames' import Markdown from 'markdown-it' -import { action, observable, makeObservable } from 'mobx' import { observer } from 'mobx-react' -import React, { Component } from 'react' +import React, { useCallback, useState } from 'react' import Tooltip from '@cypress/react-tooltip' -import appState, { AppState } from '../lib/app-state' -import events, { Events } from '../lib/events' +import appState from '../lib/app-state' +import events from '../lib/events' import FlashOnClick from '../lib/flash-on-click' import StateIcon from '../lib/state-icon' import Tag from '../lib/tag' import type { TimeoutID } from '../lib/types' -import runnablesStore, { RunnablesStore } from '../runnables/runnables-store' +import runnablesStore from '../runnables/runnables-store' import type { Alias, AliasObject } from '../instruments/instrument-model' import { determineTagType } from '../sessions/utils' @@ -290,9 +289,6 @@ const Progress = observer(({ model }: ProgressProps) => { interface Props { model: CommandModel aliasesWithDuplicates: Array<Alias> | null - appState: AppState - events: Events - runnablesStore: RunnablesStore groupId?: number } @@ -317,12 +313,12 @@ const CommandControls = observer(({ model, commandName, events }) => { const isSessionCommand = commandName === 'session' const displayNumOfChildren = !isSystemEvent && !isSessionCommand && model.hasChildren && !model.isOpen - const _removeStudioCommand = (e: React.MouseEvent<HTMLElement, globalThis.MouseEvent>) => { + const _removeStudioCommand = useCallback((e: React.MouseEvent<HTMLElement, globalThis.MouseEvent>) => { e.preventDefault() e.stopPropagation() events.emit('studio:remove:command', model.number) - } + }, [events, model.number]) return ( <span className='command-controls'> @@ -369,139 +365,48 @@ const CommandControls = observer(({ model, commandName, events }) => { ) }) -@observer -class Command extends Component<Props> { - @observable isOpen: boolean|null = null - private _showTimeout?: TimeoutID - - static defaultProps = { - appState, - events, - runnablesStore, - } +const Command: React.FC<Props> = observer(({ model, aliasesWithDuplicates, groupId }) => { + const [showTimeout, setShowTimeout] = useState<TimeoutID | undefined>(undefined) - constructor (props: Props) { - super(props) - makeObservable(this) + if (model.group && groupId !== model.group) { + return null } - render () { - const { model, aliasesWithDuplicates } = this.props - - if (model.group && this.props.groupId !== model.group) { - return null - } - - const commandName = model.name ? nameClassName(model.name) : '' - const groupPlaceholder: Array<JSX.Element> = [] - - let groupLevel = 0 - - if (model.groupLevel !== undefined) { - // cap the group nesting to 5 levels to keep the log text legible - groupLevel = model.groupLevel < 6 ? model.groupLevel : 5 + const commandName = model.name ? nameClassName(model.name) : '' + const groupPlaceholder: Array<JSX.Element> = [] - for (let i = 1; i < groupLevel; i++) { - groupPlaceholder.push(<span key={`${this.props.groupId}-${i}`} className='command-group-block' />) - } - } - - return ( - <> - <li className={cs('command', `command-name-${commandName}`, { 'command-is-studio': model.isStudio })}> - <div - className={cs( - 'command-wrapper', - `command-state-${model.state}`, - `command-type-${model.type}`, - { - 'command-is-event': !!model.event, - 'command-is-pinned': this._isPinned(), - 'command-is-interactive': (model.hasConsoleProps || model.hasSnapshot), - }, - )} - > - <NavColumns model={model} isPinned={this._isPinned()} toggleColumnPin={this._toggleColumnPin} /> - <FlashOnClick - message='Printed output to your console' - onClick={this._toggleColumnPin} - shouldShowMessage={this._shouldShowClickMessage} - wrapperClassName={cs('command-pin-target', { 'command-group': !!this.props.groupId })} - > - <div - className='command-wrapper-text' - onMouseEnter={() => this._snapshot(true)} - onMouseLeave={() => this._snapshot(false)} - > - {groupPlaceholder} - <CommandDetails model={model} groupId={this.props.groupId} aliasesWithDuplicates={aliasesWithDuplicates} /> - <CommandControls model={model} commandName={commandName} events={this.props.events} /> - </div> - </FlashOnClick> - </div> - <Progress model={model} /> - {this._children()} - </li> - {model.showError && ( - <li> - <TestError - err={model.err} - testId={model.testId} - commandId={model.id} - // if the err is recovered and the current command is a log group, nest the test error within the group - groupLevel={model.group && model.hasChildren ? ++groupLevel : groupLevel} - /> - </li> - )} - </> - ) - } + let groupLevel = 0 - _children () { - const { appState, events, model, runnablesStore } = this.props + if (model.groupLevel !== undefined) { + // cap the group nesting to 5 levels to keep the log text legible + groupLevel = model.groupLevel < 6 ? model.groupLevel : 5 - if (!model.hasChildren || !model.isOpen) { - return null + for (let i = 1; i < groupLevel; i++) { + groupPlaceholder.push(<span key={`${groupId}-${i}`} className='command-group-block' />) } - - return ( - <ul className='command-child-container'> - {model.children.map((child) => ( - <Command - key={child.id} - model={child} - appState={appState} - events={events} - runnablesStore={runnablesStore} - aliasesWithDuplicates={null} - groupId={model.id} - /> - ))} - </ul> - ) } - _isPinned () { - return this.props.appState.pinnedSnapshotId === this.props.model.id + const _isPinned = () => { + return appState.pinnedSnapshotId === model.id } - _shouldShowClickMessage = () => { - return !this.props.appState.isRunning && !!this.props.model.hasConsoleProps + const _shouldShowClickMessage = () => { + return !appState.isRunning && !!model.hasConsoleProps } - @action _toggleColumnPin = () => { - if (this.props.appState.isRunning) return + const _toggleColumnPin = () => { + if (appState.isRunning) return - const { testId, id } = this.props.model + const { testId, id } = model - if (this._isPinned()) { - this.props.appState.pinnedSnapshotId = null - this.props.events.emit('unpin:snapshot', testId, id) - this._snapshot(true) + if (_isPinned()) { + appState.pinnedSnapshotId = null + events.emit('unpin:snapshot', testId, id) + _snapshot(true) } else { - this.props.appState.pinnedSnapshotId = id as number - this.props.events.emit('pin:snapshot', testId, id) - this.props.events.emit('show:command', testId, id) + appState.pinnedSnapshotId = id as number + events.emit('pin:snapshot', testId, id) + events.emit('show:command', testId, id) } } @@ -522,31 +427,90 @@ class Command extends Component<Props> { // over many commands, unless you're hovered for // 50ms, it won't show the snapshot at all. so we // optimize for both snapshot showing + restoring - _snapshot (show: boolean) { - const { model, runnablesStore } = this.props - + const _snapshot = (show: boolean) => { if (show) { runnablesStore.attemptingShowSnapshot = true - this._showTimeout = setTimeout(() => { + setShowTimeout(setTimeout(() => { runnablesStore.showingSnapshot = true - this.props.events.emit('show:snapshot', model.testId, model.id) - }, 50) + events.emit('show:snapshot', model.testId, model.id) + }, 50)) } else { runnablesStore.attemptingShowSnapshot = false - clearTimeout(this._showTimeout as TimeoutID) + clearTimeout(showTimeout as TimeoutID) setTimeout(() => { // if we are currently showing a snapshot but // we aren't trying to show a different snapshot if (runnablesStore.showingSnapshot && !runnablesStore.attemptingShowSnapshot) { runnablesStore.showingSnapshot = false - this.props.events.emit('hide:snapshot', model.testId, model.id) + events.emit('hide:snapshot', model.testId, model.id) } }, 50) } } -} + + return ( + <> + <li className={cs('command', `command-name-${commandName}`, { 'command-is-studio': model.isStudio })}> + <div + className={cs( + 'command-wrapper', + `command-state-${model.state}`, + `command-type-${model.type}`, + { + 'command-is-event': !!model.event, + 'command-is-pinned': _isPinned(), + 'command-is-interactive': (model.hasConsoleProps || model.hasSnapshot), + }, + )} + > + <NavColumns model={model} isPinned={_isPinned()} toggleColumnPin={_toggleColumnPin} /> + <FlashOnClick + message='Printed output to your console' + onClick={_toggleColumnPin} + shouldShowMessage={_shouldShowClickMessage} + wrapperClassName={cs('command-pin-target', { 'command-group': !!groupId })} + > + <div + className='command-wrapper-text' + onMouseEnter={() => _snapshot(true)} + onMouseLeave={() => _snapshot(false)} + > + {groupPlaceholder} + <CommandDetails model={model} groupId={groupId} aliasesWithDuplicates={aliasesWithDuplicates} /> + <CommandControls model={model} commandName={commandName} events={events} /> + </div> + </FlashOnClick> + </div> + <Progress model={model} /> + {model.hasChildren && model.isOpen && ( + <ul className='command-child-container'> + {model.children.map((child) => ( + <Command + key={child.id} + model={child} + aliasesWithDuplicates={null} + groupId={model.id} + /> + ))} + </ul> + )} + </li> + {model.showError && ( + <li> + <TestError + err={model.err} + testId={model.testId} + commandId={model.id} + // if the err is recovered and the current command is a log group, nest the test error within the group + groupLevel={model.group && model.hasChildren ? ++groupLevel : groupLevel} + /> + </li> + )} + </> + ) +}) export { Aliases, AliasesReferences, Message, Progress } diff --git a/packages/reporter/src/errors/error-code-frame.tsx b/packages/reporter/src/errors/error-code-frame.tsx index ec4fa4bf0cde..f25270d2803b 100644 --- a/packages/reporter/src/errors/error-code-frame.tsx +++ b/packages/reporter/src/errors/error-code-frame.tsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react' +import React, { useEffect, useRef } from 'react' import { observer } from 'mobx-react' import Prism from 'prismjs' @@ -9,28 +9,27 @@ interface Props { codeFrame: CodeFrame } -@observer -class ErrorCodeFrame extends Component<Props> { - componentDidMount () { - Prism.highlightAllUnder(this.refs.codeFrame as ParentNode) - } - - render () { - const { line, frame, language } = this.props.codeFrame - - // since we pull out 2 lines above the highlighted code, it will always - // be the 3rd line unless it's at the top of the file (lines 1 or 2) - const highlightLine = Math.min(line, 3) - - return ( - <div className='test-err-code-frame'> - <FileNameOpener className="runnable-err-file-path" fileDetails={this.props.codeFrame} hasIcon /> - <pre ref='codeFrame' data-line={highlightLine}> - <code className={`language-${language || 'text'}`}>{frame}</code> - </pre> - </div> - ) - } -} +const ErrorCodeFrame: React.FC<Props> = observer(({ codeFrame }) => { + const codeFrameRef = useRef<null | HTMLPreElement>(null) + + const { line, frame, language } = codeFrame + + // since we pull out 2 lines above the highlighted code, it will always + // be the 3rd line unless it's at the top of the file (lines 1 or 2) + const highlightLine = Math.min(line, 3) + + useEffect(() => { + Prism.highlightAllUnder(codeFrameRef.current as unknown as ParentNode) + }, []) + + return ( + <div className='test-err-code-frame'> + <FileNameOpener className="runnable-err-file-path" fileDetails={codeFrame} hasIcon /> + <pre ref={codeFrameRef} data-line={highlightLine}> + <code className={`language-${language || 'text'}`}>{frame}</code> + </pre> + </div> + ) +}) export default ErrorCodeFrame diff --git a/packages/reporter/src/errors/test-error.tsx b/packages/reporter/src/errors/test-error.tsx index 26ee4772a0b6..17d9d99473f6 100644 --- a/packages/reporter/src/errors/test-error.tsx +++ b/packages/reporter/src/errors/test-error.tsx @@ -1,5 +1,5 @@ import _ from 'lodash' -import React, { MouseEvent } from 'react' +import React, { MouseEvent, useCallback } from 'react' import cs from 'classnames' import { observer } from 'mobx-react' import Markdown from 'markdown-it' @@ -44,11 +44,14 @@ interface TestErrorProps { testId?: string commandId?: number // the command group level to nest the recovered in-test error - groupLevel: number + groupLevel?: number } -const TestError = (props: TestErrorProps) => { - const { err } = props +const TestError: React.FC<TestErrorProps> = ({ err, groupLevel = 0, testId, commandId }) => { + const _onPrint = useCallback((e: MouseEvent) => { + e.stopPropagation() + events.emit('show:error', { err, groupLevel, testId, commandId }) + }, [err, groupLevel, testId, commandId]) if (!err || !err.displayMessage) return null @@ -56,23 +59,13 @@ const TestError = (props: TestErrorProps) => { md.enable(['backticks', 'emphasis', 'escape']) - const onPrint = () => { - events.emit('show:error', props) - } - - const _onPrintClick = (e: MouseEvent) => { - e.stopPropagation() - - onPrint() - } - const { codeFrame } = err const groupPlaceholder: Array<JSX.Element> = [] if (err.isRecovered) { // cap the group nesting to 5 levels to keep the log text legible - for (let i = 0; i < props.groupLevel; i++) { + for (let i = 0; i < groupLevel; i++) { groupPlaceholder.push(<span key={`${err.name}-err-${i}`} className='err-group-block' />) } } @@ -99,10 +92,10 @@ const TestError = (props: TestErrorProps) => { header='View stack trace' headerClass='runnable-err-stack-expander' headerExtras={ - <FlashOnClick onClick={_onPrintClick} message="Printed output to your console"> + <FlashOnClick onClick={_onPrint} message="Printed output to your console"> <div className="runnable-err-print" - onKeyPress={onEnterOrSpace(onPrint)} + onKeyDown={onEnterOrSpace(() => events.emit('show:error', { err, groupLevel, testId, commandId }))} role='button' tabIndex={0} > @@ -121,8 +114,4 @@ const TestError = (props: TestErrorProps) => { ) } -TestError.defaultProps = { - groupLevel: 0, -} - export default observer(TestError) diff --git a/packages/reporter/src/lib/flash-on-click.tsx b/packages/reporter/src/lib/flash-on-click.tsx index 377b86149fc6..8d92a57cda56 100644 --- a/packages/reporter/src/lib/flash-on-click.tsx +++ b/packages/reporter/src/lib/flash-on-click.tsx @@ -1,7 +1,6 @@ -import { action, observable, makeObservable } from 'mobx' +import { action } from 'mobx' import { observer } from 'mobx-react' -import PropTypes from 'prop-types' -import React, { Children, cloneElement, Component, MouseEvent, ReactElement, ReactNode } from 'react' +import React, { Children, cloneElement, MouseEvent, ReactElement, ReactNode, useCallback, useState } from 'react' // @ts-ignore import Tooltip from '@cypress/react-tooltip' @@ -10,55 +9,35 @@ interface Props { onClick: ((e: MouseEvent) => void) shouldShowMessage?: (() => boolean) wrapperClassName?: string + children: React.ReactNode } -@observer -class FlashOnClick extends Component<Props> { - static propTypes = { - message: PropTypes.string.isRequired, - onClick: PropTypes.func.isRequired, - shouldShowMessage: PropTypes.func, - wrapperClassName: PropTypes.string, - } - - static defaultProps = { - shouldShowMessage: () => true, - } - - @observable _show = false - - constructor (props: Props) { - super(props) - makeObservable(this) - } - - render () { - const child = Children.only<ReactNode>(this.props.children) - - return ( - <Tooltip - placement='top' - title={this.props.message} - visible={this._show} - className='cy-tooltip' - wrapperClassName={this.props.wrapperClassName} - > - {cloneElement(child as ReactElement, { onClick: this._onClick })} - </Tooltip> - ) - } - - @action _onClick = (e: MouseEvent) => { - const { onClick, shouldShowMessage } = this.props +const FlashOnClick: React.FC<Props> = observer(({ message, onClick, wrapperClassName, children, shouldShowMessage = () => true }) => { + const [show, setShow] = useState(false) + const _onClick = useCallback((e: MouseEvent) => { onClick(e) if (shouldShowMessage && !shouldShowMessage()) return - this._show = true + setShow(true) setTimeout(action('hide:console:message', () => { - this._show = false + setShow(false) }), 1500) - } -} + }, [onClick, shouldShowMessage]) + + const child = Children.only<ReactNode>(children) + + return ( + <Tooltip + placement='top' + title={message} + visible={show} + className='cy-tooltip' + wrapperClassName={wrapperClassName} + > + {cloneElement(child as ReactElement, { onClick: _onClick })} + </Tooltip> + ) +}) export default FlashOnClick diff --git a/packages/reporter/src/lib/switch.tsx b/packages/reporter/src/lib/switch.tsx index ab25cffcb8a1..14a328609019 100644 --- a/packages/reporter/src/lib/switch.tsx +++ b/packages/reporter/src/lib/switch.tsx @@ -1,6 +1,5 @@ -import { action, makeObservable } from 'mobx' import { observer } from 'mobx-react' -import React, { Component } from 'react' +import React, { useCallback } from 'react' interface Props { value: boolean @@ -9,34 +8,23 @@ interface Props { onUpdate: (e: MouseEvent) => void } -@observer -class Switch extends Component<Props> { - @action _onClick = (e: MouseEvent) => { - const { onUpdate } = this.props - +const Switch: React.FC<Props> = observer(({ value, 'data-cy': dataCy, size = 'lg', onUpdate }) => { + const _onClick = useCallback((e: MouseEvent) => { onUpdate(e) - } - - constructor (props: Props) { - super(props) - makeObservable(this) - } + }, [onUpdate]) - render () { - const { 'data-cy': dataCy, size = 'lg', value } = this.props - - return ( - <button - data-cy={dataCy} - className={`switch switch-${size}`} - role="switch" - aria-checked={value} - onClick={this._onClick} - > - <span className="indicator" /> - </button> - ) - } -} + return ( + <button + data-cy={dataCy} + className={`switch switch-${size}`} + role="switch" + aria-checked={value} + // @ts-expect-error + onClick={_onClick} + > + <span className="indicator" /> + </button> + ) +}) export default Switch diff --git a/packages/reporter/src/main.tsx b/packages/reporter/src/main.tsx index e8a201ce1e96..ce2d436b16e2 100644 --- a/packages/reporter/src/main.tsx +++ b/packages/reporter/src/main.tsx @@ -1,15 +1,15 @@ /* global JSX */ -import { action, runInAction } from 'mobx' +import { action } from 'mobx' import { observer } from 'mobx-react' import cs from 'classnames' -import React, { Component } from 'react' +import React, { useEffect, useRef, useState } from 'react' import { createRoot } from 'react-dom/client' // @ts-ignore import EQ from 'css-element-queries/src/ElementQueries' import type { RunnablesErrorModel } from './runnables/runnable-error' -import appState, { AppState } from './lib/app-state' -import events, { Runner, Events } from './lib/events' +import appStateDefault, { AppState } from './lib/app-state' +import events, { Events, Runner } from './lib/events' import runnablesStore, { RunnablesStore } from './runnables/runnables-store' import scroller, { Scroller } from './lib/scroller' import statsStore, { StatsStore } from './header/stats-store' @@ -20,6 +20,16 @@ import Runnables from './runnables/runnables' import TestingPreferences from './preferences/testing-preferences' import type { MobxRunnerStore } from '@packages/app/src/store/mobx-runner-store' +function usePrevious (value) { + const ref = useRef() + + useEffect(() => { + ref.current = value + }, []) + + return ref.current +} + export interface BaseReporterProps { appState: AppState className?: string @@ -38,77 +48,29 @@ export interface BaseReporterProps { } export interface SingleReporterProps extends BaseReporterProps{ - runMode: 'single' + runMode?: 'single' } -@observer -class Reporter extends Component<SingleReporterProps> { - static defaultProps: Partial<SingleReporterProps> = { - runMode: 'single', - appState, - events, - runnablesStore, - scroller, - statsStore, - } +// In React Class components (now deprecated), we used to use appState as a default prop. Now since defaultProps are not supported in functional components, we can use ES6 default params to accomplish the same thing +const Reporter: React.FC<SingleReporterProps> = observer(({ appState = appStateDefault, runner, className, error, runMode = 'single', studioEnabled, autoScrollingEnabled, isSpecsListOpen, resetStatsOnSpecChange, renderReporterHeader = (props: ReporterHeaderProps) => <Header {...props}/>, runnerStore }) => { + const previousSpecRunId = usePrevious(runnerStore.specRunId) + const [isMounted, setIsMounted] = useState(false) + const [isInitialized, setIsInitialized] = useState(false) - render () { - const { + // this registration needs to happen synchronously and not async inside useEffect or else the events will not be registered and the reporter might hang inside cy-in-cy tests + if (!isInitialized) { + events.init({ appState, - className, runnablesStore, scroller, - error, statsStore, - studioEnabled, - renderReporterHeader = (props: ReporterHeaderProps) => <Header {...props}/>, - runnerStore, - } = this.props - - return ( - <div className={cs(className, 'reporter', { - 'studio-active': appState.studioActive, - })}> - {renderReporterHeader({ appState, statsStore, runnablesStore })} - {appState?.isPreferencesMenuOpen ? ( - <TestingPreferences appState={appState} /> - ) : ( - runnerStore.spec && <Runnables - appState={appState} - error={error} - runnablesStore={runnablesStore} - scroller={scroller} - spec={runnerStore.spec} - statsStore={statsStore} - studioEnabled={studioEnabled} - canSaveStudioLogs={runnerStore.canSaveStudioLogs} - /> - )} - </div> - ) - } - - // this hook will only trigger if we switch spec file at runtime - // it never happens in normal e2e but can happen in component-testing mode - componentDidUpdate (newProps: BaseReporterProps) { - if (!this.props.runnerStore.spec) { - throw Error(`Expected runnerStore.spec not to be null.`) - } + }) - this.props.runnablesStore.setRunningSpec(this.props.runnerStore.spec.relative) - if ( - this.props.resetStatsOnSpecChange && - this.props.runnerStore.specRunId !== newProps.runnerStore.specRunId - ) { - runInAction('reporter:stats:reset', () => { - this.props.statsStore.reset() - }) - } + events.listen(runner) + setIsInitialized(true) } - componentDidMount () { - const { appState, runnablesStore, runner, scroller, statsStore, autoScrollingEnabled, isSpecsListOpen, runnerStore } = this.props - + useEffect(() => { if (!runnerStore.spec) { throw Error(`Expected runnerStore.spec not to be null.`) } @@ -122,24 +84,52 @@ class Reporter extends Component<SingleReporterProps> { appState.setSpecsList(isSpecsListOpen ?? false) })() - this.props.events.init({ - appState, - runnablesStore, - scroller, - statsStore, - }) - - this.props.events.listen(runner) - shortcuts.start() EQ.init() - this.props.runnablesStore.setRunningSpec(runnerStore.spec.relative) - } + runnablesStore.setRunningSpec(runnerStore.spec.relative) + // we need to know when the test is mounted for our reporter tests. see + setIsMounted(true) - componentWillUnmount () { - shortcuts.stop() - } -} + return () => shortcuts.stop() + }, []) + + useEffect(() => { + if (!runnerStore.spec) { + throw Error(`Expected runnerStore.spec not to be null.`) + } + + runnablesStore.setRunningSpec(runnerStore.spec.relative) + if ( + resetStatsOnSpecChange && + runnerStore.specRunId !== previousSpecRunId + ) { + statsStore.reset() + } + }, [runnerStore.spec, runnerStore.specRunId, resetStatsOnSpecChange, previousSpecRunId]) + + return ( + <div className={cs(className, 'reporter', { + 'studio-active': appState.studioActive, + 'mounted': isMounted, + })}> + {renderReporterHeader({ appState, statsStore, runnablesStore })} + {appState?.isPreferencesMenuOpen ? ( + <TestingPreferences appState={appState} /> + ) : ( + runnerStore.spec && <Runnables + appState={appState} + error={error} + runnablesStore={runnablesStore} + scroller={scroller} + spec={runnerStore.spec} + statsStore={statsStore} + studioEnabled={studioEnabled} + canSaveStudioLogs={runnerStore.canSaveStudioLogs} + /> + )} + </div> + ) +}) declare global { interface Window { @@ -152,7 +142,7 @@ declare global { // NOTE: this is for testing Cypress-in-Cypress if (window.Cypress) { - window.state = appState + window.state = appStateDefault window.render = (props) => { const container: HTMLElement = document.getElementById('app') as HTMLElement const root = createRoot(container) diff --git a/packages/reporter/src/runnables/runnable-and-suite.tsx b/packages/reporter/src/runnables/runnable-and-suite.tsx index e7743a5a2d36..af2143cc2bf7 100644 --- a/packages/reporter/src/runnables/runnable-and-suite.tsx +++ b/packages/reporter/src/runnables/runnable-and-suite.tsx @@ -1,7 +1,7 @@ import cs from 'classnames' import _ from 'lodash' import { observer } from 'mobx-react' -import React, { Component, MouseEvent } from 'react' +import React, { MouseEvent, useCallback } from 'react' import { indent } from '../lib/util' @@ -23,12 +23,12 @@ interface SuiteProps { } const Suite = observer(({ eventManager = events, model, studioEnabled, canSaveStudioLogs }: SuiteProps) => { - const _launchStudio = (e: MouseEvent) => { + const _launchStudio = useCallback((e: MouseEvent) => { e.preventDefault() e.stopPropagation() eventManager.emit('studio:init:suite', model.id) - } + }, [eventManager, model.id]) const _header = () => ( <> @@ -76,30 +76,21 @@ export interface RunnableProps { // in order to mess with its internal state. converting it to a functional // component breaks that, so it needs to stay a Class-based component or // else the driver tests need to be refactored to support it being functional -@observer -class Runnable extends Component<RunnableProps> { - static defaultProps = { - appState, - } - - render () { - const { appState, model, studioEnabled, canSaveStudioLogs } = this.props - - return ( - <li - className={cs(`${model.type} runnable runnable-${model.state}`, { - 'runnable-retried': model.hasRetried, - 'runnable-studio': appState.studioActive, - })} - data-model-state={model.state} - > - {model.type === 'test' - ? <Test model={model as TestModel} studioEnabled={studioEnabled} canSaveStudioLogs={canSaveStudioLogs} /> - : <Suite model={model as SuiteModel} studioEnabled={studioEnabled} canSaveStudioLogs={canSaveStudioLogs} />} - </li> - ) - } -} +const Runnable: React.FC<RunnableProps> = observer(({ appState: appStateProps = appState, model, studioEnabled, canSaveStudioLogs }) => { + return ( + <li + className={cs(`${model.type} runnable runnable-${model.state}`, { + 'runnable-retried': model.hasRetried, + 'runnable-studio': appStateProps.studioActive, + })} + data-model-state={model.state} + > + {model.type === 'test' + ? <Test model={model as TestModel} studioEnabled={studioEnabled} canSaveStudioLogs={canSaveStudioLogs} /> + : <Suite model={model as SuiteModel} studioEnabled={studioEnabled} canSaveStudioLogs={canSaveStudioLogs} />} + </li> + ) +}) export { Suite } diff --git a/packages/reporter/src/runnables/runnable-header.tsx b/packages/reporter/src/runnables/runnable-header.tsx index e28ee9512e0e..3a411cb5e6ad 100644 --- a/packages/reporter/src/runnables/runnable-header.tsx +++ b/packages/reporter/src/runnables/runnable-header.tsx @@ -1,5 +1,5 @@ import { observer } from 'mobx-react' -import React, { Component, ReactElement } from 'react' +import React, { ReactElement } from 'react' import type { StatsStore } from '../header/stats-store' import { formatDuration, getFilenameParts } from '../lib/util' @@ -12,53 +12,48 @@ interface RunnableHeaderProps { statsStore: StatsStore } -@observer -class RunnableHeader extends Component<RunnableHeaderProps> { - render () { - const { spec, statsStore } = this.props - - const relativeSpecPath = spec.relative - - if (spec.relative === '__all') { - if (spec.specFilter) { - return renderRunnableHeader( - <span><span>Specs matching "{spec.specFilter}"</span></span>, - ) - } +const RunnableHeader: React.FC<RunnableHeaderProps> = observer(({ spec, statsStore }) => { + const relativeSpecPath = spec.relative + if (spec.relative === '__all') { + if (spec.specFilter) { return renderRunnableHeader( - <span><span>All Specs</span></span>, + <span><span>Specs matching "{spec.specFilter}"</span></span>, ) } - const displayFileName = () => { - const specParts = getFilenameParts(spec.name) - - return ( - <> - <strong>{specParts[0]}</strong>{specParts[1]} - </> - ) - } + return renderRunnableHeader( + <span><span>All Specs</span></span>, + ) + } - const fileDetails = { - absoluteFile: spec.absolute, - column: 0, - displayFile: displayFileName(), - line: 0, - originalFile: relativeSpecPath, - relativeFile: relativeSpecPath, - } + const displayFileName = () => { + const specParts = getFilenameParts(spec.name) - return renderRunnableHeader( + return ( <> - <FileNameOpener fileDetails={fileDetails} hasIcon /> - {Boolean(statsStore.duration) && ( - <span className='duration' data-cy="spec-duration">{formatDuration(statsStore.duration)}</span> - )} - </>, + <strong>{specParts[0]}</strong>{specParts[1]} + </> ) } -} + + const fileDetails = { + absoluteFile: spec.absolute, + column: 0, + displayFile: displayFileName(), + line: 0, + originalFile: relativeSpecPath, + relativeFile: relativeSpecPath, + } + + return renderRunnableHeader( + <> + <FileNameOpener fileDetails={fileDetails} hasIcon /> + {Boolean(statsStore.duration) && ( + <span className='duration' data-cy="spec-duration">{formatDuration(statsStore.duration)}</span> + )} + </>, + ) +}) export default RunnableHeader diff --git a/packages/reporter/src/runnables/runnables.tsx b/packages/reporter/src/runnables/runnables.tsx index 3bde4ec38b12..98d022e978c9 100644 --- a/packages/reporter/src/runnables/runnables.tsx +++ b/packages/reporter/src/runnables/runnables.tsx @@ -1,7 +1,7 @@ import _ from 'lodash' import { action } from 'mobx' import { observer } from 'mobx-react' -import React, { Component, MouseEvent } from 'react' +import React, { MouseEvent, useCallback, useEffect, useRef } from 'react' import events, { Events } from '../lib/events' import { RunnablesError, RunnablesErrorModel } from './runnable-error' @@ -33,12 +33,12 @@ interface RunnablesEmptyStateProps { } const RunnablesEmptyState = ({ spec, studioEnabled, eventManager = events }: RunnablesEmptyStateProps) => { - const _launchStudio = (e: MouseEvent) => { + const _launchStudio = useCallback((e: MouseEvent) => { e.preventDefault() // root runnable always has r1 as id eventManager.emit('studio:init:suite', 'r1') - } + }, [eventManager]) const isAllSpecs = spec.absolute === '__all' || spec.relative === '__all' @@ -154,28 +154,10 @@ export interface RunnablesProps { canSaveStudioLogs: boolean } -@observer -class Runnables extends Component<RunnablesProps> { - render () { - const { error, runnablesStore, spec, studioEnabled, canSaveStudioLogs } = this.props - - return ( - <div ref='container' className='container'> - <RunnableHeader spec={spec} statsStore={statsStore} /> - <RunnablesContent - runnablesStore={runnablesStore} - studioEnabled={studioEnabled} - canSaveStudioLogs={canSaveStudioLogs} - spec={spec} - error={error} - /> - </div> - ) - } - - componentDidMount () { - const { scroller, appState } = this.props +const Runnables: React.FC<RunnablesProps> = observer(({ appState, scroller, error, runnablesStore, spec, studioEnabled, canSaveStudioLogs }) => { + const containerRef = useRef<HTMLDivElement>(null) + useEffect(() => { let maybeHandleScroll: UserScrollCallback | undefined = undefined if (window.__CYPRESS_MODE__ === 'open') { @@ -191,9 +173,22 @@ class Runnables extends Component<RunnablesProps> { // we need to always call scroller.setContainer, but the callback can be undefined // so we pass maybeHandleScroll. If we don't, Cypress blows up with an error like // `A container must be set on the scroller with scroller.setContainer(container)` - scroller.setContainer(this.refs.container as Element, maybeHandleScroll) - } -} + scroller.setContainer(containerRef.current as Element, maybeHandleScroll) + }, []) + + return ( + <div ref={containerRef} className='container'> + <RunnableHeader spec={spec} statsStore={statsStore} /> + <RunnablesContent + runnablesStore={runnablesStore} + studioEnabled={studioEnabled} + canSaveStudioLogs={canSaveStudioLogs} + spec={spec} + error={error} + /> + </div> + ) +}) export { RunnablesList } diff --git a/packages/reporter/src/test/test-model.ts b/packages/reporter/src/test/test-model.ts index 09070b111806..85982f564dc2 100644 --- a/packages/reporter/src/test/test-model.ts +++ b/packages/reporter/src/test/test-model.ts @@ -187,6 +187,10 @@ export default class Test extends Runnable { cb() } + @action setIsOpen (isOpen: boolean) { + this._isOpen = isOpen + } + // this is called to sync up the command log UI for the sake of // screenshots, so we only ever need to open the last attempt setIsOpenWhenActive (isOpen: boolean) { diff --git a/packages/reporter/src/test/test.cy.tsx b/packages/reporter/src/test/test.cy.tsx index ea44776d7b1b..2793c78c3539 100644 --- a/packages/reporter/src/test/test.cy.tsx +++ b/packages/reporter/src/test/test.cy.tsx @@ -9,6 +9,9 @@ describe('test/test.tsx', () => { state: 'passed', title: 'foobar', attempts: [], + setIsOpen: (isOpen) => model.isOpen = isOpen, + onOpenStateChangeRequested: (isOpen) => model.setIsOpen(isOpen), + callbackAfterUpdate: () => undefined, } const appState = { @@ -37,6 +40,9 @@ describe('test/test.tsx', () => { state: 'passed', title: 'foobar', attempts: [], + setIsOpen: (isOpen) => model.isOpen = isOpen, + onOpenStateChangeRequested: (isOpen) => model.setIsOpen(isOpen), + callbackAfterUpdate: () => undefined, } const appState = { diff --git a/packages/reporter/src/test/test.tsx b/packages/reporter/src/test/test.tsx index 665fc444b9cd..47bc7dbea973 100644 --- a/packages/reporter/src/test/test.tsx +++ b/packages/reporter/src/test/test.tsx @@ -1,5 +1,5 @@ import { observer } from 'mobx-react' -import React, { Component, createRef, RefObject, MouseEvent } from 'react' +import React, { MouseEvent, useCallback, useEffect, useRef, useState } from 'react' // @ts-ignore import Tooltip from '@cypress/react-tooltip' import cs from 'classnames' @@ -8,7 +8,6 @@ import events, { Events } from '../lib/events' import appState, { AppState } from '../lib/app-state' import Collapsible from '../collapsible/collapsible' import { indent } from '../lib/util' -import runnablesStore, { RunnablesStore } from '../runnables/runnables-store' import TestModel from './test-model' import scroller, { Scroller } from '../lib/scroller' @@ -21,173 +20,126 @@ import ClipboardIcon from '@packages/frontend-shared/src/assets/icons/general-cl import WarningIcon from '@packages/frontend-shared/src/assets/icons/warning_x16.svg' interface StudioControlsProps { - events: Events - model: TestModel + events?: Events canSaveStudioLogs: boolean } -interface StudioControlsState { - copySuccess: boolean -} - -@observer -class StudioControls extends Component<StudioControlsProps, StudioControlsState> { - static defaultProps = { - events, - } - - state = { - copySuccess: false, - } +const StudioControls: React.FC<StudioControlsProps> = observer(({ events: eventsProps = events, canSaveStudioLogs }) => { + const [copySuccess, setCopySuccess] = useState(false) - _cancel = (e: MouseEvent) => { + const _cancel = useCallback((e: MouseEvent) => { e.preventDefault() - this.props.events.emit('studio:cancel') - } + eventsProps.emit('studio:cancel') + }, [eventsProps]) - _save = (e: MouseEvent) => { + const _save = useCallback((e: MouseEvent) => { e.preventDefault() - this.props.events.emit('studio:save') - } + eventsProps.emit('studio:save') + }, [eventsProps]) - _copy = (e: MouseEvent) => { + const _copy = useCallback((e: MouseEvent) => { e.preventDefault() - this.props.events.emit('studio:copy:to:clipboard', () => { - this.setState({ copySuccess: true }) + eventsProps.emit('studio:copy:to:clipboard', () => { + setCopySuccess(true) }) - } + }, [eventsProps]) - _endCopySuccess = () => { - if (this.state.copySuccess) { - this.setState({ copySuccess: false }) + const _endCopySuccess = useCallback(() => { + if (copySuccess) { + setCopySuccess(false) } - } - - render () { - const { canSaveStudioLogs } = this.props - const { copySuccess } = this.state - - return ( - <div className='studio-controls'> - <a className='studio-cancel' onClick={this._cancel}>Cancel</a> - <Tooltip - title={copySuccess ? 'Commands Copied!' : 'Copy Commands to Clipboard'} - className='cy-tooltip' - wrapperClassName='studio-copy-wrapper' - visible={!canSaveStudioLogs ? false : null} - updateCue={copySuccess} + }, [copySuccess]) + + return ( + <div className='studio-controls'> + <a className='studio-cancel' onClick={_cancel}>Cancel</a> + <Tooltip + title={copySuccess ? 'Commands Copied!' : 'Copy Commands to Clipboard'} + className='cy-tooltip' + wrapperClassName='studio-copy-wrapper' + visible={!canSaveStudioLogs ? false : null} + updateCue={copySuccess} + > + <button + className={cs('studio-copy', { + 'studio-copy-success': copySuccess, + })} + disabled={!canSaveStudioLogs} + onClick={_copy} + onMouseLeave={_endCopySuccess} > - <button - className={cs('studio-copy', { - 'studio-copy-success': copySuccess, - })} - disabled={!canSaveStudioLogs} - onClick={this._copy} - onMouseLeave={this._endCopySuccess} - > - {copySuccess ? ( - <CheckIcon /> - ) : ( - <ClipboardIcon /> - )} - </button> - </Tooltip> - <button className='studio-save' disabled={!canSaveStudioLogs} onClick={this._save}>Save Commands</button> - </div> - ) - } -} + {copySuccess ? ( + <CheckIcon /> + ) : ( + <ClipboardIcon /> + )} + </button> + </Tooltip> + <button className='studio-save' disabled={!canSaveStudioLogs} onClick={_save}>Save Commands</button> + </div> + ) +}) interface TestProps { - events: Events - appState: AppState - runnablesStore: RunnablesStore - scroller: Scroller + events?: Events + appState?: AppState + scroller?: Scroller model: TestModel studioEnabled: boolean canSaveStudioLogs: boolean } -@observer -class Test extends Component<TestProps> { - static defaultProps = { - events, - appState, - runnablesStore, - scroller, - } - - containerRef: RefObject<HTMLDivElement> - - constructor (props: TestProps) { - super(props) - - this.containerRef = createRef<HTMLDivElement>() - } +const Test: React.FC<TestProps> = observer(({ model, events: eventsProps = events, appState: appStateProps = appState, scroller: scrollerProps = scroller, studioEnabled, canSaveStudioLogs }) => { + const containerRef = useRef(null) + const [isMounted, setIsMounted] = useState(false) - componentDidMount () { - this._scrollIntoView() - } + useEffect(() => { + _scrollIntoView() + if (!isMounted) { + setIsMounted(true) + } else { + model.callbackAfterUpdate() + } + }) - componentDidUpdate () { - this._scrollIntoView() - this.props.model.callbackAfterUpdate() - } + const _launchStudio = useCallback((e: MouseEvent) => { + e.preventDefault() + e.stopPropagation() - _scrollIntoView () { - const { appState, model, scroller } = this.props - const { state } = model + eventsProps.emit('studio:init:test', model.id) + }, [eventsProps, model.id]) - if (appState.autoScrollingEnabled && (appState.isRunning || appState.studioActive) && state !== 'processing') { + const _scrollIntoView = () => { + if (appStateProps.autoScrollingEnabled && (appStateProps.isRunning || appStateProps.studioActive) && model.state !== 'processing') { window.requestAnimationFrame(() => { // since this executes async in a RAF the ref might be null - if (this.containerRef.current) { - scroller.scrollIntoView(this.containerRef.current as HTMLElement) + if (containerRef.current) { + scrollerProps.scrollIntoView(containerRef.current as HTMLElement) } }) } } - render () { - const { model } = this.props - - return ( - <Collapsible - containerRef={this.containerRef} - header={this._header()} - headerClass='runnable-wrapper' - headerStyle={{ paddingLeft: indent(model.level) }} - contentClass='runnable-instruments' - isOpen={model.isOpen} - hideExpander - > - {this._contents()} - </Collapsible> - ) - } - - _header () { - const { appState, model } = this.props - + const _header = () => { return (<> - <StateIcon aria-hidden className="runnable-state-icon" state={model.state} isStudio={appState.studioActive} /> + <StateIcon aria-hidden className="runnable-state-icon" state={model.state} isStudio={appStateProps.studioActive} /> <span className='runnable-title'> <span>{model.title}</span> <span className='visually-hidden'>{model.state}</span> </span> - {this._controls()} + {_controls()} </>) } - _controls () { + const _controls = () => { let controls: Array<JSX.Element> = [] - if (this.props.model.state === 'failed') { + if (model.state === 'failed') { controls.push( - <Tooltip key={`test-failed-${this.props.model}`} placement='top' title='One or more commands failed' className='cy-tooltip'> + <Tooltip key={`test-failed-${model}`} placement='top' title='One or more commands failed' className='cy-tooltip'> <span> <WarningIcon className="runnable-controls-status" /> </span> @@ -195,12 +147,12 @@ class Test extends Component<TestProps> { ) } - if (this.props.studioEnabled && !appState.studioActive) { + if (studioEnabled && !appStateProps.studioActive) { controls.push( <LaunchStudioIcon - key={`studio-command-${this.props.model}`} + key={`studio-command-${model}`} title='Add Commands to Test' - onClick={this._launchStudio} + onClick={_launchStudio} />, ) } @@ -216,25 +168,23 @@ class Test extends Component<TestProps> { ) } - _contents () { - const { appState, model } = this.props - - return ( + return ( + <Collapsible + containerRef={containerRef} + header={_header()} + headerClass='runnable-wrapper' + headerStyle={{ paddingLeft: indent(model.level) }} + contentClass='runnable-instruments' + isOpen={model.isOpen} + onOpenStateChangeRequested={(isOpen: boolean) => model.setIsOpen(isOpen)} + hideExpander + > <div style={{ paddingLeft: indent(model.level) }}> - <Attempts studioActive={appState.studioActive} test={model} scrollIntoView={() => this._scrollIntoView()} /> - {appState.studioActive && <StudioControls model={model} canSaveStudioLogs={this.props.canSaveStudioLogs}/>} + <Attempts studioActive={appStateProps.studioActive} test={model} scrollIntoView={() => _scrollIntoView()} /> + {appStateProps.studioActive && <StudioControls canSaveStudioLogs={canSaveStudioLogs}/>} </div> - ) - } - - _launchStudio = (e: MouseEvent) => { - e.preventDefault() - e.stopPropagation() - - const { model, events } = this.props - - events.emit('studio:init:test', model.id) - } -} + </Collapsible> + ) +}) export default Test diff --git a/packages/server/lib/automation/automation.ts b/packages/server/lib/automation/automation.ts index 7a7250efee9f..b4073451dbc5 100644 --- a/packages/server/lib/automation/automation.ts +++ b/packages/server/lib/automation/automation.ts @@ -86,12 +86,12 @@ export class Automation { const onReq = this.get('onRequest') if (onReq) { + debug('Middleware `onRequest` fn found, attempting middleware exec for message: %s', message) + return Bluebird.try(() => { return onReq(resolvedMessage, resolvedData) }).catch((e) => { if (AutomationNotImplemented.isAutomationNotImplementedErr(e)) { - debug(`${e.message}. Falling back to emit via socket.`) - return this.requestAutomationResponse(resolvedMessage, resolvedData, fn) } @@ -189,6 +189,8 @@ export class Automation { } use (middlewares: AutomationMiddleware) { + debug('installing middleware') + return this.middleware = { ...this.middleware, ...middlewares, @@ -196,6 +198,7 @@ export class Automation { } async push<T extends keyof AutomationCommands> (message: T, data: AutomationCommands[T]['dataType']) { + debug('push `%s`: %o', message, data) const result = await this.normalize(message, data) if (result) { @@ -206,6 +209,7 @@ export class Automation { async request<T extends keyof AutomationCommands> (message: T, data: AutomationCommands[T]['dataType'], fn) { // curry in the message + callback function // for obtaining the external automation data + debug('request: `%s`', message) const automate = this.automationValve(message, fn) await this.invokeAsync('onBeforeRequest', message, data) diff --git a/packages/server/lib/automation/commands/key_press.ts b/packages/server/lib/automation/commands/key_press.ts index aa7b28241e2d..5d556a7a7437 100644 --- a/packages/server/lib/automation/commands/key_press.ts +++ b/packages/server/lib/automation/commands/key_press.ts @@ -1,8 +1,10 @@ +import type ProtocolMapping from 'devtools-protocol/types/protocol-mapping' +import type { Protocol } from 'devtools-protocol' import type { KeyPressParams, KeyPressSupportedKeys } from '@packages/types' import type { SendDebuggerCommand } from '../../browsers/cdp_automation' import type { Client } from 'webdriver' - import Debug from 'debug' +import { isEqual, isError } from 'lodash' const debug = Debug('cypress:server:automation:command:keypress') @@ -20,11 +22,41 @@ export class InvalidKeyError extends Error { } } +export function isSupportedKey (key: string): key is KeyPressSupportedKeys { + return CDP_KEYCODE[key] && BIDI_VALUE[key] +} + export const CDP_KEYCODE: KeyCodeLookup = { 'Tab': 'U+000009', } -export async function cdpKeyPress ({ key }: KeyPressParams, send: SendDebuggerCommand): Promise<void> { +async function evaluateInFrameContext (expression: string, + send: SendDebuggerCommand, + contexts: Map<Protocol.Runtime.ExecutionContextId, Protocol.Runtime.ExecutionContextDescription>, + frame: Protocol.Page.Frame): Promise<ProtocolMapping.Commands['Runtime.evaluate']['returnType']> { + for (const [contextId, context] of contexts.entries()) { + if (context.auxData?.frameId === frame.id) { + try { + return await send('Runtime.evaluate', { + expression, + contextId, + }) + } catch (e) { + if (isError(e) && (e as Error).message.includes('Cannot find context with specified id')) { + debug('found invalid context %d, removing', contextId) + contexts.delete(contextId) + } + } + } + } + throw new Error('Unable to find valid context for frame') +} + +export async function cdpKeyPress ( + { key }: KeyPressParams, send: SendDebuggerCommand, + contexts: Map<Protocol.Runtime.ExecutionContextId, Protocol.Runtime.ExecutionContextDescription>, + frameTree: Protocol.Page.FrameTree, +): Promise<void> { debug('cdp keypress', { key }) if (!CDP_KEYCODE[key]) { throw new InvalidKeyError(key) @@ -32,6 +64,22 @@ export async function cdpKeyPress ({ key }: KeyPressParams, send: SendDebuggerCo const keyIdentifier = CDP_KEYCODE[key] + const autFrame = frameTree.childFrames?.find(({ frame }) => { + return frame.name?.includes('Your project') + }) + + if (!autFrame) { + throw new Error('Could not find AUT frame') + } + + const topActiveElement = await evaluateInFrameContext('document.activeElement', send, contexts, frameTree.frame) + + const autFrameIsActive = topActiveElement.result.description && autFrame.frame.name && topActiveElement.result.description.includes(autFrame.frame.name) + + if (!autFrameIsActive) { + await evaluateInFrameContext('window.focus()', send, contexts, autFrame.frame) + } + try { await send('Input.dispatchKeyEvent', { type: 'keyDown', @@ -56,19 +104,32 @@ export const BIDI_VALUE: KeyCodeLookup = { 'Tab': '\uE004', } -export async function bidiKeyPress ({ key }: KeyPressParams, client: Client, context: string, idSuffix?: string): Promise<void> { +export async function bidiKeyPress ({ key }: KeyPressParams, client: Client, autContext: string, idSuffix?: string): Promise<void> { const value = BIDI_VALUE[key] if (!value) { throw new InvalidKeyError(key) } + const autFrameElement = await client.findElement('css selector', 'iframe.aut-iframe') + const activeElement = await client.getActiveElement() + + if (!isEqual(autFrameElement, activeElement)) { + await client.scriptEvaluate( + { + expression: `window.focus()`, + target: { context: autContext }, + awaitPromise: false, + }, + ) + } + try { await client.inputPerformActions({ - context, + context: autContext, actions: [{ type: 'key', - id: `${context}-${key}-${idSuffix || Date.now()}`, + id: `${autContext}-${key}-${idSuffix || Date.now()}`, actions: [ { type: 'keyDown', value }, { type: 'keyUp', value }, diff --git a/packages/server/lib/browsers/bidi_automation.ts b/packages/server/lib/browsers/bidi_automation.ts index 4cdfbf1a0f1f..b9329cefe182 100644 --- a/packages/server/lib/browsers/bidi_automation.ts +++ b/packages/server/lib/browsers/bidi_automation.ts @@ -79,9 +79,9 @@ export class BidiAutomation { private interceptId: string | undefined = undefined private constructor (webDriverClient: WebDriverClient, automation: Automation) { + debug('initializing bidi automation') this.automation = automation this.webDriverClient = webDriverClient - // bind Bidi Events to update the standard automation client // Error here is expected until webdriver adds initiatorType and destination to the request object // @ts-expect-error @@ -91,9 +91,6 @@ export class BidiAutomation { this.webDriverClient.on('network.fetchError', this.onFetchError) this.webDriverClient.on('browsingContext.contextCreated', this.onBrowsingContextCreated) this.webDriverClient.on('browsingContext.contextDestroyed', this.onBrowsingContextDestroyed) - - debug('registering middleware') - automation.use(this.automationMiddleware) } setTopLevelContextId = (contextId?: string) => { @@ -294,10 +291,10 @@ export class BidiAutomation { switch (message) { case 'key:press': - if (this.topLevelContextId) { - await bidiKeyPress(data, this.webDriverClient, this.topLevelContextId) + if (this.autContextId) { + await bidiKeyPress(data, this.webDriverClient, this.autContextId, this.topLevelContextId) } else { - throw new Error('Cannot emit key press: no top level context initialized') + throw new Error('Cannot emit key press: no AUT context initialized') } return diff --git a/packages/server/lib/browsers/cdp_automation.ts b/packages/server/lib/browsers/cdp_automation.ts index 3c6ecb6d2d34..1ef28e4a7325 100644 --- a/packages/server/lib/browsers/cdp_automation.ts +++ b/packages/server/lib/browsers/cdp_automation.ts @@ -169,6 +169,7 @@ export class CdpAutomation implements CDPClient, AutomationMiddleware { private frameTree: Protocol.Page.FrameTree | undefined private gettingFrameTree: Promise<void> | undefined | null private cachedDataUrlRequestIds: Set<string> = new Set() + private executionContexts: Map<Protocol.Runtime.ExecutionContextId, Protocol.Runtime.ExecutionContextDescription> = new Map() private constructor (private sendDebuggerCommandFn: SendDebuggerCommand, private onFn: OnFn, private offFn: OffFn, private sendCloseCommandFn: SendCloseCommand, private automation: Automation, private focusTabOnScreenshot: boolean = false, private isHeadless: boolean = false) { onFn('Network.requestWillBeSent', this.onNetworkRequestWillBeSent) @@ -178,6 +179,9 @@ export class CdpAutomation implements CDPClient, AutomationMiddleware { onFn('ServiceWorker.workerRegistrationUpdated', this.onServiceWorkerRegistrationUpdated) onFn('ServiceWorker.workerVersionUpdated', this.onServiceWorkerVersionUpdated) + onFn('Runtime.executionContextCreated', this.onExecutionContextCreated) + onFn('Runtime.executionContextDestroyed', this.onExecutionContextDestroyed) + this.on = onFn this.off = offFn this.send = sendDebuggerCommandFn @@ -337,6 +341,18 @@ export class CdpAutomation implements CDPClient, AutomationMiddleware { this.automation.onServiceWorkerVersionUpdated?.(params) } + private onExecutionContextCreated = (event: Protocol.Runtime.ExecutionContextCreatedEvent) => { + debugVerbose('new execution context:', event) + this.executionContexts.set(event.context.id, event.context) + } + + private onExecutionContextDestroyed = (event: Protocol.Runtime.ExecutionContextDestroyedEvent) => { + debugVerbose('removing execution context', event) + if (this.executionContexts.has(event.executionContextId)) { + this.executionContexts.delete(event.executionContextId) + } + } + private getAllCookies = (filter: CyCookieFilter) => { return this.sendDebuggerCommandFn('Network.getAllCookies') .then((result: Protocol.Network.GetAllCookiesResponse) => { @@ -588,7 +604,13 @@ export class CdpAutomation implements CDPClient, AutomationMiddleware { case 'collect:garbage': return this.sendDebuggerCommandFn('HeapProfiler.collectGarbage') case 'key:press': - return cdpKeyPress(data, this.sendDebuggerCommandFn) + if (this.gettingFrameTree) { + debugVerbose('awaiting frame tree') + + await this.gettingFrameTree + } + + return cdpKeyPress(data, this.sendDebuggerCommandFn, this.executionContexts, (await this.send('Page.getFrameTree')).frameTree) default: throw new Error(`No automation handler registered for: '${message}'`) } diff --git a/packages/server/lib/browsers/firefox-util.ts b/packages/server/lib/browsers/firefox-util.ts index f3a3dcf6842f..9d093e33945e 100644 --- a/packages/server/lib/browsers/firefox-util.ts +++ b/packages/server/lib/browsers/firefox-util.ts @@ -56,6 +56,8 @@ export default { // we need to set this to bind our AUT intercepts correctly. Hopefully we can move this in the future on a more sure implementation client.setTopLevelContextId(contexts[0].context) + automation.use(client.automationMiddleware) + await webdriverClient.browsingContextNavigate({ context: contexts[0].context, url, diff --git a/packages/server/lib/browsers/firefox.ts b/packages/server/lib/browsers/firefox.ts index aa5fe8ba8181..eb217309cc46 100644 --- a/packages/server/lib/browsers/firefox.ts +++ b/packages/server/lib/browsers/firefox.ts @@ -388,7 +388,11 @@ export function clearInstanceState (options: GracefulShutdownOptions = {}) { } export async function connectToNewSpec (browser: Browser, options: BrowserNewTabOpts, automation: Automation) { + debug('connectToNewSpec bidi') await firefoxUtil.connectToNewSpecBiDi(options, automation, browserBidiClient!) + + debug('registering middleware') + automation.use(browserBidiClient!.automationMiddleware) } export function connectToExisting () { diff --git a/packages/server/lib/cloud/protocol.ts b/packages/server/lib/cloud/protocol.ts index 45de3f55784f..89ac137bffea 100644 --- a/packages/server/lib/cloud/protocol.ts +++ b/packages/server/lib/cloud/protocol.ts @@ -62,6 +62,10 @@ export class ProtocolManager implements ProtocolManagerShape { } : undefined } + get db () { + return this._db + } + async prepareProtocol (script: string, options: ProtocolManagerOptions) { this._captureHash = base64url.fromBase64(crypto.createHash('SHA256').update(script).digest('base64')) diff --git a/packages/server/lib/cloud/studio.ts b/packages/server/lib/cloud/studio.ts index 166d57e251e3..f93341cd3091 100644 --- a/packages/server/lib/cloud/studio.ts +++ b/packages/server/lib/cloud/studio.ts @@ -6,6 +6,7 @@ import os from 'os' import { agent } from '@packages/network' import Debug from 'debug' import { requireScript } from './require_script' +import type Database from 'better-sqlite3' interface StudioServer { default: StudioServerDefaultShape } @@ -37,6 +38,10 @@ export class StudioManager implements StudioManagerShape { return manager } + setProtocolDb (db: Database.Database): void { + this.invokeSync('setProtocolDb', { isEssential: true }, db) + } + async setup ({ script, studioPath, studioHash, projectSlug, cloudApi }: SetupOptions): Promise<void> { const { createStudioServer } = requireScript<StudioServer>(script).default @@ -100,6 +105,7 @@ export class StudioManager implements StudioManagerShape { } try { + // @ts-expect-error - TS not associating the method & args properly, even though we know it's correct return this._studioServer[method].apply(this._studioServer, args) } catch (error: unknown) { let actualError: Error diff --git a/packages/server/lib/project-base.ts b/packages/server/lib/project-base.ts index 17f56a8178e1..e232ad4e0d6a 100644 --- a/packages/server/lib/project-base.ts +++ b/packages/server/lib/project-base.ts @@ -447,6 +447,10 @@ export class ProjectBase extends EE { await browsers.connectProtocolToBrowser({ browser: this.browser, foundBrowsers: this.options.browsers, protocolManager: this.protocolManager }) + if (this.protocolManager.db) { + this.ctx.coreData.studio?.setProtocolDb(this.protocolManager.db) + } + return { canAccessStudioAI: true } } diff --git a/packages/server/lib/reporter.js b/packages/server/lib/reporter.js index 1cb6d2e914bf..d2e3639cd149 100644 --- a/packages/server/lib/reporter.js +++ b/packages/server/lib/reporter.js @@ -4,9 +4,9 @@ const { stackUtils } = require('@packages/errors') // mocha-* is used to allow us to have later versions of mocha specified in devDependencies // and prevents accidentally upgrading this one // TODO: look into upgrading this to version in driver -const Mocha = require('mocha-7.0.1') -const mochaReporters = require('mocha-7.0.1/lib/reporters') -const mochaCreateStatsCollector = require('mocha-7.0.1/lib/stats-collector') +const Mocha = require('mocha-7.2.0') +const mochaReporters = require('mocha-7.2.0/lib/reporters') +const mochaCreateStatsCollector = require('mocha-7.2.0/lib/stats-collector') const mochaColor = mochaReporters.Base.color const mochaSymbols = mochaReporters.Base.symbols @@ -16,7 +16,7 @@ const { overrideRequire } = require('./override_require') // override calls to `require('mocha*')` when to always resolve with a mocha we control // otherwise mocha will be resolved from project's node_modules and might not work with our code -const customReporterMochaPath = path.dirname(require.resolve('mocha-7.0.1')) +const customReporterMochaPath = path.dirname(require.resolve('mocha-7.2.0')) const buildAttemptMessage = (currentRetry, totalRetries) => { return `(Attempt ${currentRetry} of ${totalRetries})` diff --git a/packages/server/lib/socket-base.ts b/packages/server/lib/socket-base.ts index cd2a86e217f0..a6b3fb080c04 100644 --- a/packages/server/lib/socket-base.ts +++ b/packages/server/lib/socket-base.ts @@ -185,6 +185,8 @@ export class SocketBase { message: T, data: AutomationCommands[T]['dataType'], ) => { + debug('request: %s', message) + return automation.request(message, data, onAutomationClientRequestCallback) } diff --git a/packages/server/package.json b/packages/server/package.json index 0dc62877aa19..30c09c11aa33 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -100,7 +100,7 @@ "mime-db": "1.45.0", "minimatch": "3.1.2", "minimist": "1.2.8", - "mocha-7.0.1": "npm:mocha@7.0.1", + "mocha-7.2.0": "npm:mocha@7.2.0", "mocha-junit-reporter": "2.2.0", "mocha-teamcity-reporter": "3.0.0", "morgan": "1.9.1", diff --git a/packages/server/test/support/fixtures/cloud/protocol/test-protocol.ts b/packages/server/test/support/fixtures/cloud/protocol/test-protocol.ts index cda1a1b27cdd..3f378c8cb3f6 100644 --- a/packages/server/test/support/fixtures/cloud/protocol/test-protocol.ts +++ b/packages/server/test/support/fixtures/cloud/protocol/test-protocol.ts @@ -1,4 +1,4 @@ -import type { Database } from 'better-sqlite3' +import type Database from 'better-sqlite3' import type { AppCaptureProtocolInterface, CDPClient, ResponseStreamOptions } from '@packages/types' import { Readable } from 'stream' @@ -12,7 +12,7 @@ export class AppCaptureProtocol implements AppCaptureProtocolInterface { responseStreamReceived (options: ResponseStreamOptions): Readable { return Readable.from([]) } - beforeSpec ({ workingDirectory, archivePath, dbPath, db }: { workingDirectory: string, archivePath: string, dbPath: string, db: Database }): void {} + beforeSpec ({ workingDirectory, archivePath, dbPath, db }: { workingDirectory: string, archivePath: string, dbPath: string, db: Database.Database }): void {} addRunnables (runnables: any): void {} commandLogAdded (log: any): void {} commandLogChanged (log: any): void {} diff --git a/packages/server/test/support/fixtures/cloud/studio/test-studio.ts b/packages/server/test/support/fixtures/cloud/studio/test-studio.ts index fc6795d95584..6f2f63bc238a 100644 --- a/packages/server/test/support/fixtures/cloud/studio/test-studio.ts +++ b/packages/server/test/support/fixtures/cloud/studio/test-studio.ts @@ -1,4 +1,5 @@ import type { StudioServerShape, StudioServerDefaultShape, StudioBrowser } from '@packages/types' +import type Database from 'better-sqlite3' import type { Router } from 'express' class StudioServer implements StudioServerShape { @@ -9,6 +10,9 @@ class StudioServer implements StudioServerShape { canAccessStudioAI (browser: StudioBrowser): Promise<boolean> { return Promise.resolve(true) } + + setProtocolDb (db: Database.Database): void { + } } const studioServerDefault: StudioServerDefaultShape = { diff --git a/packages/server/test/unit/automation/commands/key_press.spec.ts b/packages/server/test/unit/automation/commands/key_press.spec.ts index 10a2a6db85a4..a62a4c927d84 100644 --- a/packages/server/test/unit/automation/commands/key_press.spec.ts +++ b/packages/server/test/unit/automation/commands/key_press.spec.ts @@ -3,32 +3,158 @@ import type { KeyPressSupportedKeys } from '@packages/types' import type { SendDebuggerCommand } from '../../../../lib/browsers/cdp_automation' import { cdpKeyPress, bidiKeyPress, BIDI_VALUE, CDP_KEYCODE } from '../../../../lib/automation/commands/key_press' import { Client as WebdriverClient } from 'webdriver' - +import type { Protocol } from 'devtools-protocol' const { expect, sinon } = require('../../../spec_helper') describe('key:press automation command', () => { describe('cdp()', () => { let sendFn: Sinon.SinonStub<Parameters<SendDebuggerCommand>, ReturnType<SendDebuggerCommand>> + const topFrameId = 'abc' + const autFrameId = 'def' + + // @ts-expect-error + const topExecutionContext: Protocol.Runtime.ExecutionContextDescription = { + id: 123, + auxData: { + frameId: topFrameId, + }, + } + // @ts-expect-error + const autExecutionContext: Protocol.Runtime.ExecutionContextDescription = { + id: 456, + auxData: { + frameId: autFrameId, + }, + } + + let executionContexts: Map<Protocol.Runtime.ExecutionContextId, Protocol.Runtime.ExecutionContextDescription> = new Map() + + const autFrame = { + frame: { + id: autFrameId, + name: 'Your project', + }, + } + + const frameTree: Protocol.Page.FrameTree = { + // @ts-expect-error - partial mock of the frame tree + frame: { + id: topFrameId, + }, + childFrames: [ + // @ts-expect-error - partial mock of the frame tree + autFrame, + ], + } beforeEach(() => { sendFn = sinon.stub() + executionContexts.set(topExecutionContext.id, topExecutionContext) + executionContexts.set(autExecutionContext.id, autExecutionContext) + }) + + describe('when the aut frame does not have focus', () => { + const topActiveElement: Protocol.Runtime.EvaluateResponse = { + result: { + type: 'object', + description: 'a.some-link', + }, + } + + beforeEach(() => { + sendFn.withArgs('Runtime.evaluate', { + expression: 'document.activeElement', + contextId: topExecutionContext.id, + }).resolves(topActiveElement) + }) + + it('focuses the frame and sends keydown and keyup', async () => { + await cdpKeyPress({ key: 'Tab' }, sendFn, executionContexts, frameTree) + expect(sendFn).to.have.been.calledWith('Runtime.evaluate', { + expression: 'window.focus()', + contextId: autExecutionContext.id, + }) + + expect(sendFn).to.have.been.calledWith('Input.dispatchKeyEvent', { + type: 'keyDown', + keyIdentifier: CDP_KEYCODE.Tab, + key: 'Tab', + code: 'Tab', + }) + + expect(sendFn).to.have.been.calledWith('Input.dispatchKeyEvent', { + type: 'keyUp', + keyIdentifier: CDP_KEYCODE.Tab, + key: 'Tab', + code: 'Tab', + }) + }) + + describe('when there are invalid execution contexts associated with the top frame', () => { + // @ts-expect-error - this is a "fake" partial + const invalidExecutionContext: Protocol.Runtime.ExecutionContextDescription = { + id: 9, + auxData: { + frameId: topFrameId, + }, + } + + beforeEach(() => { + executionContexts = new Map() + executionContexts.set(invalidExecutionContext.id, invalidExecutionContext) + executionContexts.set(topExecutionContext.id, topExecutionContext) + executionContexts.set(autExecutionContext.id, autExecutionContext) + sendFn.withArgs('Runtime.evaluate', { + expression: 'document.activeElement', + contextId: invalidExecutionContext.id, + }).rejects(new Error('Cannot find context with specified id')) + }) + + it('does not throw', async () => { + let thrown: any = undefined + + try { + await cdpKeyPress({ key: 'Tab' }, sendFn, executionContexts, frameTree) + } catch (e) { + thrown = e + } + + expect(thrown).to.be.undefined + }) + }) }) - it('dispaches a keydown followed by a keyup event to the provided send fn with the tab keycode', async () => { - await cdpKeyPress({ key: 'Tab' }, sendFn) + describe('when the aut frame has focus', () => { + const topActiveElement: Protocol.Runtime.EvaluateResponse = { + result: { + type: 'object', + description: autFrame.frame.name, + }, + } - expect(sendFn).to.have.been.calledWith('Input.dispatchKeyEvent', { - type: 'keyDown', - keyIdentifier: CDP_KEYCODE.Tab, - key: 'Tab', - code: 'Tab', + beforeEach(() => { + sendFn.withArgs('Runtime.evaluate', { + expression: 'document.activeElement', + contextId: topExecutionContext.id, + }).resolves(topActiveElement) }) - expect(sendFn).to.have.been.calledWith('Input.dispatchKeyEvent', { - type: 'keyUp', - keyIdentifier: CDP_KEYCODE.Tab, - key: 'Tab', - code: 'Tab', + it('dispaches a keydown followed by a keyup event to the provided send fn with the tab keycode', async () => { + await cdpKeyPress({ key: 'Tab' }, sendFn, executionContexts, frameTree) + + expect(sendFn).to.have.been.calledWith('Input.dispatchKeyEvent', { + type: 'keyDown', + keyIdentifier: CDP_KEYCODE.Tab, + key: 'Tab', + code: 'Tab', + }) + + expect(sendFn).to.have.been.calledWith('Input.dispatchKeyEvent', { + type: 'keyUp', + keyIdentifier: CDP_KEYCODE.Tab, + key: 'Tab', + code: 'Tab', + }) }) }) @@ -37,15 +163,21 @@ describe('key:press automation command', () => { // typescript would keep this from happening, but it hasn't yet // been checked for correctness since being received by automation // @ts-expect-error - await expect(cdpKeyPress({ key: 'foo' })).to.be.rejectedWith('foo is not supported by \'cy.press()\'.') + await expect(cdpKeyPress({ key: 'foo' }, sendFn, executionContexts, frameTree)).to.be.rejectedWith('foo is not supported by \'cy.press()\'.') }) }) }) describe('bidi', () => { let client: Sinon.SinonStubbedInstance<WebdriverClient> - let context: string + let autContext: string let key: KeyPressSupportedKeys + const iframeElement = { + 'element-6066-11e4-a52e-4f735466cecf': 'uuid-1', + } + const otherElement = { + 'element-6066-11e4-a52e-4f735466cecf': 'uuid-2', + } beforeEach(() => { // can't create a sinon stubbed instance because webdriver doesn't export the constructor. Because it's known that @@ -53,18 +185,55 @@ describe('key:press automation command', () => { // @ts-expect-error client = { inputPerformActions: (sinon as Sinon.SinonSandbox).stub<Parameters<WebdriverClient['inputPerformActions']>, ReturnType<WebdriverClient['inputPerformActions']>>(), + getActiveElement: (sinon as Sinon.SinonSandbox).stub<Parameters<WebdriverClient['getActiveElement']>, ReturnType<WebdriverClient['getActiveElement']>>(), + findElement: (sinon as Sinon.SinonSandbox).stub<Parameters<WebdriverClient['findElement']>, ReturnType<WebdriverClient['findElement']>>(), + scriptEvaluate: (sinon as Sinon.SinonSandbox).stub<Parameters<WebdriverClient['scriptEvaluate']>, ReturnType<WebdriverClient['scriptEvaluate']>>(), } - context = 'someContextId' + autContext = 'someContextId' key = 'Tab' + + client.inputPerformActions.resolves() + }) + + describe('when the aut iframe is not in focus', () => { + beforeEach(() => { + client.findElement.withArgs('css selector ', 'iframe.aut-iframe').resolves(iframeElement) + // @ts-expect-error - webdriver types show this returning a string, but it actually returns an ElementReference, same as findElement + client.getActiveElement.resolves(otherElement) + }) + + it('focuses the frame before dispatching keydown and keyup', async () => { + await bidiKeyPress({ key }, client as WebdriverClient, autContext, 'idSuffix') + expect(client.scriptEvaluate).to.have.been.calledWith({ + expression: 'window.focus()', + target: { context: autContext }, + awaitPromise: false, + }) + + expect(client.inputPerformActions.firstCall.args[0]).to.deep.equal({ + context: autContext, + actions: [{ + type: 'key', + id: 'someContextId-Tab-idSuffix', + actions: [ + { type: 'keyDown', value: BIDI_VALUE[key] }, + { type: 'keyUp', value: BIDI_VALUE[key] }, + ], + }], + }) + }) }) - it('calls client.inputPerformActions with a keydown, pause, and keyup action', () => { - bidiKeyPress({ key }, client as WebdriverClient, context, 'idSuffix') + it('calls client.inputPerformActions with a keydown and keyup action', async () => { + client.findElement.withArgs('css selector ', 'iframe.aut-iframe').resolves(iframeElement) + // @ts-expect-error - webdriver types show this returning a string, but it actually returns an ElementReference, same as findElement + client.getActiveElement.resolves(iframeElement) + await bidiKeyPress({ key }, client as WebdriverClient, autContext, 'idSuffix') expect(client.inputPerformActions.firstCall.args[0]).to.deep.equal({ - context, + context: autContext, actions: [{ type: 'key', id: 'someContextId-Tab-idSuffix', diff --git a/packages/server/test/unit/browsers/bidi_automation_spec.ts b/packages/server/test/unit/browsers/bidi_automation_spec.ts index 75fffc44566e..4f2575df9f69 100644 --- a/packages/server/test/unit/browsers/bidi_automation_spec.ts +++ b/packages/server/test/unit/browsers/bidi_automation_spec.ts @@ -33,7 +33,7 @@ describe('lib/browsers/bidi_automation', () => { it('binds BIDI_EVENTS when a new instance is created', () => { mockWebdriverClient.on = sinon.stub() - const bidiAutoInstance = BidiAutomation.create(mockWebdriverClient, mockAutomationClient) + BidiAutomation.create(mockWebdriverClient, mockAutomationClient) expect(mockWebdriverClient.on).to.have.been.calledWith('network.beforeRequestSent') expect(mockWebdriverClient.on).to.have.been.calledWith('network.responseStarted') @@ -41,7 +41,6 @@ describe('lib/browsers/bidi_automation', () => { expect(mockWebdriverClient.on).to.have.been.calledWith('network.fetchError') expect(mockWebdriverClient.on).to.have.been.calledWith('browsingContext.contextCreated') expect(mockWebdriverClient.on).to.have.been.calledWith('browsingContext.contextDestroyed') - expect(mockAutomationClient.use).to.have.been.calledWith(bidiAutoInstance.automationMiddleware) }) it('unbinds BIDI_EVENTS when close() is called', () => { diff --git a/packages/server/test/unit/browsers/firefox-util_spec.ts b/packages/server/test/unit/browsers/firefox-util_spec.ts new file mode 100644 index 000000000000..08abf506f021 --- /dev/null +++ b/packages/server/test/unit/browsers/firefox-util_spec.ts @@ -0,0 +1,58 @@ +require('../../spec_helper') +import FirefoxUtil from '../../../lib/browsers/firefox-util' +import sinon from 'sinon' +import { expect } from 'chai' +import { Automation } from '../../../lib/automation' +import { Client as WebDriverClient } from 'webdriver' +import { BidiAutomation } from '../../../lib/browsers/bidi_automation' + +describe('Firefox-Util', () => { + let automation: sinon.SinonStubbedInstance<Automation> + let onError: sinon.SinonStub<[Error], void> + let url: string + let remotePort: number | undefined + let webdriverClient: Partial<sinon.SinonStubbedInstance<WebDriverClient>> + let useWebDriverBiDi: boolean + let stubbedBiDiAutomation: sinon.SinonStubbedInstance<BidiAutomation> + + beforeEach(() => { + automation = sinon.createStubInstance(Automation) + onError = sinon.stub<[Error], void>() + url = 'http://some-url' + remotePort = 8000 + webdriverClient = { + sessionSubscribe: sinon.stub< + Parameters<WebDriverClient['sessionSubscribe']>, + ReturnType<WebDriverClient['sessionSubscribe']> + >().resolves(), + browsingContextGetTree: sinon.stub< + Parameters<WebDriverClient['browsingContextGetTree']>, + ReturnType<WebDriverClient['browsingContextGetTree']> + >().resolves({ contexts: [{ + context: 'abc', + children: [], + url: 'http://some-url', + userContext: 'user-context', + }] }), + browsingContextNavigate: sinon.stub< + Parameters<WebDriverClient['browsingContextNavigate']>, + ReturnType<WebDriverClient['browsingContextNavigate']> + >().resolves(), + } + + useWebDriverBiDi = true + stubbedBiDiAutomation = sinon.createStubInstance(BidiAutomation) + // sinon's createStubInstance doesn't stub out this member method + stubbedBiDiAutomation.setTopLevelContextId = sinon.stub() + sinon.stub(BidiAutomation, 'create').returns(stubbedBiDiAutomation) + }) + + describe('.setup()', () => { + describe('when using bidi', () => { + it('registers the automation middleware with the automation system', async () => { + await FirefoxUtil.setup({ automation, onError, url, remotePort, webdriverClient, useWebDriverBiDi }) + expect(automation.use).to.have.been.calledWith(stubbedBiDiAutomation.automationMiddleware) + }) + }) + }) +}) diff --git a/packages/server/test/unit/browsers/firefox_spec.ts b/packages/server/test/unit/browsers/firefox_spec.ts index 41eb5534e8ac..502a638bc3c5 100644 --- a/packages/server/test/unit/browsers/firefox_spec.ts +++ b/packages/server/test/unit/browsers/firefox_spec.ts @@ -119,6 +119,8 @@ describe('lib/browsers/firefox', () => { context: mockContextId, url: 'next-spec-url', }) + + expect(this.automation.use).to.have.been.calledWith(bidiAutomationClient.automationMiddleware) }) }) diff --git a/packages/server/test/unit/cloud/protocol_spec.ts b/packages/server/test/unit/cloud/protocol_spec.ts index 81eb4868896d..5dcb26dcd380 100644 --- a/packages/server/test/unit/cloud/protocol_spec.ts +++ b/packages/server/test/unit/cloud/protocol_spec.ts @@ -350,6 +350,20 @@ describe('lib/cloud/protocol', () => { }) }) + describe('.db', () => { + it('returns the database instance', () => { + const mockDb = { test: 'db' } + + protocolManager['_db'] = mockDb + + expect(protocolManager.db).to.equal(mockDb) + }) + + it('returns undefined when no database is set', () => { + expect(protocolManager.db).to.be.undefined + }) + }) + describe('.uploadCaptureArtifact()', () => { let filePath: string let fileSize: number diff --git a/packages/server/test/unit/cloud/studio_spec.ts b/packages/server/test/unit/cloud/studio_spec.ts index ed353b2ab55d..e13326b62f52 100644 --- a/packages/server/test/unit/cloud/studio_spec.ts +++ b/packages/server/test/unit/cloud/studio_spec.ts @@ -160,9 +160,27 @@ describe('lib/cloud/studio', () => { name: 'chrome', family: 'chromium', channel: 'stable', + displayName: 'Chrome', + version: '120.0.0', + majorVersion: '120', + path: '/path/to/chrome', + isHeaded: true, + isHeadless: false, }) expect(result).to.be.true }) }) + + describe('setProtocolDb', () => { + it('sets the protocol database on the studio server', () => { + const mockDb = { test: 'db' } + + sinon.stub(studio, 'setProtocolDb') + + studioManager.setProtocolDb(mockDb as any) + + expect(studio.setProtocolDb).to.be.calledWith(mockDb) + }) + }) }) diff --git a/packages/server/test/unit/project_spec.js b/packages/server/test/unit/project_spec.js index e0d7b2fb7a07..2bf7ff7d1393 100644 --- a/packages/server/test/unit/project_spec.js +++ b/packages/server/test/unit/project_spec.js @@ -737,6 +737,7 @@ This option will not have an effect in Some-other-name. Tests that rely on web s const mockSetupProtocol = sinon.stub() const mockBeforeSpec = sinon.stub() const mockAccessStudioLLM = sinon.stub().resolves(true) + const mockSetProtocolDb = sinon.stub() this.project.spec = {} this.project.ctx.coreData.studio = { @@ -744,7 +745,9 @@ This option will not have an effect in Some-other-name. Tests that rely on web s protocolManager: { setupProtocol: mockSetupProtocol, beforeSpec: mockBeforeSpec, + db: { test: 'db' }, }, + setProtocolDb: mockSetProtocolDb, } sinon.stub(browsers, 'connectProtocolToBrowser').resolves() @@ -793,6 +796,7 @@ This option will not have an effect in Some-other-name. Tests that rely on web s }) expect(this.project['_protocolManager']).to.eq(this.project.ctx.coreData.studio.protocolManager) + expect(mockSetProtocolDb).to.be.calledWith({ test: 'db' }) }) it('passes onStudioInit callback with AI enabled but no protocol manager', async function () { diff --git a/packages/types/src/protocol.ts b/packages/types/src/protocol.ts index 0bd6c06b6468..fc1c3c948f99 100644 --- a/packages/types/src/protocol.ts +++ b/packages/types/src/protocol.ts @@ -1,4 +1,4 @@ -import type { Database } from 'better-sqlite3' +import type Database from 'better-sqlite3' import type ProtocolMapping from 'devtools-protocol/types/protocol-mapping' import type { IncomingHttpHeaders } from 'http' import type { Readable } from 'stream' @@ -38,7 +38,7 @@ export interface AppCaptureProtocolCommon { export interface AppCaptureProtocolInterface extends AppCaptureProtocolCommon { getDbMetadata (): { offset: number, size: number } | undefined - beforeSpec ({ spec, workingDirectory, archivePath, dbPath, db }: { spec: FoundSpec & { instanceId: string }, workingDirectory: string, archivePath: string, dbPath: string, db: Database }): void + beforeSpec ({ spec, workingDirectory, archivePath, dbPath, db }: { spec: FoundSpec & { instanceId: string }, workingDirectory: string, archivePath: string, dbPath: string, db: Database.Database }): void uploadStallSamplingInterval: () => number connectToBrowser (cdpClient: CDPClient): Promise<void> } @@ -138,6 +138,7 @@ export interface ProtocolManagerShape extends AppCaptureProtocolCommon { uploadCaptureArtifact(artifact: CaptureArtifact): Promise<UploadCaptureArtifactResult | undefined> connectToBrowser (cdpClient: CDPClient): Promise<void> close (): void + db?: Database.Database } type Response = { diff --git a/packages/types/src/studio/studio-server-types.ts b/packages/types/src/studio/studio-server-types.ts index 102639ad48b9..3cfc04cb2144 100644 --- a/packages/types/src/studio/studio-server-types.ts +++ b/packages/types/src/studio/studio-server-types.ts @@ -2,6 +2,7 @@ import type { Router } from 'express' import type { AxiosInstance } from 'axios' +import type Database from 'better-sqlite3' interface RetryOptions { maxAttempts: number @@ -32,6 +33,7 @@ export interface StudioServerOptions { export interface StudioServerShape { initializeRoutes(router: Router): void canAccessStudioAI(browser: Cypress.Browser): Promise<boolean> + setProtocolDb(database: Database.Database): void } export interface StudioServerDefaultShape { diff --git a/patches/snap-shot-core+10.2.0.dev.patch b/patches/snap-shot-core+10.2.4.dev.patch similarity index 100% rename from patches/snap-shot-core+10.2.0.dev.patch rename to patches/snap-shot-core+10.2.4.dev.patch diff --git a/scripts/binary/binary-cleanup.js b/scripts/binary/binary-cleanup.js index 796e8b390cc7..bd4ea05fb964 100644 --- a/scripts/binary/binary-cleanup.js +++ b/scripts/binary/binary-cleanup.js @@ -49,7 +49,7 @@ const getDependencyPathsToKeep = async (buildAppDir) => { 'node_modules/webpack-dev-server/lib/Server.js', 'node_modules/html-webpack-plugin-4/index.js', 'node_modules/html-webpack-plugin-5/index.js', - 'node_modules/mocha-7.0.1/index.js', + 'node_modules/mocha-7.2.0/index.js', 'packages/server/node_modules/webdriver/build/index.js', // dependencies needed for geckodriver when running firefox in the binary 'node_modules/pump/index.js', diff --git a/system-tests/__snapshots__/protocol_spec.js b/system-tests/__snapshots__/protocol_spec.js index cee63879b112..8a3b23dd9114 100644 --- a/system-tests/__snapshots__/protocol_spec.js +++ b/system-tests/__snapshots__/protocol_spec.js @@ -73,7 +73,7 @@ exports['e2e events'] = ` "line": 7, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:3131/__cypress/tests?p=cypress/e2e/protocol.cy.js:15:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:3131/__cypress/tests?p=cypress/e2e/protocol.cy.js:15:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": 0, @@ -114,7 +114,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -141,7 +141,7 @@ exports['e2e events'] = ` "line": 5, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:16:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:16:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": 0, @@ -182,7 +182,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -209,7 +209,7 @@ exports['e2e events'] = ` "line": 12, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:24:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:24:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": 0, @@ -250,7 +250,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -277,7 +277,7 @@ exports['e2e events'] = ` "line": 17, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:28:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:28:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": 0, @@ -318,7 +318,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -345,7 +345,7 @@ exports['e2e events'] = ` "line": 22, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:32:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:32:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": 0, @@ -386,7 +386,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -413,7 +413,7 @@ exports['e2e events'] = ` "line": 32, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:42:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:42:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": 0, @@ -454,7 +454,7 @@ exports['e2e events'] = ` "line": 38, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:47:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:47:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -481,7 +481,7 @@ exports['e2e events'] = ` "line": 39, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:50:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:50:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": 0, @@ -522,7 +522,7 @@ exports['e2e events'] = ` "line": 38, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:47:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:47:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -549,7 +549,7 @@ exports['e2e events'] = ` "line": 46, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:58:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:58:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": 0, @@ -590,7 +590,7 @@ exports['e2e events'] = ` "line": 54, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:67:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:67:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -617,7 +617,7 @@ exports['e2e events'] = ` "line": 55, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:70:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:70:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": 0, @@ -647,7 +647,7 @@ exports['e2e events'] = ` "line": 2, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/shadow-dom.cy.js:9:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/shadow-dom.cy.js:9:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": 0, @@ -677,7 +677,7 @@ exports['e2e events'] = ` "line": 7, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/shadow-dom.cy.js:15:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/shadow-dom.cy.js:15:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": 0, @@ -752,7 +752,7 @@ exports['e2e events'] = ` "line": 7, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:3131/__cypress/tests?p=cypress/e2e/protocol.cy.js:15:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:3131/__cypress/tests?p=cypress/e2e/protocol.cy.js:15:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "final": true, "currentRetry": 0, @@ -802,7 +802,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -838,7 +838,7 @@ exports['e2e events'] = ` "line": 5, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:16:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:16:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "final": true, "currentRetry": 0, @@ -890,7 +890,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -926,7 +926,7 @@ exports['e2e events'] = ` "line": 12, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:24:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:24:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "final": true, "currentRetry": 0, @@ -978,7 +978,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -1014,7 +1014,7 @@ exports['e2e events'] = ` "line": 17, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:28:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:28:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "final": true, "currentRetry": 0, @@ -1066,7 +1066,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -1102,7 +1102,7 @@ exports['e2e events'] = ` "line": 22, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:32:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:32:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "final": true, "currentRetry": 0, @@ -1154,7 +1154,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -1190,7 +1190,7 @@ exports['e2e events'] = ` "line": 32, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:42:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:42:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "final": true, "currentRetry": 0, @@ -1242,7 +1242,7 @@ exports['e2e events'] = ` "line": 38, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:47:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:47:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -1278,7 +1278,7 @@ exports['e2e events'] = ` "line": 39, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:50:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:50:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "final": true, "currentRetry": 0, @@ -1330,7 +1330,7 @@ exports['e2e events'] = ` "line": 38, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:47:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:47:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -1366,7 +1366,7 @@ exports['e2e events'] = ` "line": 46, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:58:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:58:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "final": true, "currentRetry": 0, @@ -1418,7 +1418,7 @@ exports['e2e events'] = ` "line": 54, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:67:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:67:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -1454,7 +1454,7 @@ exports['e2e events'] = ` "line": 55, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:70:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:70:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "final": true, "currentRetry": 0, @@ -1502,7 +1502,7 @@ exports['e2e events'] = ` "line": 2, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/shadow-dom.cy.js:9:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/shadow-dom.cy.js:9:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -1552,7 +1552,7 @@ exports['e2e events'] = ` "line": 7, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/shadow-dom.cy.js:15:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/shadow-dom.cy.js:15:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -1629,7 +1629,7 @@ exports['e2e events'] = ` "line": 7, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:3131/__cypress/tests?p=cypress/e2e/protocol.cy.js:15:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:3131/__cypress/tests?p=cypress/e2e/protocol.cy.js:15:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "final": true, "currentRetry": 0, @@ -1676,7 +1676,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -1713,7 +1713,7 @@ exports['e2e events'] = ` "line": 5, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:16:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:16:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "final": true, "currentRetry": 0, @@ -1760,7 +1760,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -1797,7 +1797,7 @@ exports['e2e events'] = ` "line": 12, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:24:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:24:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "final": true, "currentRetry": 0, @@ -1844,7 +1844,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -1881,7 +1881,7 @@ exports['e2e events'] = ` "line": 17, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:28:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:28:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "final": true, "currentRetry": 0, @@ -1928,7 +1928,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -1965,7 +1965,7 @@ exports['e2e events'] = ` "line": 22, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:32:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:32:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "final": true, "currentRetry": 0, @@ -2012,7 +2012,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -2049,7 +2049,7 @@ exports['e2e events'] = ` "line": 32, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:42:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:42:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "final": true, "currentRetry": 0, @@ -2096,7 +2096,7 @@ exports['e2e events'] = ` "line": 38, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:47:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:47:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -2133,7 +2133,7 @@ exports['e2e events'] = ` "line": 39, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:50:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:50:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "final": true, "currentRetry": 0, @@ -2180,7 +2180,7 @@ exports['e2e events'] = ` "line": 38, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:47:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:47:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -2217,7 +2217,7 @@ exports['e2e events'] = ` "line": 46, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:58:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:58:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "final": true, "currentRetry": 0, @@ -2264,7 +2264,7 @@ exports['e2e events'] = ` "line": 54, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:67:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:67:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -2301,7 +2301,7 @@ exports['e2e events'] = ` "line": 55, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:70:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:70:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "final": true, "currentRetry": 0, @@ -2347,7 +2347,7 @@ exports['e2e events'] = ` "line": 2, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/shadow-dom.cy.js:9:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/shadow-dom.cy.js:9:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -2393,7 +2393,7 @@ exports['e2e events'] = ` "line": 7, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/shadow-dom.cy.js:15:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/shadow-dom.cy.js:15:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -2455,7 +2455,7 @@ exports['e2e events'] = ` "line": 2, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/protocol.cy.js:11:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/protocol.cy.js:11:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": -1, @@ -2479,7 +2479,7 @@ exports['e2e events'] = ` "line": 7, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/protocol.cy.js:15:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/protocol.cy.js:15:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": -1, @@ -2578,7 +2578,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" }, "retries": -1, "_slow": 10000, @@ -2600,7 +2600,7 @@ exports['e2e events'] = ` "line": 5, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:16:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:16:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": -1, @@ -2639,7 +2639,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -2670,7 +2670,7 @@ exports['e2e events'] = ` "line": 12, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:24:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:24:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": -1, @@ -2709,7 +2709,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -2740,7 +2740,7 @@ exports['e2e events'] = ` "line": 17, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:28:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:28:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": -1, @@ -2779,7 +2779,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -2810,7 +2810,7 @@ exports['e2e events'] = ` "line": 22, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:32:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:32:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": -1, @@ -2849,7 +2849,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -2880,7 +2880,7 @@ exports['e2e events'] = ` "line": 32, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:42:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:42:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": -1, @@ -2919,7 +2919,7 @@ exports['e2e events'] = ` "line": 4, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:13:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -2956,7 +2956,7 @@ exports['e2e events'] = ` "line": 38, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:47:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:47:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" }, "retries": -1, "_slow": 10000, @@ -2978,7 +2978,7 @@ exports['e2e events'] = ` "line": 39, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:50:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:50:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": -1, @@ -3017,7 +3017,7 @@ exports['e2e events'] = ` "line": 38, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:47:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:47:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -3048,7 +3048,7 @@ exports['e2e events'] = ` "line": 46, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:58:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:58:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": -1, @@ -3087,7 +3087,7 @@ exports['e2e events'] = ` "line": 38, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:47:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:47:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -3124,7 +3124,7 @@ exports['e2e events'] = ` "line": 54, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:67:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:67:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" }, "retries": -1, "_slow": 10000, @@ -3146,7 +3146,7 @@ exports['e2e events'] = ` "line": 55, "column": 4, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:70:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:70:5)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:185:16)" }, "currentRetry": 0, "retries": -1, @@ -3185,7 +3185,7 @@ exports['e2e events'] = ` "line": 54, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:67:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/test-isolation.cy.js:67:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)" } } ], @@ -3259,7 +3259,7 @@ exports['e2e events'] = ` "line": 2, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/shadow-dom.cy.js:9:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/shadow-dom.cy.js:9:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": -1, @@ -3290,7 +3290,7 @@ exports['e2e events'] = ` "line": 7, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/shadow-dom.cy.js:15:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.eval (http://localhost:2121/__cypress/tests?p=cypress/e2e/shadow-dom.cy.js:15:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": -1, @@ -6184,7 +6184,7 @@ exports['component events - experimentalSingleTabRunMode: true'] = ` "line": 5, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": 0, @@ -6214,7 +6214,7 @@ exports['component events - experimentalSingleTabRunMode: true'] = ` "line": 11, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": 0, @@ -6244,7 +6244,7 @@ exports['component events - experimentalSingleTabRunMode: true'] = ` "line": 5, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": 0, @@ -6274,7 +6274,7 @@ exports['component events - experimentalSingleTabRunMode: true'] = ` "line": 11, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": 0, @@ -6322,7 +6322,7 @@ exports['component events - experimentalSingleTabRunMode: true'] = ` "line": 5, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -6372,7 +6372,7 @@ exports['component events - experimentalSingleTabRunMode: true'] = ` "line": 11, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -6420,7 +6420,7 @@ exports['component events - experimentalSingleTabRunMode: true'] = ` "line": 5, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -6470,7 +6470,7 @@ exports['component events - experimentalSingleTabRunMode: true'] = ` "line": 11, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -6520,7 +6520,7 @@ exports['component events - experimentalSingleTabRunMode: true'] = ` "line": 5, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -6566,7 +6566,7 @@ exports['component events - experimentalSingleTabRunMode: true'] = ` "line": 11, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -6612,7 +6612,7 @@ exports['component events - experimentalSingleTabRunMode: true'] = ` "line": 5, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -6658,7 +6658,7 @@ exports['component events - experimentalSingleTabRunMode: true'] = ` "line": 11, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -6717,7 +6717,7 @@ exports['component events - experimentalSingleTabRunMode: true'] = ` "line": 5, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": -1, @@ -6748,7 +6748,7 @@ exports['component events - experimentalSingleTabRunMode: true'] = ` "line": 11, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": -1, @@ -6820,7 +6820,7 @@ exports['component events - experimentalSingleTabRunMode: true'] = ` "line": 5, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": -1, @@ -6851,7 +6851,7 @@ exports['component events - experimentalSingleTabRunMode: true'] = ` "line": 11, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": -1, @@ -8003,7 +8003,7 @@ exports['component events - experimentalSingleTabRunMode: false'] = ` "line": 5, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": 0, @@ -8033,7 +8033,7 @@ exports['component events - experimentalSingleTabRunMode: false'] = ` "line": 11, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": 0, @@ -8063,7 +8063,7 @@ exports['component events - experimentalSingleTabRunMode: false'] = ` "line": 5, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": 0, @@ -8093,7 +8093,7 @@ exports['component events - experimentalSingleTabRunMode: false'] = ` "line": 11, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": 0, @@ -8141,7 +8141,7 @@ exports['component events - experimentalSingleTabRunMode: false'] = ` "line": 5, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -8191,7 +8191,7 @@ exports['component events - experimentalSingleTabRunMode: false'] = ` "line": 11, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -8239,7 +8239,7 @@ exports['component events - experimentalSingleTabRunMode: false'] = ` "line": 5, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -8289,7 +8289,7 @@ exports['component events - experimentalSingleTabRunMode: false'] = ` "line": 11, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -8339,7 +8339,7 @@ exports['component events - experimentalSingleTabRunMode: false'] = ` "line": 5, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -8385,7 +8385,7 @@ exports['component events - experimentalSingleTabRunMode: false'] = ` "line": 11, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -8431,7 +8431,7 @@ exports['component events - experimentalSingleTabRunMode: false'] = ` "line": 5, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -8477,7 +8477,7 @@ exports['component events - experimentalSingleTabRunMode: false'] = ` "line": 11, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "final": true, "currentRetry": 0, @@ -8536,7 +8536,7 @@ exports['component events - experimentalSingleTabRunMode: false'] = ` "line": 5, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": -1, @@ -8567,7 +8567,7 @@ exports['component events - experimentalSingleTabRunMode: false'] = ` "line": 11, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": -1, @@ -8639,7 +8639,7 @@ exports['component events - experimentalSingleTabRunMode: false'] = ` "line": 5, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:17:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": -1, @@ -8670,7 +8670,7 @@ exports['component events - experimentalSingleTabRunMode: false'] = ` "line": 11, "column": 2, "whitespace": " ", - "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:140:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" + "stack": "Error\\n at Suite.<anonymous> (http://localhost:2121/__cypress/src/spec-0.js:22:3)\\n at Object.create (cypress:///../driver/node_modules/mocha/lib/interfaces/common.js:141:19)\\n at context.describe.context.context (cypress:///../driver/node_modules/mocha/lib/interfaces/bdd.js:42:27)\\n at createRunnable (cypress:///../driver/src/cypress/mocha.ts:126:31)\\n at eval (cypress:///../driver/src/cypress/mocha.ts:187:14)" }, "currentRetry": 0, "retries": -1, diff --git a/system-tests/projects/plugin-extension/ext/background.js b/system-tests/projects/plugin-extension/ext/content.js similarity index 100% rename from system-tests/projects/plugin-extension/ext/background.js rename to system-tests/projects/plugin-extension/ext/content.js diff --git a/system-tests/projects/plugin-extension/ext/manifest.json b/system-tests/projects/plugin-extension/ext/manifest.json index 68a6c0163a9c..6c1e65276c44 100644 --- a/system-tests/projects/plugin-extension/ext/manifest.json +++ b/system-tests/projects/plugin-extension/ext/manifest.json @@ -3,8 +3,11 @@ "version": "0", "description": "tests adding user extension into Cypress", "permissions": [ - "tabs", - "webNavigation", + "tabs" + ], + "host_permissions": [ + "http://*/*", + "https://*/*", "<all_urls>" ], "content_scripts": [ @@ -17,11 +20,11 @@ "*://*/__/*" ], "js": [ - "background.js" + "content.js" ], "run_at": "document_end", "all_frames": true } ], - "manifest_version": 2 + "manifest_version": 3 } diff --git a/tooling/v8-snapshot/cache/darwin/snapshot-meta.json b/tooling/v8-snapshot/cache/darwin/snapshot-meta.json index c09de3d0c607..af516a808aa9 100644 --- a/tooling/v8-snapshot/cache/darwin/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/darwin/snapshot-meta.json @@ -33,8 +33,8 @@ "./node_modules/jsonfile/index.js", "./node_modules/make-dir/index.js", "./node_modules/minimatch/minimatch.js", - "./node_modules/mocha-7.0.1/node_modules/debug/src/node.js", - "./node_modules/mocha-7.0.1/node_modules/glob/node_modules/minimatch/minimatch.js", + "./node_modules/mocha-7.2.0/node_modules/debug/src/node.js", + "./node_modules/mocha-7.2.0/node_modules/glob/node_modules/minimatch/minimatch.js", "./node_modules/mocha-junit-reporter/node_modules/debug/src/node.js", "./node_modules/mocha/node_modules/debug/src/node.js", "./node_modules/morgan/node_modules/debug/src/node.js", @@ -345,28 +345,28 @@ "./node_modules/minizlib/constants.js", "./node_modules/minizlib/index.js", "./node_modules/minizlib/node_modules/minipass/index.js", - "./node_modules/mocha-7.0.1/index.js", - "./node_modules/mocha-7.0.1/lib/hook.js", - "./node_modules/mocha-7.0.1/lib/mocha.js", - "./node_modules/mocha-7.0.1/lib/reporters/base.js", - "./node_modules/mocha-7.0.1/lib/reporters/dot.js", - "./node_modules/mocha-7.0.1/lib/reporters/landing.js", - "./node_modules/mocha-7.0.1/lib/reporters/list.js", - "./node_modules/mocha-7.0.1/lib/reporters/min.js", - "./node_modules/mocha-7.0.1/lib/reporters/nyan.js", - "./node_modules/mocha-7.0.1/lib/reporters/progress.js", - "./node_modules/mocha-7.0.1/lib/reporters/spec.js", - "./node_modules/mocha-7.0.1/lib/reporters/tap.js", - "./node_modules/mocha-7.0.1/lib/reporters/xunit.js", - "./node_modules/mocha-7.0.1/lib/runnable.js", - "./node_modules/mocha-7.0.1/lib/runner.js", - "./node_modules/mocha-7.0.1/lib/suite.js", - "./node_modules/mocha-7.0.1/lib/test.js", - "./node_modules/mocha-7.0.1/node_modules/debug/src/browser.js", - "./node_modules/mocha-7.0.1/node_modules/debug/src/index.js", - "./node_modules/mocha-7.0.1/node_modules/glob/glob.js", - "./node_modules/mocha-7.0.1/node_modules/glob/sync.js", - "./node_modules/mocha-7.0.1/node_modules/supports-color/index.js", + "./node_modules/mocha-7.2.0/index.js", + "./node_modules/mocha-7.2.0/lib/hook.js", + "./node_modules/mocha-7.2.0/lib/mocha.js", + "./node_modules/mocha-7.2.0/lib/reporters/base.js", + "./node_modules/mocha-7.2.0/lib/reporters/dot.js", + "./node_modules/mocha-7.2.0/lib/reporters/landing.js", + "./node_modules/mocha-7.2.0/lib/reporters/list.js", + "./node_modules/mocha-7.2.0/lib/reporters/min.js", + "./node_modules/mocha-7.2.0/lib/reporters/nyan.js", + "./node_modules/mocha-7.2.0/lib/reporters/progress.js", + "./node_modules/mocha-7.2.0/lib/reporters/spec.js", + "./node_modules/mocha-7.2.0/lib/reporters/tap.js", + "./node_modules/mocha-7.2.0/lib/reporters/xunit.js", + "./node_modules/mocha-7.2.0/lib/runnable.js", + "./node_modules/mocha-7.2.0/lib/runner.js", + "./node_modules/mocha-7.2.0/lib/suite.js", + "./node_modules/mocha-7.2.0/lib/test.js", + "./node_modules/mocha-7.2.0/node_modules/debug/src/browser.js", + "./node_modules/mocha-7.2.0/node_modules/debug/src/index.js", + "./node_modules/mocha-7.2.0/node_modules/glob/glob.js", + "./node_modules/mocha-7.2.0/node_modules/glob/sync.js", + "./node_modules/mocha-7.2.0/node_modules/supports-color/index.js", "./node_modules/mocha-junit-reporter/index.js", "./node_modules/mocha/index.js", "./node_modules/mocha/lib/hook.js", @@ -2229,7 +2229,6 @@ "./node_modules/is-regexp/index.js", "./node_modules/is-stream/index.js", "./node_modules/is-typedarray/index.js", - "./node_modules/isarray/index.js", "./node_modules/isbinaryfile/lib/index.js", "./node_modules/isexe/mode.js", "./node_modules/isexe/windows.js", @@ -2487,38 +2486,39 @@ "./node_modules/min-indent/index.js", "./node_modules/minimatch/node_modules/brace-expansion/index.js", "./node_modules/minimist/index.js", - "./node_modules/mocha-7.0.1/lib/browser/progress.js", - "./node_modules/mocha-7.0.1/lib/context.js", - "./node_modules/mocha-7.0.1/lib/errors.js", - "./node_modules/mocha-7.0.1/lib/growl.js", - "./node_modules/mocha-7.0.1/lib/interfaces/bdd.js", - "./node_modules/mocha-7.0.1/lib/interfaces/common.js", - "./node_modules/mocha-7.0.1/lib/interfaces/exports.js", - "./node_modules/mocha-7.0.1/lib/interfaces/index.js", - "./node_modules/mocha-7.0.1/lib/interfaces/qunit.js", - "./node_modules/mocha-7.0.1/lib/interfaces/tdd.js", - "./node_modules/mocha-7.0.1/lib/mocharc.json", - "./node_modules/mocha-7.0.1/lib/pending.js", - "./node_modules/mocha-7.0.1/lib/reporters/doc.js", - "./node_modules/mocha-7.0.1/lib/reporters/html.js", - "./node_modules/mocha-7.0.1/lib/reporters/index.js", - "./node_modules/mocha-7.0.1/lib/reporters/json-stream.js", - "./node_modules/mocha-7.0.1/lib/reporters/json.js", - "./node_modules/mocha-7.0.1/lib/reporters/markdown.js", - "./node_modules/mocha-7.0.1/lib/stats-collector.js", - "./node_modules/mocha-7.0.1/lib/utils.js", - "./node_modules/mocha-7.0.1/node_modules/brace-expansion/index.js", - "./node_modules/mocha-7.0.1/node_modules/debug/node_modules/ms/index.js", - "./node_modules/mocha-7.0.1/node_modules/debug/src/common.js", - "./node_modules/mocha-7.0.1/node_modules/glob/common.js", - "./node_modules/mocha-7.0.1/node_modules/has-flag/index.js", - "./node_modules/mocha-7.0.1/node_modules/mkdirp/index.js", - "./node_modules/mocha-7.0.1/node_modules/ms/index.js", - "./node_modules/mocha-7.0.1/node_modules/object.assign/implementation.js", - "./node_modules/mocha-7.0.1/node_modules/object.assign/index.js", - "./node_modules/mocha-7.0.1/node_modules/object.assign/polyfill.js", - "./node_modules/mocha-7.0.1/node_modules/object.assign/shim.js", - "./node_modules/mocha-7.0.1/package.json", + "./node_modules/mocha-7.2.0/lib/browser/progress.js", + "./node_modules/mocha-7.2.0/lib/context.js", + "./node_modules/mocha-7.2.0/lib/errors.js", + "./node_modules/mocha-7.2.0/lib/esm-utils.js", + "./node_modules/mocha-7.2.0/lib/growl.js", + "./node_modules/mocha-7.2.0/lib/interfaces/bdd.js", + "./node_modules/mocha-7.2.0/lib/interfaces/common.js", + "./node_modules/mocha-7.2.0/lib/interfaces/exports.js", + "./node_modules/mocha-7.2.0/lib/interfaces/index.js", + "./node_modules/mocha-7.2.0/lib/interfaces/qunit.js", + "./node_modules/mocha-7.2.0/lib/interfaces/tdd.js", + "./node_modules/mocha-7.2.0/lib/mocharc.json", + "./node_modules/mocha-7.2.0/lib/pending.js", + "./node_modules/mocha-7.2.0/lib/reporters/doc.js", + "./node_modules/mocha-7.2.0/lib/reporters/html.js", + "./node_modules/mocha-7.2.0/lib/reporters/index.js", + "./node_modules/mocha-7.2.0/lib/reporters/json-stream.js", + "./node_modules/mocha-7.2.0/lib/reporters/json.js", + "./node_modules/mocha-7.2.0/lib/reporters/markdown.js", + "./node_modules/mocha-7.2.0/lib/stats-collector.js", + "./node_modules/mocha-7.2.0/lib/utils.js", + "./node_modules/mocha-7.2.0/node_modules/brace-expansion/index.js", + "./node_modules/mocha-7.2.0/node_modules/debug/node_modules/ms/index.js", + "./node_modules/mocha-7.2.0/node_modules/debug/src/common.js", + "./node_modules/mocha-7.2.0/node_modules/glob/common.js", + "./node_modules/mocha-7.2.0/node_modules/has-flag/index.js", + "./node_modules/mocha-7.2.0/node_modules/mkdirp/index.js", + "./node_modules/mocha-7.2.0/node_modules/ms/index.js", + "./node_modules/mocha-7.2.0/node_modules/object.assign/implementation.js", + "./node_modules/mocha-7.2.0/node_modules/object.assign/index.js", + "./node_modules/mocha-7.2.0/node_modules/object.assign/polyfill.js", + "./node_modules/mocha-7.2.0/node_modules/object.assign/shim.js", + "./node_modules/mocha-7.2.0/package.json", "./node_modules/mocha-junit-reporter/node_modules/mkdirp/index.js", "./node_modules/mocha-junit-reporter/node_modules/mkdirp/lib/find-made.js", "./node_modules/mocha-junit-reporter/node_modules/mkdirp/lib/mkdirp-manual.js", @@ -3179,6 +3179,7 @@ "./node_modules/react-docgen/node_modules/doctrine/package.json", "./node_modules/react-docgen/node_modules/strip-indent/index.js", "./node_modules/readable-stream/lib/internal/streams/destroy.js", + "./node_modules/readable-stream/node_modules/isarray/index.js", "./node_modules/recast/node_modules/ast-types/def/babel-core.js", "./node_modules/recast/node_modules/ast-types/def/babel.js", "./node_modules/recast/node_modules/ast-types/def/core-operators.js", @@ -4229,5 +4230,5 @@ "./tooling/v8-snapshot/cache/darwin/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "a83ec07b936fc8a327f5d598ffadd5d272171e21824eabfe913646bf73ca4d43" + "deferredHash": "712617e51b2b166bd89f4eeb0c7840516ff71d7c469fb06777924ee845bd6fb4" } \ No newline at end of file diff --git a/tooling/v8-snapshot/cache/linux/snapshot-meta.json b/tooling/v8-snapshot/cache/linux/snapshot-meta.json index 55bfbc2b7edb..d2a3eba7dbcc 100644 --- a/tooling/v8-snapshot/cache/linux/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/linux/snapshot-meta.json @@ -33,8 +33,8 @@ "./node_modules/jsonfile/index.js", "./node_modules/make-dir/index.js", "./node_modules/minimatch/minimatch.js", - "./node_modules/mocha-7.0.1/node_modules/debug/src/node.js", - "./node_modules/mocha-7.0.1/node_modules/glob/node_modules/minimatch/minimatch.js", + "./node_modules/mocha-7.2.0/node_modules/debug/src/node.js", + "./node_modules/mocha-7.2.0/node_modules/glob/node_modules/minimatch/minimatch.js", "./node_modules/mocha-junit-reporter/node_modules/debug/src/node.js", "./node_modules/mocha/node_modules/debug/src/node.js", "./node_modules/morgan/node_modules/debug/src/node.js", @@ -344,28 +344,28 @@ "./node_modules/minizlib/constants.js", "./node_modules/minizlib/index.js", "./node_modules/minizlib/node_modules/minipass/index.js", - "./node_modules/mocha-7.0.1/index.js", - "./node_modules/mocha-7.0.1/lib/hook.js", - "./node_modules/mocha-7.0.1/lib/mocha.js", - "./node_modules/mocha-7.0.1/lib/reporters/base.js", - "./node_modules/mocha-7.0.1/lib/reporters/dot.js", - "./node_modules/mocha-7.0.1/lib/reporters/landing.js", - "./node_modules/mocha-7.0.1/lib/reporters/list.js", - "./node_modules/mocha-7.0.1/lib/reporters/min.js", - "./node_modules/mocha-7.0.1/lib/reporters/nyan.js", - "./node_modules/mocha-7.0.1/lib/reporters/progress.js", - "./node_modules/mocha-7.0.1/lib/reporters/spec.js", - "./node_modules/mocha-7.0.1/lib/reporters/tap.js", - "./node_modules/mocha-7.0.1/lib/reporters/xunit.js", - "./node_modules/mocha-7.0.1/lib/runnable.js", - "./node_modules/mocha-7.0.1/lib/runner.js", - "./node_modules/mocha-7.0.1/lib/suite.js", - "./node_modules/mocha-7.0.1/lib/test.js", - "./node_modules/mocha-7.0.1/node_modules/debug/src/browser.js", - "./node_modules/mocha-7.0.1/node_modules/debug/src/index.js", - "./node_modules/mocha-7.0.1/node_modules/glob/glob.js", - "./node_modules/mocha-7.0.1/node_modules/glob/sync.js", - "./node_modules/mocha-7.0.1/node_modules/supports-color/index.js", + "./node_modules/mocha-7.2.0/index.js", + "./node_modules/mocha-7.2.0/lib/hook.js", + "./node_modules/mocha-7.2.0/lib/mocha.js", + "./node_modules/mocha-7.2.0/lib/reporters/base.js", + "./node_modules/mocha-7.2.0/lib/reporters/dot.js", + "./node_modules/mocha-7.2.0/lib/reporters/landing.js", + "./node_modules/mocha-7.2.0/lib/reporters/list.js", + "./node_modules/mocha-7.2.0/lib/reporters/min.js", + "./node_modules/mocha-7.2.0/lib/reporters/nyan.js", + "./node_modules/mocha-7.2.0/lib/reporters/progress.js", + "./node_modules/mocha-7.2.0/lib/reporters/spec.js", + "./node_modules/mocha-7.2.0/lib/reporters/tap.js", + "./node_modules/mocha-7.2.0/lib/reporters/xunit.js", + "./node_modules/mocha-7.2.0/lib/runnable.js", + "./node_modules/mocha-7.2.0/lib/runner.js", + "./node_modules/mocha-7.2.0/lib/suite.js", + "./node_modules/mocha-7.2.0/lib/test.js", + "./node_modules/mocha-7.2.0/node_modules/debug/src/browser.js", + "./node_modules/mocha-7.2.0/node_modules/debug/src/index.js", + "./node_modules/mocha-7.2.0/node_modules/glob/glob.js", + "./node_modules/mocha-7.2.0/node_modules/glob/sync.js", + "./node_modules/mocha-7.2.0/node_modules/supports-color/index.js", "./node_modules/mocha-junit-reporter/index.js", "./node_modules/mocha/index.js", "./node_modules/mocha/lib/hook.js", @@ -2230,7 +2230,6 @@ "./node_modules/is-regexp/index.js", "./node_modules/is-stream/index.js", "./node_modules/is-typedarray/index.js", - "./node_modules/isarray/index.js", "./node_modules/isbinaryfile/lib/index.js", "./node_modules/isexe/mode.js", "./node_modules/isexe/windows.js", @@ -2488,38 +2487,39 @@ "./node_modules/min-indent/index.js", "./node_modules/minimatch/node_modules/brace-expansion/index.js", "./node_modules/minimist/index.js", - "./node_modules/mocha-7.0.1/lib/browser/progress.js", - "./node_modules/mocha-7.0.1/lib/context.js", - "./node_modules/mocha-7.0.1/lib/errors.js", - "./node_modules/mocha-7.0.1/lib/growl.js", - "./node_modules/mocha-7.0.1/lib/interfaces/bdd.js", - "./node_modules/mocha-7.0.1/lib/interfaces/common.js", - "./node_modules/mocha-7.0.1/lib/interfaces/exports.js", - "./node_modules/mocha-7.0.1/lib/interfaces/index.js", - "./node_modules/mocha-7.0.1/lib/interfaces/qunit.js", - "./node_modules/mocha-7.0.1/lib/interfaces/tdd.js", - "./node_modules/mocha-7.0.1/lib/mocharc.json", - "./node_modules/mocha-7.0.1/lib/pending.js", - "./node_modules/mocha-7.0.1/lib/reporters/doc.js", - "./node_modules/mocha-7.0.1/lib/reporters/html.js", - "./node_modules/mocha-7.0.1/lib/reporters/index.js", - "./node_modules/mocha-7.0.1/lib/reporters/json-stream.js", - "./node_modules/mocha-7.0.1/lib/reporters/json.js", - "./node_modules/mocha-7.0.1/lib/reporters/markdown.js", - "./node_modules/mocha-7.0.1/lib/stats-collector.js", - "./node_modules/mocha-7.0.1/lib/utils.js", - "./node_modules/mocha-7.0.1/node_modules/brace-expansion/index.js", - "./node_modules/mocha-7.0.1/node_modules/debug/node_modules/ms/index.js", - "./node_modules/mocha-7.0.1/node_modules/debug/src/common.js", - "./node_modules/mocha-7.0.1/node_modules/glob/common.js", - "./node_modules/mocha-7.0.1/node_modules/has-flag/index.js", - "./node_modules/mocha-7.0.1/node_modules/mkdirp/index.js", - "./node_modules/mocha-7.0.1/node_modules/ms/index.js", - "./node_modules/mocha-7.0.1/node_modules/object.assign/implementation.js", - "./node_modules/mocha-7.0.1/node_modules/object.assign/index.js", - "./node_modules/mocha-7.0.1/node_modules/object.assign/polyfill.js", - "./node_modules/mocha-7.0.1/node_modules/object.assign/shim.js", - "./node_modules/mocha-7.0.1/package.json", + "./node_modules/mocha-7.2.0/lib/browser/progress.js", + "./node_modules/mocha-7.2.0/lib/context.js", + "./node_modules/mocha-7.2.0/lib/errors.js", + "./node_modules/mocha-7.2.0/lib/esm-utils.js", + "./node_modules/mocha-7.2.0/lib/growl.js", + "./node_modules/mocha-7.2.0/lib/interfaces/bdd.js", + "./node_modules/mocha-7.2.0/lib/interfaces/common.js", + "./node_modules/mocha-7.2.0/lib/interfaces/exports.js", + "./node_modules/mocha-7.2.0/lib/interfaces/index.js", + "./node_modules/mocha-7.2.0/lib/interfaces/qunit.js", + "./node_modules/mocha-7.2.0/lib/interfaces/tdd.js", + "./node_modules/mocha-7.2.0/lib/mocharc.json", + "./node_modules/mocha-7.2.0/lib/pending.js", + "./node_modules/mocha-7.2.0/lib/reporters/doc.js", + "./node_modules/mocha-7.2.0/lib/reporters/html.js", + "./node_modules/mocha-7.2.0/lib/reporters/index.js", + "./node_modules/mocha-7.2.0/lib/reporters/json-stream.js", + "./node_modules/mocha-7.2.0/lib/reporters/json.js", + "./node_modules/mocha-7.2.0/lib/reporters/markdown.js", + "./node_modules/mocha-7.2.0/lib/stats-collector.js", + "./node_modules/mocha-7.2.0/lib/utils.js", + "./node_modules/mocha-7.2.0/node_modules/brace-expansion/index.js", + "./node_modules/mocha-7.2.0/node_modules/debug/node_modules/ms/index.js", + "./node_modules/mocha-7.2.0/node_modules/debug/src/common.js", + "./node_modules/mocha-7.2.0/node_modules/glob/common.js", + "./node_modules/mocha-7.2.0/node_modules/has-flag/index.js", + "./node_modules/mocha-7.2.0/node_modules/mkdirp/index.js", + "./node_modules/mocha-7.2.0/node_modules/ms/index.js", + "./node_modules/mocha-7.2.0/node_modules/object.assign/implementation.js", + "./node_modules/mocha-7.2.0/node_modules/object.assign/index.js", + "./node_modules/mocha-7.2.0/node_modules/object.assign/polyfill.js", + "./node_modules/mocha-7.2.0/node_modules/object.assign/shim.js", + "./node_modules/mocha-7.2.0/package.json", "./node_modules/mocha-junit-reporter/node_modules/mkdirp/index.js", "./node_modules/mocha-junit-reporter/node_modules/mkdirp/lib/find-made.js", "./node_modules/mocha-junit-reporter/node_modules/mkdirp/lib/mkdirp-manual.js", @@ -3180,6 +3180,7 @@ "./node_modules/react-docgen/node_modules/doctrine/package.json", "./node_modules/react-docgen/node_modules/strip-indent/index.js", "./node_modules/readable-stream/lib/internal/streams/destroy.js", + "./node_modules/readable-stream/node_modules/isarray/index.js", "./node_modules/recast/node_modules/ast-types/def/babel-core.js", "./node_modules/recast/node_modules/ast-types/def/babel.js", "./node_modules/recast/node_modules/ast-types/def/core-operators.js", @@ -4232,5 +4233,5 @@ "./tooling/v8-snapshot/cache/linux/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "a83ec07b936fc8a327f5d598ffadd5d272171e21824eabfe913646bf73ca4d43" + "deferredHash": "712617e51b2b166bd89f4eeb0c7840516ff71d7c469fb06777924ee845bd6fb4" } \ No newline at end of file diff --git a/tooling/v8-snapshot/cache/win32/snapshot-meta.json b/tooling/v8-snapshot/cache/win32/snapshot-meta.json index 658ac8ba3e6a..a36f86eda5f9 100644 --- a/tooling/v8-snapshot/cache/win32/snapshot-meta.json +++ b/tooling/v8-snapshot/cache/win32/snapshot-meta.json @@ -33,8 +33,8 @@ "./node_modules/jsonfile/index.js", "./node_modules/make-dir/index.js", "./node_modules/minimatch/minimatch.js", - "./node_modules/mocha-7.0.1/node_modules/debug/src/node.js", - "./node_modules/mocha-7.0.1/node_modules/glob/node_modules/minimatch/minimatch.js", + "./node_modules/mocha-7.2.0/node_modules/debug/src/node.js", + "./node_modules/mocha-7.2.0/node_modules/glob/node_modules/minimatch/minimatch.js", "./node_modules/mocha-junit-reporter/node_modules/debug/src/node.js", "./node_modules/mocha/node_modules/debug/src/node.js", "./node_modules/morgan/node_modules/debug/src/node.js", @@ -346,28 +346,28 @@ "./node_modules/minizlib/constants.js", "./node_modules/minizlib/index.js", "./node_modules/minizlib/node_modules/minipass/index.js", - "./node_modules/mocha-7.0.1/index.js", - "./node_modules/mocha-7.0.1/lib/hook.js", - "./node_modules/mocha-7.0.1/lib/mocha.js", - "./node_modules/mocha-7.0.1/lib/reporters/base.js", - "./node_modules/mocha-7.0.1/lib/reporters/dot.js", - "./node_modules/mocha-7.0.1/lib/reporters/landing.js", - "./node_modules/mocha-7.0.1/lib/reporters/list.js", - "./node_modules/mocha-7.0.1/lib/reporters/min.js", - "./node_modules/mocha-7.0.1/lib/reporters/nyan.js", - "./node_modules/mocha-7.0.1/lib/reporters/progress.js", - "./node_modules/mocha-7.0.1/lib/reporters/spec.js", - "./node_modules/mocha-7.0.1/lib/reporters/tap.js", - "./node_modules/mocha-7.0.1/lib/reporters/xunit.js", - "./node_modules/mocha-7.0.1/lib/runnable.js", - "./node_modules/mocha-7.0.1/lib/runner.js", - "./node_modules/mocha-7.0.1/lib/suite.js", - "./node_modules/mocha-7.0.1/lib/test.js", - "./node_modules/mocha-7.0.1/node_modules/debug/src/browser.js", - "./node_modules/mocha-7.0.1/node_modules/debug/src/index.js", - "./node_modules/mocha-7.0.1/node_modules/glob/glob.js", - "./node_modules/mocha-7.0.1/node_modules/glob/sync.js", - "./node_modules/mocha-7.0.1/node_modules/supports-color/index.js", + "./node_modules/mocha-7.2.0/index.js", + "./node_modules/mocha-7.2.0/lib/hook.js", + "./node_modules/mocha-7.2.0/lib/mocha.js", + "./node_modules/mocha-7.2.0/lib/reporters/base.js", + "./node_modules/mocha-7.2.0/lib/reporters/dot.js", + "./node_modules/mocha-7.2.0/lib/reporters/landing.js", + "./node_modules/mocha-7.2.0/lib/reporters/list.js", + "./node_modules/mocha-7.2.0/lib/reporters/min.js", + "./node_modules/mocha-7.2.0/lib/reporters/nyan.js", + "./node_modules/mocha-7.2.0/lib/reporters/progress.js", + "./node_modules/mocha-7.2.0/lib/reporters/spec.js", + "./node_modules/mocha-7.2.0/lib/reporters/tap.js", + "./node_modules/mocha-7.2.0/lib/reporters/xunit.js", + "./node_modules/mocha-7.2.0/lib/runnable.js", + "./node_modules/mocha-7.2.0/lib/runner.js", + "./node_modules/mocha-7.2.0/lib/suite.js", + "./node_modules/mocha-7.2.0/lib/test.js", + "./node_modules/mocha-7.2.0/node_modules/debug/src/browser.js", + "./node_modules/mocha-7.2.0/node_modules/debug/src/index.js", + "./node_modules/mocha-7.2.0/node_modules/glob/glob.js", + "./node_modules/mocha-7.2.0/node_modules/glob/sync.js", + "./node_modules/mocha-7.2.0/node_modules/supports-color/index.js", "./node_modules/mocha-junit-reporter/index.js", "./node_modules/mocha/index.js", "./node_modules/mocha/lib/hook.js", @@ -2234,7 +2234,6 @@ "./node_modules/is-regexp/index.js", "./node_modules/is-stream/index.js", "./node_modules/is-typedarray/index.js", - "./node_modules/isarray/index.js", "./node_modules/isbinaryfile/lib/index.js", "./node_modules/isexe/mode.js", "./node_modules/isexe/windows.js", @@ -2492,38 +2491,39 @@ "./node_modules/min-indent/index.js", "./node_modules/minimatch/node_modules/brace-expansion/index.js", "./node_modules/minimist/index.js", - "./node_modules/mocha-7.0.1/lib/browser/progress.js", - "./node_modules/mocha-7.0.1/lib/context.js", - "./node_modules/mocha-7.0.1/lib/errors.js", - "./node_modules/mocha-7.0.1/lib/growl.js", - "./node_modules/mocha-7.0.1/lib/interfaces/bdd.js", - "./node_modules/mocha-7.0.1/lib/interfaces/common.js", - "./node_modules/mocha-7.0.1/lib/interfaces/exports.js", - "./node_modules/mocha-7.0.1/lib/interfaces/index.js", - "./node_modules/mocha-7.0.1/lib/interfaces/qunit.js", - "./node_modules/mocha-7.0.1/lib/interfaces/tdd.js", - "./node_modules/mocha-7.0.1/lib/mocharc.json", - "./node_modules/mocha-7.0.1/lib/pending.js", - "./node_modules/mocha-7.0.1/lib/reporters/doc.js", - "./node_modules/mocha-7.0.1/lib/reporters/html.js", - "./node_modules/mocha-7.0.1/lib/reporters/index.js", - "./node_modules/mocha-7.0.1/lib/reporters/json-stream.js", - "./node_modules/mocha-7.0.1/lib/reporters/json.js", - "./node_modules/mocha-7.0.1/lib/reporters/markdown.js", - "./node_modules/mocha-7.0.1/lib/stats-collector.js", - "./node_modules/mocha-7.0.1/lib/utils.js", - "./node_modules/mocha-7.0.1/node_modules/brace-expansion/index.js", - "./node_modules/mocha-7.0.1/node_modules/debug/node_modules/ms/index.js", - "./node_modules/mocha-7.0.1/node_modules/debug/src/common.js", - "./node_modules/mocha-7.0.1/node_modules/glob/common.js", - "./node_modules/mocha-7.0.1/node_modules/has-flag/index.js", - "./node_modules/mocha-7.0.1/node_modules/mkdirp/index.js", - "./node_modules/mocha-7.0.1/node_modules/ms/index.js", - "./node_modules/mocha-7.0.1/node_modules/object.assign/implementation.js", - "./node_modules/mocha-7.0.1/node_modules/object.assign/index.js", - "./node_modules/mocha-7.0.1/node_modules/object.assign/polyfill.js", - "./node_modules/mocha-7.0.1/node_modules/object.assign/shim.js", - "./node_modules/mocha-7.0.1/package.json", + "./node_modules/mocha-7.2.0/lib/browser/progress.js", + "./node_modules/mocha-7.2.0/lib/context.js", + "./node_modules/mocha-7.2.0/lib/errors.js", + "./node_modules/mocha-7.2.0/lib/esm-utils.js", + "./node_modules/mocha-7.2.0/lib/growl.js", + "./node_modules/mocha-7.2.0/lib/interfaces/bdd.js", + "./node_modules/mocha-7.2.0/lib/interfaces/common.js", + "./node_modules/mocha-7.2.0/lib/interfaces/exports.js", + "./node_modules/mocha-7.2.0/lib/interfaces/index.js", + "./node_modules/mocha-7.2.0/lib/interfaces/qunit.js", + "./node_modules/mocha-7.2.0/lib/interfaces/tdd.js", + "./node_modules/mocha-7.2.0/lib/mocharc.json", + "./node_modules/mocha-7.2.0/lib/pending.js", + "./node_modules/mocha-7.2.0/lib/reporters/doc.js", + "./node_modules/mocha-7.2.0/lib/reporters/html.js", + "./node_modules/mocha-7.2.0/lib/reporters/index.js", + "./node_modules/mocha-7.2.0/lib/reporters/json-stream.js", + "./node_modules/mocha-7.2.0/lib/reporters/json.js", + "./node_modules/mocha-7.2.0/lib/reporters/markdown.js", + "./node_modules/mocha-7.2.0/lib/stats-collector.js", + "./node_modules/mocha-7.2.0/lib/utils.js", + "./node_modules/mocha-7.2.0/node_modules/brace-expansion/index.js", + "./node_modules/mocha-7.2.0/node_modules/debug/node_modules/ms/index.js", + "./node_modules/mocha-7.2.0/node_modules/debug/src/common.js", + "./node_modules/mocha-7.2.0/node_modules/glob/common.js", + "./node_modules/mocha-7.2.0/node_modules/has-flag/index.js", + "./node_modules/mocha-7.2.0/node_modules/mkdirp/index.js", + "./node_modules/mocha-7.2.0/node_modules/ms/index.js", + "./node_modules/mocha-7.2.0/node_modules/object.assign/implementation.js", + "./node_modules/mocha-7.2.0/node_modules/object.assign/index.js", + "./node_modules/mocha-7.2.0/node_modules/object.assign/polyfill.js", + "./node_modules/mocha-7.2.0/node_modules/object.assign/shim.js", + "./node_modules/mocha-7.2.0/package.json", "./node_modules/mocha-junit-reporter/node_modules/mkdirp/index.js", "./node_modules/mocha-junit-reporter/node_modules/mkdirp/lib/find-made.js", "./node_modules/mocha-junit-reporter/node_modules/mkdirp/lib/mkdirp-manual.js", @@ -3184,6 +3184,7 @@ "./node_modules/react-docgen/node_modules/doctrine/package.json", "./node_modules/react-docgen/node_modules/strip-indent/index.js", "./node_modules/readable-stream/lib/internal/streams/destroy.js", + "./node_modules/readable-stream/node_modules/isarray/index.js", "./node_modules/recast/node_modules/ast-types/def/babel-core.js", "./node_modules/recast/node_modules/ast-types/def/babel.js", "./node_modules/recast/node_modules/ast-types/def/core-operators.js", @@ -4232,5 +4233,5 @@ "./tooling/v8-snapshot/cache/win32/snapshot-entry.js" ], "deferredHashFile": "yarn.lock", - "deferredHash": "8314db54df0460f6d49850716cab3431b20fcf5dc94a69f6f5a6d87e071d0865" + "deferredHash": "4098770ca48f758aedb33b68d8f40029bffb3e9c1617cb46d0aa9f5edc0bd2ac" } \ No newline at end of file diff --git a/tooling/v8-snapshot/src/setup/force-no-rewrite.ts b/tooling/v8-snapshot/src/setup/force-no-rewrite.ts index dc0d30e7e0ad..51cbcb639e53 100644 --- a/tooling/v8-snapshot/src/setup/force-no-rewrite.ts +++ b/tooling/v8-snapshot/src/setup/force-no-rewrite.ts @@ -43,14 +43,14 @@ export default [ 'node_modules/stream-parser/node_modules/debug/src/node.js', 'node_modules/@cypress/commit-info/node_modules/debug/src/node.js', 'node_modules/@cypress/get-windows-proxy/node_modules/debug/src/node.js', - 'node_modules/mocha-7.0.1/node_modules/debug/src/node.js', + 'node_modules/mocha-7.2.0/node_modules/debug/src/node.js', 'node_modules/tcp-port-used/node_modules/debug/src/node.js', 'packages/data-context/node_modules/debug/src/node.js', 'packages/graphql/node_modules/debug/src/node.js', 'packages/net-stubbing/node_modules/debug/src/node.js', 'packages/server/node_modules/mocha/node_modules/debug/src/node.js', 'node_modules/minimatch/minimatch.js', - 'node_modules/mocha-7.0.1/node_modules/glob/node_modules/minimatch/minimatch.js', + 'node_modules/mocha-7.2.0/node_modules/glob/node_modules/minimatch/minimatch.js', 'packages/data-context/node_modules/minimatch/minimatch.js', 'packages/network/node_modules/minimatch/minimatch.js', 'packages/server/node_modules/glob/node_modules/minimatch/minimatch.js', diff --git a/yarn.lock b/yarn.lock index a75c7e527fa8..6c7bfca77605 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11886,7 +11886,7 @@ cachedir@2.3.0, cachedir@^2.3.0: resolved "https://registry.yarnpkg.com/cachedir/-/cachedir-2.3.0.tgz#0c75892a052198f0b21c7c1804d8331edfcae0e8" integrity sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw== -call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: +call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== @@ -11894,18 +11894,17 @@ call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: es-errors "^1.3.0" function-bind "^1.1.2" -call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" - integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.6, call-bind@^1.0.7, call-bind@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c" + integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww== dependencies: + call-bind-apply-helpers "^1.0.0" es-define-property "^1.0.0" - es-errors "^1.3.0" - function-bind "^1.1.2" get-intrinsic "^1.2.4" - set-function-length "^1.2.1" + set-function-length "^1.2.2" -call-bound@^1.0.2: +call-bound@^1.0.2, call-bound@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== @@ -12437,7 +12436,7 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -ci-info@^3.2.0: +ci-info@^3.2.0, ci-info@^3.7.0: version "3.9.0" resolved "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== @@ -17411,15 +17410,6 @@ fs-extra@^6.0.1: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^7.0.1: - version "7.0.1" - resolved "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" - integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -19627,7 +19617,7 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-ci@2.0.0, is-ci@^2.0.0: +is-ci@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== @@ -20663,7 +20653,7 @@ json-stable-stringify@1.0.1: dependencies: jsonify "~0.0.0" -json-stable-stringify@1.1.1, json-stable-stringify@^1.0.1: +json-stable-stringify@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.1.1.tgz#52d4361b47d49168bcc4e564189a42e5a7439454" integrity sha512-SU/971Kt5qVQfJpyDveVhQ/vya+5hvrjClFOcr8c0Fq5aODJjMwutrOfCU+eCnVD5gpx1Q3fEqkyom77zH1iIg== @@ -20673,6 +20663,17 @@ json-stable-stringify@1.1.1, json-stable-stringify@^1.0.1: jsonify "^0.0.1" object-keys "^1.1.1" +json-stable-stringify@^1.0.1, json-stable-stringify@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.2.1.tgz#addb683c2b78014d0b78d704c2fcbdf0695a60e2" + integrity sha512-Lp6HbbBgosLmJbjx0pBLbgvx68FaFU1sdkmBuckmhhJ88kL13OA51CDtR2yJB50eCNMH9wRqtQNNiAqQH4YXnA== + dependencies: + call-bind "^1.0.8" + call-bound "^1.0.3" + isarray "^2.0.5" + jsonify "^0.0.1" + object-keys "^1.1.1" + json-stringify-nice@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz#2c937962b80181d3f317dd39aa323e14f5a60a67" @@ -22846,10 +22847,10 @@ mobx@6.13.6: resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.13.6.tgz#3b80895c7c9df456efc86ae0b6983ccea1da6cc6" integrity sha512-r19KNV0uBN4b+ER8Z0gA4y+MzDYIQ2SvOmn3fUrqPnWXdQfakd9yfbPBDBF/p5I+bd3N5Rk1fHONIvMay+bJGA== -"mocha-7.0.1@npm:mocha@7.0.1": - version "7.0.1" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.0.1.tgz#276186d35a4852f6249808c6dd4a1376cbf6c6ce" - integrity sha512-9eWmWTdHLXh72rGrdZjNbG3aa1/3NRPpul1z0D979QpEnFdCG0Q5tv834N+94QEN2cysfV72YocQ3fn87s70fg== +"mocha-7.2.0@npm:mocha@7.2.0": + version "7.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.2.0.tgz#01cc227b00d875ab1eed03a75106689cfed5a604" + integrity sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ== dependencies: ansi-colors "3.2.3" browser-stdout "1.3.1" @@ -22862,9 +22863,9 @@ mobx@6.13.6: growl "1.10.5" he "1.2.0" js-yaml "3.13.1" - log-symbols "2.2.0" + log-symbols "3.0.0" minimatch "3.0.4" - mkdirp "0.5.1" + mkdirp "0.5.5" ms "2.1.1" node-environment-flags "1.0.6" object.assign "4.1.0" @@ -22872,8 +22873,8 @@ mobx@6.13.6: supports-color "6.0.0" which "1.3.1" wide-align "1.1.3" - yargs "13.3.0" - yargs-parser "13.1.1" + yargs "13.3.2" + yargs-parser "13.1.2" yargs-unparser "1.6.0" mocha-banner@1.1.2: @@ -23053,7 +23054,7 @@ mocha@7.1.2: yargs-parser "13.1.2" yargs-unparser "1.6.0" -mocha@^7.1.0: +mocha@7.2.0, mocha@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.2.0.tgz#01cc227b00d875ab1eed03a75106689cfed5a604" integrity sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ== @@ -25405,24 +25406,26 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= -patch-package@6.4.7: - version "6.4.7" - resolved "https://registry.npmjs.org/patch-package/-/patch-package-6.4.7.tgz#2282d53c397909a0d9ef92dae3fdeb558382b148" - integrity sha512-S0vh/ZEafZ17hbhgqdnpunKDfzHQibQizx9g8yEf5dcVk3KOflOfdufRXQX8CSEkyOQwuM/bNz1GwKvFj54kaQ== +patch-package@8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/patch-package/-/patch-package-8.0.0.tgz#d191e2f1b6e06a4624a0116bcb88edd6714ede61" + integrity sha512-da8BVIhzjtgScwDJ2TtKsfT5JFWz1hYoBl9rUQ1f38MC2HwnEIkK8VN3dKMKcP7P7bvvgzNDbfNHtx3MsQb5vA== dependencies: "@yarnpkg/lockfile" "^1.1.0" - chalk "^2.4.2" - cross-spawn "^6.0.5" + chalk "^4.1.2" + ci-info "^3.7.0" + cross-spawn "^7.0.3" find-yarn-workspace-root "^2.0.0" - fs-extra "^7.0.1" - is-ci "^2.0.0" + fs-extra "^9.0.0" + json-stable-stringify "^1.0.2" klaw-sync "^6.0.0" - minimist "^1.2.0" + minimist "^1.2.6" open "^7.4.2" rimraf "^2.6.3" - semver "^5.6.0" + semver "^7.5.3" slash "^2.0.0" tmp "^0.0.33" + yaml "^2.2.2" path-browserify@0.0.1: version "0.0.1" @@ -28301,7 +28304,7 @@ set-blocking@^2.0.0, set-blocking@~2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= -set-function-length@^1.2.1: +set-function-length@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== @@ -33185,7 +33188,7 @@ yaml-eslint-parser@^1.2.2: lodash "^4.17.21" yaml "^2.0.0" -yaml@2.7.0, yaml@^2.0.0, yaml@^2.3.4, yaml@^2.4.1, yaml@^2.6.0: +yaml@2.7.0: version "2.7.0" resolved "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz#aef9bb617a64c937a9a748803786ad8d3ffe1e98" integrity sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA== @@ -33195,6 +33198,11 @@ yaml@^1.10.0: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== +yaml@^2.0.0, yaml@^2.2.2, yaml@^2.3.4, yaml@^2.4.1, yaml@^2.6.0: + version "2.7.1" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.7.1.tgz#44a247d1b88523855679ac7fa7cda6ed7e135cf6" + integrity sha512-10ULxpnOCQXxJvBgxsn9ptjq6uviG/htZKk9veJGhlqn3w/DxQ631zFF+nlQXLwmImeS5amR2dl2U8sg6U9jsQ== + yargs-parser@13.1.1: version "13.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0"