From a9476ecb3d43f628b689e060294a1952937cb1a7 Mon Sep 17 00:00:00 2001 From: Zachary Williams Date: Mon, 11 Jul 2022 10:52:20 -0500 Subject: [PATCH] fix: remove CT side effects from mount when e2e testing (#22633) --- npm/mount-utils/src/index.ts | 10 +++++++++- npm/react/src/mount.ts | 9 +++++++++ npm/vue/src/index.ts | 8 ++++++++ npm/vue2/src/index.ts | 8 ++++++++ .../cypress-e2e-mount-import.config.js | 13 +++++++++++++ .../cypress/e2e/passing-with-mount.cy.js | 6 ++++++ .../cypress/support/e2e-with-mount.js | 3 +++ system-tests/projects/component-tests/index.html | 12 ++++++++++++ system-tests/test/e2e_with_mount_import_spec.ts | 10 ++++++++++ 9 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 system-tests/projects/component-tests/cypress-e2e-mount-import.config.js create mode 100644 system-tests/projects/component-tests/cypress/e2e/passing-with-mount.cy.js create mode 100644 system-tests/projects/component-tests/cypress/support/e2e-with-mount.js create mode 100644 system-tests/projects/component-tests/index.html create mode 100644 system-tests/test/e2e_with_mount_import_spec.ts diff --git a/npm/mount-utils/src/index.ts b/npm/mount-utils/src/index.ts index 94b70c14108f..5593110bd505 100644 --- a/npm/mount-utils/src/index.ts +++ b/npm/mount-utils/src/index.ts @@ -46,7 +46,7 @@ export const getContainerEl = (): HTMLElement => { return el } - throw Error(`No element found that matches selector ${ROOT_SELECTOR}. Please use the mount utils to mount it properly`) + throw Error(`No element found that matches selector ${ROOT_SELECTOR}. Please add a root element with data-cy-root attribute to your "component-index.html" file so that Cypress can attach your component to the DOM.`) } /** @@ -200,6 +200,14 @@ export const injectStylesBeforeElement = ( } export function setupHooks (optionalCallback?: Function) { + // Consumed by the framework "mount" libs. A user might register their own mount in the scaffolded 'commands.js' + // file that is imported by e2e and component support files by default. We don't want CT side effects to run when e2e + // testing so we early return. + // System test to verify CT side effects do not pollute e2e: system-tests/test/e2e_with_mount_import_spec.ts + if (Cypress.testingType !== 'component') { + return + } + // When running component specs, we cannot allow "cy.visit" // because it will wipe out our preparation work, and does not make much sense // thus we overwrite "cy.visit" to throw an error diff --git a/npm/react/src/mount.ts b/npm/react/src/mount.ts index da17a97b8506..ea4867b22d3c 100644 --- a/npm/react/src/mount.ts +++ b/npm/react/src/mount.ts @@ -322,6 +322,15 @@ export declare namespace Cypress { } } +// Side effects from "import { mount } from '@cypress/'" are annoying, we should avoid doing this +// by creating an explicit function/import that the user can register in their 'component.js' support file, +// such as: +// import 'cypress//support' +// or +// import { registerCT } from 'cypress/' +// registerCT() +// Note: This would be a breaking change + // it is required to unmount component in beforeEach hook in order to provide a clean state inside test // because `mount` can be called after some preparation that can side effect unmount // @see npm/react/cypress/component/advanced/set-timeout-example/loading-indicator-spec.js diff --git a/npm/vue/src/index.ts b/npm/vue/src/index.ts index 74c63d95fdfa..8e92a9622e54 100644 --- a/npm/vue/src/index.ts +++ b/npm/vue/src/index.ts @@ -306,4 +306,12 @@ export function mountCallback ( } } +// Side effects from "import { mount } from '@cypress/'" are annoying, we should avoid doing this +// by creating an explicit function/import that the user can register in their 'component.js' support file, +// such as: +// import 'cypress//support' +// or +// import { registerCT } from 'cypress/' +// registerCT() +// Note: This would be a breaking change setupHooks() diff --git a/npm/vue2/src/index.ts b/npm/vue2/src/index.ts index 6bedfc2d6605..4f8ea0d226dc 100644 --- a/npm/vue2/src/index.ts +++ b/npm/vue2/src/index.ts @@ -426,4 +426,12 @@ export const mountCallback = ( return () => mount(component, options) } +// Side effects from "import { mount } from '@cypress/'" are annoying, we should avoid doing this +// by creating an explicit function/import that the user can register in their 'component.js' support file, +// such as: +// import 'cypress//support' +// or +// import { registerCT } from 'cypress/' +// registerCT() +// Note: This would be a breaking change setupHooks() diff --git a/system-tests/projects/component-tests/cypress-e2e-mount-import.config.js b/system-tests/projects/component-tests/cypress-e2e-mount-import.config.js new file mode 100644 index 000000000000..440a1e02b9d9 --- /dev/null +++ b/system-tests/projects/component-tests/cypress-e2e-mount-import.config.js @@ -0,0 +1,13 @@ +const { defineConfig } = require('cypress') + +module.exports = defineConfig({ + e2e: { + supportFile: 'cypress/support/e2e-with-mount.js', + }, + component: { + specPattern: 'cypress/component-tests/*.spec.js', + devServer: { + bundler: 'webpack', + }, + }, +}) diff --git a/system-tests/projects/component-tests/cypress/e2e/passing-with-mount.cy.js b/system-tests/projects/component-tests/cypress/e2e/passing-with-mount.cy.js new file mode 100644 index 000000000000..5a8c47671ebd --- /dev/null +++ b/system-tests/projects/component-tests/cypress/e2e/passing-with-mount.cy.js @@ -0,0 +1,6 @@ +it('should pass with component mount registered', () => { + // "cy.visit" is disabled when component testing due to a side effect of "import { mount } from 'cypress/{react,vue}'" + // These side effects have been disabled when testingType === 'e2e' so this will now pass. + cy.visit('./index.html') + cy.contains('h1', 'Hello World') +}) diff --git a/system-tests/projects/component-tests/cypress/support/e2e-with-mount.js b/system-tests/projects/component-tests/cypress/support/e2e-with-mount.js new file mode 100644 index 000000000000..86674a7a022b --- /dev/null +++ b/system-tests/projects/component-tests/cypress/support/e2e-with-mount.js @@ -0,0 +1,3 @@ +import { mount } from 'cypress/react' + +Cypress.Commands.add('mount', mount) diff --git a/system-tests/projects/component-tests/index.html b/system-tests/projects/component-tests/index.html new file mode 100644 index 000000000000..0aac47a2fd9e --- /dev/null +++ b/system-tests/projects/component-tests/index.html @@ -0,0 +1,12 @@ + + + + + + + Document + + +

Hello World

+ + \ No newline at end of file diff --git a/system-tests/test/e2e_with_mount_import_spec.ts b/system-tests/test/e2e_with_mount_import_spec.ts new file mode 100644 index 000000000000..1bb7da4496b8 --- /dev/null +++ b/system-tests/test/e2e_with_mount_import_spec.ts @@ -0,0 +1,10 @@ +import systemTests from '../lib/system-tests' + +// see: https://github.com/cypress-io/cypress/issues/22589 +systemTests.it('should not run CT side effects in e2e with mount registration', { + project: 'component-tests', + spec: 'passing-with-mount.cy.js', + browser: 'chrome', + configFile: 'cypress-e2e-mount-import.config.js', + expectedExitCode: 0, +})