cypress 10.11.0 → 11.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/angular/CHANGELOG.md +20 -0
  2. package/angular/dist/index.d.ts +124 -1
  3. package/angular/dist/index.js +59 -59
  4. package/lib/cli.js +15 -1
  5. package/lib/tasks/download.js +3 -7
  6. package/lib/util.js +2 -2
  7. package/mount-utils/CHANGELOG.md +14 -0
  8. package/mount-utils/README.md +5 -23
  9. package/mount-utils/dist/index.d.ts +25 -39
  10. package/mount-utils/dist/index.js +33 -112
  11. package/mount-utils/package.json +1 -0
  12. package/package.json +3 -3
  13. package/react/CHANGELOG.md +27 -0
  14. package/react/README.md +2 -22
  15. package/react/dist/cypress-react.cjs.js +92 -219
  16. package/react/dist/cypress-react.esm-bundler.js +92 -220
  17. package/react/dist/index.d.ts +111 -4
  18. package/react18/CHANGELOG.md +13 -0
  19. package/react18/dist/cypress-react.cjs.js +117 -180
  20. package/react18/dist/cypress-react.esm-bundler.js +103 -167
  21. package/react18/dist/index.d.ts +78 -6
  22. package/react18/package.json +1 -0
  23. package/svelte/CHANGELOG.md +20 -0
  24. package/svelte/dist/cypress-svelte.cjs.js +19 -114
  25. package/svelte/dist/cypress-svelte.esm-bundler.js +19 -114
  26. package/svelte/dist/index.d.ts +201 -1
  27. package/types/cypress.d.ts +18 -10
  28. package/vue/CHANGELOG.md +34 -0
  29. package/vue/README.md +4 -8
  30. package/vue/dist/cypress-vue.cjs.js +68 -151
  31. package/vue/dist/cypress-vue.esm-bundler.js +68 -151
  32. package/vue/dist/index.d.ts +1352 -104
  33. package/vue/package.json +1 -1
  34. package/vue2/CHANGELOG.md +27 -0
  35. package/vue2/README.md +3 -7
  36. package/vue2/dist/cypress-vue2.cjs.js +87 -211
  37. package/vue2/dist/cypress-vue2.esm-bundler.js +86 -210
  38. package/vue2/dist/index.d.ts +341 -172
  39. package/vue2/package.json +1 -3
  40. package/angular/dist/mount.d.ts +0 -112
  41. package/react/dist/createMount.d.ts +0 -31
  42. package/react/dist/getDisplayName.d.ts +0 -8
  43. package/react/dist/mount.d.ts +0 -8
  44. package/react/dist/mountHook.d.ts +0 -12
  45. package/react/dist/types.d.ts +0 -45
  46. package/svelte/dist/mount.d.ts +0 -30
  47. package/vue/dist/@vue/test-utils/baseWrapper.d.ts +0 -63
  48. package/vue/dist/@vue/test-utils/components/RouterLinkStub.d.ts +0 -21
  49. package/vue/dist/@vue/test-utils/config.d.ts +0 -30
  50. package/vue/dist/@vue/test-utils/constants/dom-events.d.ts +0 -900
  51. package/vue/dist/@vue/test-utils/createDomEvent.d.ts +0 -9
  52. package/vue/dist/@vue/test-utils/domWrapper.d.ts +0 -18
  53. package/vue/dist/@vue/test-utils/emit.d.ts +0 -5
  54. package/vue/dist/@vue/test-utils/errorWrapper.d.ts +0 -1
  55. package/vue/dist/@vue/test-utils/index.d.ts +0 -11
  56. package/vue/dist/@vue/test-utils/interfaces/wrapperLike.d.ts +0 -56
  57. package/vue/dist/@vue/test-utils/mount.d.ts +0 -35
  58. package/vue/dist/@vue/test-utils/stubs.d.ts +0 -22
  59. package/vue/dist/@vue/test-utils/types.d.ts +0 -125
  60. package/vue/dist/@vue/test-utils/utils/autoUnmount.d.ts +0 -5
  61. package/vue/dist/@vue/test-utils/utils/compileSlots.d.ts +0 -2
  62. package/vue/dist/@vue/test-utils/utils/componentName.d.ts +0 -4
  63. package/vue/dist/@vue/test-utils/utils/find.d.ts +0 -10
  64. package/vue/dist/@vue/test-utils/utils/flushPromises.d.ts +0 -1
  65. package/vue/dist/@vue/test-utils/utils/getRootNodes.d.ts +0 -2
  66. package/vue/dist/@vue/test-utils/utils/isElement.d.ts +0 -1
  67. package/vue/dist/@vue/test-utils/utils/isElementVisible.d.ts +0 -6
  68. package/vue/dist/@vue/test-utils/utils/matchName.d.ts +0 -1
  69. package/vue/dist/@vue/test-utils/utils/stringifyNode.d.ts +0 -1
  70. package/vue/dist/@vue/test-utils/utils/vueCompatSupport.d.ts +0 -8
  71. package/vue/dist/@vue/test-utils/utils/vueShared.d.ts +0 -3
  72. package/vue/dist/@vue/test-utils/utils.d.ts +0 -13
  73. package/vue/dist/@vue/test-utils/vueWrapper.d.ts +0 -35
  74. package/vue/dist/@vue/test-utils/wrapperFactory.d.ts +0 -14
@@ -59,6 +59,11 @@ function __rest(s, e) {
59
59
  }
60
60
 
61
61
  const ROOT_SELECTOR = '[data-cy-root]';
62
+ /**
63
+ * Gets the root element used to mount the component.
64
+ * @returns {HTMLElement} The root element
65
+ * @throws {Error} If the root element is not found
66
+ */
62
67
  const getContainerEl = () => {
63
68
  const el = document.querySelector(ROOT_SELECTOR);
64
69
  if (el) {
@@ -66,122 +71,19 @@ const getContainerEl = () => {
66
71
  }
67
72
  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.`);
68
73
  };
69
- /**
70
- * Remove any style or extra link elements from the iframe placeholder
71
- * left from any previous test
72
- *
73
- */
74
- function cleanupStyles() {
75
- const styles = document.body.querySelectorAll('[data-cy=injected-style-tag]');
76
- styles.forEach((styleElement) => {
77
- if (styleElement.parentElement) {
78
- styleElement.parentElement.removeChild(styleElement);
79
- }
80
- });
81
- const links = document.body.querySelectorAll('[data-cy=injected-stylesheet]');
82
- links.forEach((link) => {
83
- if (link.parentElement) {
84
- link.parentElement.removeChild(link);
74
+ function checkForRemovedStyleOptions(mountingOptions) {
75
+ for (const key of ['cssFile', 'cssFiles', 'style', 'styles', 'stylesheet', 'stylesheets']) {
76
+ if (mountingOptions[key]) {
77
+ Cypress.utils.throwErrByPath('mount.removed_style_mounting_options', key);
85
78
  }
86
- });
87
- }
88
- /**
89
- * Insert links to external style resources.
90
- */
91
- function insertStylesheets(stylesheets, document, el) {
92
- stylesheets.forEach((href) => {
93
- const link = document.createElement('link');
94
- link.type = 'text/css';
95
- link.rel = 'stylesheet';
96
- link.href = href;
97
- link.dataset.cy = 'injected-stylesheet';
98
- document.body.insertBefore(link, el);
99
- });
100
- }
101
- /**
102
- * Inserts a single stylesheet element
103
- */
104
- function insertStyles(styles, document, el) {
105
- styles.forEach((style) => {
106
- const styleElement = document.createElement('style');
107
- styleElement.dataset.cy = 'injected-style-tag';
108
- styleElement.appendChild(document.createTextNode(style));
109
- document.body.insertBefore(styleElement, el);
110
- });
111
- }
112
- function insertSingleCssFile(cssFilename, document, el, log) {
113
- return cy.readFile(cssFilename, { log }).then((css) => {
114
- const style = document.createElement('style');
115
- style.appendChild(document.createTextNode(css));
116
- document.body.insertBefore(style, el);
117
- });
118
- }
119
- /**
120
- * Reads the given CSS file from local file system
121
- * and adds the loaded style text as an element.
122
- */
123
- function insertLocalCssFiles(cssFilenames, document, el, log) {
124
- return Cypress.Promise.mapSeries(cssFilenames, (cssFilename) => {
125
- return insertSingleCssFile(cssFilename, document, el, log);
126
- });
79
+ }
127
80
  }
128
81
  /**
129
- * Injects custom style text or CSS file or 3rd party style resources
130
- * into the given document.
82
+ * Utility function to register CT side effects and run cleanup code during the "test:before:run" Cypress hook
83
+ * @param optionalCallback Callback to be called before the next test runs
131
84
  */
132
- const injectStylesBeforeElement = (options, document, el) => {
133
- if (!el)
134
- return;
135
- // first insert all stylesheets as Link elements
136
- let stylesheets = [];
137
- if (typeof options.stylesheet === 'string') {
138
- stylesheets.push(options.stylesheet);
139
- }
140
- else if (Array.isArray(options.stylesheet)) {
141
- stylesheets = stylesheets.concat(options.stylesheet);
142
- }
143
- if (typeof options.stylesheets === 'string') {
144
- options.stylesheets = [options.stylesheets];
145
- }
146
- if (options.stylesheets) {
147
- stylesheets = stylesheets.concat(options.stylesheets);
148
- }
149
- insertStylesheets(stylesheets, document, el);
150
- // insert any styles as <style>...</style> elements
151
- let styles = [];
152
- if (typeof options.style === 'string') {
153
- styles.push(options.style);
154
- }
155
- else if (Array.isArray(options.style)) {
156
- styles = styles.concat(options.style);
157
- }
158
- if (typeof options.styles === 'string') {
159
- styles.push(options.styles);
160
- }
161
- else if (Array.isArray(options.styles)) {
162
- styles = styles.concat(options.styles);
163
- }
164
- insertStyles(styles, document, el);
165
- // now load any css files by path and add their content
166
- // as <style>...</style> elements
167
- let cssFiles = [];
168
- if (typeof options.cssFile === 'string') {
169
- cssFiles.push(options.cssFile);
170
- }
171
- else if (Array.isArray(options.cssFile)) {
172
- cssFiles = cssFiles.concat(options.cssFile);
173
- }
174
- if (typeof options.cssFiles === 'string') {
175
- cssFiles.push(options.cssFiles);
176
- }
177
- else if (Array.isArray(options.cssFiles)) {
178
- cssFiles = cssFiles.concat(options.cssFiles);
179
- }
180
- return insertLocalCssFiles(cssFiles, document, el, options.log);
181
- };
182
85
  function setupHooks(optionalCallback) {
183
- // Consumed by the framework "mount" libs. A user might register their own mount in the scaffolded 'commands.js'
184
- // file that is imported by e2e and component support files by default. We don't want CT side effects to run when e2e
86
+ // We don't want CT side effects to run when e2e
185
87
  // testing so we early return.
186
88
  // System test to verify CT side effects do not pollute e2e: system-tests/test/e2e_with_mount_import_spec.ts
187
89
  if (Cypress.testingType !== 'component') {
@@ -196,7 +98,6 @@ function setupHooks(optionalCallback) {
196
98
  // @ts-ignore
197
99
  Cypress.on('test:before:run', () => {
198
100
  optionalCallback === null || optionalCallback === void 0 ? void 0 : optionalCallback();
199
- cleanupStyles();
200
101
  });
201
102
  }
202
103
 
@@ -13792,42 +13693,40 @@ mount: VTUmount,
13792
13693
  // available on the `VueTestUtils` import.
13793
13694
  shallowMount } = _VueTestUtils, VueTestUtils = __rest(_VueTestUtils, ["mount", "shallowMount"]);
13794
13695
  const DEFAULT_COMP_NAME = 'unknown';
13795
- Cypress.on('run:start', () => {
13796
- // `mount` is designed to work with component testing only.
13797
- // it assumes ROOT_SELECTOR exists, which is not the case in e2e.
13798
- // if the user registers a custom command that imports `cypress/vue`,
13799
- // this event will be registered and cause an error when the user
13800
- // launches e2e (since it's common to use Cypress for both CT and E2E.
13801
- // https://github.com/cypress-io/cypress/issues/17438
13802
- if (Cypress.testingType !== 'component') {
13803
- return;
13804
- }
13805
- Cypress.on('test:before:run', () => {
13806
- var _a;
13807
- (_a = Cypress.vueWrapper) === null || _a === void 0 ? void 0 : _a.unmount();
13808
- const el = getContainerEl();
13809
- el.innerHTML = '';
13810
- });
13811
- });
13812
- // implementation
13696
+ const VUE_ROOT = '__cy_vue_root';
13697
+ const cleanup = () => {
13698
+ var _a;
13699
+ (_a = Cypress.vueWrapper) === null || _a === void 0 ? void 0 : _a.unmount();
13700
+ Cypress.$(`#${VUE_ROOT}`).remove();
13701
+ Cypress.vueWrapper = null;
13702
+ Cypress.vue = null;
13703
+ };
13704
+ /**
13705
+ * Mounts a component and returns an object containing the component and VueWrapper
13706
+ * @param componentOptions
13707
+ * @param options
13708
+ * @returns {Cypress.Chainable<{wrapper: VueWrapper<T>, component: T}>}
13709
+ * @see {@link https://on.cypress.io/mounting-vue} for more details.
13710
+ * @example
13711
+ * import { mount } from '@cypress/vue'
13712
+ * import { Stepper } from './Stepper.vue'
13713
+ *
13714
+ * it('mounts', () => {
13715
+ * cy.mount(Stepper)
13716
+ * cy.get('[data-cy=increment]').click()
13717
+ * cy.get('[data-cy=counter]').should('have.text', '1')
13718
+ * })
13719
+ */
13813
13720
  function mount(componentOptions, options = {}) {
13814
- // TODO: get the real displayName and props from VTU shallowMount
13815
- const componentName = getComponentDisplayName(componentOptions);
13816
- const message = `<${componentName} ... />`;
13817
- let logInstance;
13721
+ checkForRemovedStyleOptions(options);
13722
+ // Remove last mounted component if cy.mount is called more than once in a test
13723
+ cleanup();
13818
13724
  // then wait for cypress to load
13819
13725
  return cy.then(() => {
13820
13726
  var _a, _b;
13821
- if (options.log !== false) {
13822
- logInstance = Cypress.log({
13823
- name: 'mount',
13824
- message: [message],
13825
- });
13826
- }
13827
13727
  // @ts-ignore
13828
13728
  const document = cy.state('document');
13829
13729
  const el = getContainerEl();
13830
- injectStylesBeforeElement(options, document, el);
13831
13730
  // merge the extensions with global
13832
13731
  if (options.extensions) {
13833
13732
  options.extensions.plugins = (_a = []) === null || _a === void 0 ? void 0 : _a.concat(options.extensions.plugins || [], options.extensions.use || []);
@@ -13835,23 +13734,37 @@ function mount(componentOptions, options = {}) {
13835
13734
  options.global = Object.assign(Object.assign({}, options.extensions), options.global);
13836
13735
  }
13837
13736
  const componentNode = document.createElement('div');
13838
- componentNode.id = '__cy_vue_root';
13737
+ componentNode.id = VUE_ROOT;
13839
13738
  el.append(componentNode);
13840
13739
  // mount the component using VTU and return the wrapper in Cypress.VueWrapper
13841
13740
  const wrapper = VTUmount(componentOptions, Object.assign({ attachTo: componentNode }, options));
13842
13741
  Cypress.vueWrapper = wrapper;
13843
13742
  Cypress.vue = wrapper.vm;
13844
13743
  return cy
13845
- .wrap(wrapper, { log: false })
13846
13744
  .wait(1, { log: false })
13847
13745
  .then(() => {
13848
- if (logInstance) {
13849
- logInstance.snapshot('mounted');
13850
- logInstance.end();
13746
+ if (options.log !== false) {
13747
+ // TODO: get the real displayName and props from VTU shallowMount
13748
+ const message = `<${getComponentDisplayName(componentOptions)} ... />`;
13749
+ Cypress.log({
13750
+ name: 'mount',
13751
+ message: [message],
13752
+ });
13851
13753
  }
13852
- // by returning undefined we keep the previous subject
13853
- // which is the mounted component
13854
- return undefined;
13754
+ const returnVal = {
13755
+ wrapper,
13756
+ component: wrapper.vm,
13757
+ };
13758
+ return new Proxy(Object.create(returnVal), {
13759
+ get(obj, prop) {
13760
+ // throw an error if it looks like the caller is trying to call a method on the VueWrapper that was originally returned
13761
+ if (Reflect.get(wrapper, prop)) {
13762
+ // @ts-expect-error - internal API
13763
+ Cypress.utils.throwErrByPath('mount.vue_yielded_value');
13764
+ }
13765
+ return Reflect.get(obj, prop);
13766
+ },
13767
+ });
13855
13768
  });
13856
13769
  });
13857
13770
  }
@@ -13880,10 +13793,14 @@ function getComponentDisplayName(componentOptions) {
13880
13793
  * @example
13881
13794
  * import {mountCallback} from '@cypress/vue'
13882
13795
  * beforeEach(mountVue(component, options))
13796
+ *
13797
+ * Removed as of Cypress 11.0.0.
13798
+ * @see https://on.cypress.io/migration-11-0-0-component-testing-updates
13883
13799
  */
13884
13800
  function mountCallback(component, options = {}) {
13885
13801
  return () => {
13886
- return mount(component, options);
13802
+ // @ts-expect-error - undocumented API
13803
+ Cypress.utils.throwErrByPath('mount.mount_callback');
13887
13804
  };
13888
13805
  }
13889
13806
  // Side effects from "import { mount } from '@cypress/<my-framework>'" are annoying, we should avoid doing this
@@ -13894,7 +13811,7 @@ function mountCallback(component, options = {}) {
13894
13811
  // import { registerCT } from 'cypress/<my-framework>'
13895
13812
  // registerCT()
13896
13813
  // Note: This would be a breaking change
13897
- setupHooks();
13814
+ setupHooks(cleanup);
13898
13815
 
13899
13816
  exports.VueTestUtils = VueTestUtils;
13900
13817
  exports.mount = mount;
@@ -36,6 +36,11 @@ function __rest(s, e) {
36
36
  }
37
37
 
38
38
  const ROOT_SELECTOR = '[data-cy-root]';
39
+ /**
40
+ * Gets the root element used to mount the component.
41
+ * @returns {HTMLElement} The root element
42
+ * @throws {Error} If the root element is not found
43
+ */
39
44
  const getContainerEl = () => {
40
45
  const el = document.querySelector(ROOT_SELECTOR);
41
46
  if (el) {
@@ -43,122 +48,19 @@ const getContainerEl = () => {
43
48
  }
44
49
  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.`);
45
50
  };
46
- /**
47
- * Remove any style or extra link elements from the iframe placeholder
48
- * left from any previous test
49
- *
50
- */
51
- function cleanupStyles() {
52
- const styles = document.body.querySelectorAll('[data-cy=injected-style-tag]');
53
- styles.forEach((styleElement) => {
54
- if (styleElement.parentElement) {
55
- styleElement.parentElement.removeChild(styleElement);
56
- }
57
- });
58
- const links = document.body.querySelectorAll('[data-cy=injected-stylesheet]');
59
- links.forEach((link) => {
60
- if (link.parentElement) {
61
- link.parentElement.removeChild(link);
51
+ function checkForRemovedStyleOptions(mountingOptions) {
52
+ for (const key of ['cssFile', 'cssFiles', 'style', 'styles', 'stylesheet', 'stylesheets']) {
53
+ if (mountingOptions[key]) {
54
+ Cypress.utils.throwErrByPath('mount.removed_style_mounting_options', key);
62
55
  }
63
- });
64
- }
65
- /**
66
- * Insert links to external style resources.
67
- */
68
- function insertStylesheets(stylesheets, document, el) {
69
- stylesheets.forEach((href) => {
70
- const link = document.createElement('link');
71
- link.type = 'text/css';
72
- link.rel = 'stylesheet';
73
- link.href = href;
74
- link.dataset.cy = 'injected-stylesheet';
75
- document.body.insertBefore(link, el);
76
- });
77
- }
78
- /**
79
- * Inserts a single stylesheet element
80
- */
81
- function insertStyles(styles, document, el) {
82
- styles.forEach((style) => {
83
- const styleElement = document.createElement('style');
84
- styleElement.dataset.cy = 'injected-style-tag';
85
- styleElement.appendChild(document.createTextNode(style));
86
- document.body.insertBefore(styleElement, el);
87
- });
88
- }
89
- function insertSingleCssFile(cssFilename, document, el, log) {
90
- return cy.readFile(cssFilename, { log }).then((css) => {
91
- const style = document.createElement('style');
92
- style.appendChild(document.createTextNode(css));
93
- document.body.insertBefore(style, el);
94
- });
95
- }
96
- /**
97
- * Reads the given CSS file from local file system
98
- * and adds the loaded style text as an element.
99
- */
100
- function insertLocalCssFiles(cssFilenames, document, el, log) {
101
- return Cypress.Promise.mapSeries(cssFilenames, (cssFilename) => {
102
- return insertSingleCssFile(cssFilename, document, el, log);
103
- });
56
+ }
104
57
  }
105
58
  /**
106
- * Injects custom style text or CSS file or 3rd party style resources
107
- * into the given document.
59
+ * Utility function to register CT side effects and run cleanup code during the "test:before:run" Cypress hook
60
+ * @param optionalCallback Callback to be called before the next test runs
108
61
  */
109
- const injectStylesBeforeElement = (options, document, el) => {
110
- if (!el)
111
- return;
112
- // first insert all stylesheets as Link elements
113
- let stylesheets = [];
114
- if (typeof options.stylesheet === 'string') {
115
- stylesheets.push(options.stylesheet);
116
- }
117
- else if (Array.isArray(options.stylesheet)) {
118
- stylesheets = stylesheets.concat(options.stylesheet);
119
- }
120
- if (typeof options.stylesheets === 'string') {
121
- options.stylesheets = [options.stylesheets];
122
- }
123
- if (options.stylesheets) {
124
- stylesheets = stylesheets.concat(options.stylesheets);
125
- }
126
- insertStylesheets(stylesheets, document, el);
127
- // insert any styles as <style>...</style> elements
128
- let styles = [];
129
- if (typeof options.style === 'string') {
130
- styles.push(options.style);
131
- }
132
- else if (Array.isArray(options.style)) {
133
- styles = styles.concat(options.style);
134
- }
135
- if (typeof options.styles === 'string') {
136
- styles.push(options.styles);
137
- }
138
- else if (Array.isArray(options.styles)) {
139
- styles = styles.concat(options.styles);
140
- }
141
- insertStyles(styles, document, el);
142
- // now load any css files by path and add their content
143
- // as <style>...</style> elements
144
- let cssFiles = [];
145
- if (typeof options.cssFile === 'string') {
146
- cssFiles.push(options.cssFile);
147
- }
148
- else if (Array.isArray(options.cssFile)) {
149
- cssFiles = cssFiles.concat(options.cssFile);
150
- }
151
- if (typeof options.cssFiles === 'string') {
152
- cssFiles.push(options.cssFiles);
153
- }
154
- else if (Array.isArray(options.cssFiles)) {
155
- cssFiles = cssFiles.concat(options.cssFiles);
156
- }
157
- return insertLocalCssFiles(cssFiles, document, el, options.log);
158
- };
159
62
  function setupHooks(optionalCallback) {
160
- // Consumed by the framework "mount" libs. A user might register their own mount in the scaffolded 'commands.js'
161
- // file that is imported by e2e and component support files by default. We don't want CT side effects to run when e2e
63
+ // We don't want CT side effects to run when e2e
162
64
  // testing so we early return.
163
65
  // System test to verify CT side effects do not pollute e2e: system-tests/test/e2e_with_mount_import_spec.ts
164
66
  if (Cypress.testingType !== 'component') {
@@ -173,7 +75,6 @@ function setupHooks(optionalCallback) {
173
75
  // @ts-ignore
174
76
  Cypress.on('test:before:run', () => {
175
77
  optionalCallback === null || optionalCallback === void 0 ? void 0 : optionalCallback();
176
- cleanupStyles();
177
78
  });
178
79
  }
179
80
 
@@ -13769,42 +13670,40 @@ mount: VTUmount,
13769
13670
  // available on the `VueTestUtils` import.
13770
13671
  shallowMount } = _VueTestUtils, VueTestUtils = __rest(_VueTestUtils, ["mount", "shallowMount"]);
13771
13672
  const DEFAULT_COMP_NAME = 'unknown';
13772
- Cypress.on('run:start', () => {
13773
- // `mount` is designed to work with component testing only.
13774
- // it assumes ROOT_SELECTOR exists, which is not the case in e2e.
13775
- // if the user registers a custom command that imports `cypress/vue`,
13776
- // this event will be registered and cause an error when the user
13777
- // launches e2e (since it's common to use Cypress for both CT and E2E.
13778
- // https://github.com/cypress-io/cypress/issues/17438
13779
- if (Cypress.testingType !== 'component') {
13780
- return;
13781
- }
13782
- Cypress.on('test:before:run', () => {
13783
- var _a;
13784
- (_a = Cypress.vueWrapper) === null || _a === void 0 ? void 0 : _a.unmount();
13785
- const el = getContainerEl();
13786
- el.innerHTML = '';
13787
- });
13788
- });
13789
- // implementation
13673
+ const VUE_ROOT = '__cy_vue_root';
13674
+ const cleanup = () => {
13675
+ var _a;
13676
+ (_a = Cypress.vueWrapper) === null || _a === void 0 ? void 0 : _a.unmount();
13677
+ Cypress.$(`#${VUE_ROOT}`).remove();
13678
+ Cypress.vueWrapper = null;
13679
+ Cypress.vue = null;
13680
+ };
13681
+ /**
13682
+ * Mounts a component and returns an object containing the component and VueWrapper
13683
+ * @param componentOptions
13684
+ * @param options
13685
+ * @returns {Cypress.Chainable<{wrapper: VueWrapper<T>, component: T}>}
13686
+ * @see {@link https://on.cypress.io/mounting-vue} for more details.
13687
+ * @example
13688
+ * import { mount } from '@cypress/vue'
13689
+ * import { Stepper } from './Stepper.vue'
13690
+ *
13691
+ * it('mounts', () => {
13692
+ * cy.mount(Stepper)
13693
+ * cy.get('[data-cy=increment]').click()
13694
+ * cy.get('[data-cy=counter]').should('have.text', '1')
13695
+ * })
13696
+ */
13790
13697
  function mount(componentOptions, options = {}) {
13791
- // TODO: get the real displayName and props from VTU shallowMount
13792
- const componentName = getComponentDisplayName(componentOptions);
13793
- const message = `<${componentName} ... />`;
13794
- let logInstance;
13698
+ checkForRemovedStyleOptions(options);
13699
+ // Remove last mounted component if cy.mount is called more than once in a test
13700
+ cleanup();
13795
13701
  // then wait for cypress to load
13796
13702
  return cy.then(() => {
13797
13703
  var _a, _b;
13798
- if (options.log !== false) {
13799
- logInstance = Cypress.log({
13800
- name: 'mount',
13801
- message: [message],
13802
- });
13803
- }
13804
13704
  // @ts-ignore
13805
13705
  const document = cy.state('document');
13806
13706
  const el = getContainerEl();
13807
- injectStylesBeforeElement(options, document, el);
13808
13707
  // merge the extensions with global
13809
13708
  if (options.extensions) {
13810
13709
  options.extensions.plugins = (_a = []) === null || _a === void 0 ? void 0 : _a.concat(options.extensions.plugins || [], options.extensions.use || []);
@@ -13812,23 +13711,37 @@ function mount(componentOptions, options = {}) {
13812
13711
  options.global = Object.assign(Object.assign({}, options.extensions), options.global);
13813
13712
  }
13814
13713
  const componentNode = document.createElement('div');
13815
- componentNode.id = '__cy_vue_root';
13714
+ componentNode.id = VUE_ROOT;
13816
13715
  el.append(componentNode);
13817
13716
  // mount the component using VTU and return the wrapper in Cypress.VueWrapper
13818
13717
  const wrapper = VTUmount(componentOptions, Object.assign({ attachTo: componentNode }, options));
13819
13718
  Cypress.vueWrapper = wrapper;
13820
13719
  Cypress.vue = wrapper.vm;
13821
13720
  return cy
13822
- .wrap(wrapper, { log: false })
13823
13721
  .wait(1, { log: false })
13824
13722
  .then(() => {
13825
- if (logInstance) {
13826
- logInstance.snapshot('mounted');
13827
- logInstance.end();
13723
+ if (options.log !== false) {
13724
+ // TODO: get the real displayName and props from VTU shallowMount
13725
+ const message = `<${getComponentDisplayName(componentOptions)} ... />`;
13726
+ Cypress.log({
13727
+ name: 'mount',
13728
+ message: [message],
13729
+ });
13828
13730
  }
13829
- // by returning undefined we keep the previous subject
13830
- // which is the mounted component
13831
- return undefined;
13731
+ const returnVal = {
13732
+ wrapper,
13733
+ component: wrapper.vm,
13734
+ };
13735
+ return new Proxy(Object.create(returnVal), {
13736
+ get(obj, prop) {
13737
+ // throw an error if it looks like the caller is trying to call a method on the VueWrapper that was originally returned
13738
+ if (Reflect.get(wrapper, prop)) {
13739
+ // @ts-expect-error - internal API
13740
+ Cypress.utils.throwErrByPath('mount.vue_yielded_value');
13741
+ }
13742
+ return Reflect.get(obj, prop);
13743
+ },
13744
+ });
13832
13745
  });
13833
13746
  });
13834
13747
  }
@@ -13857,10 +13770,14 @@ function getComponentDisplayName(componentOptions) {
13857
13770
  * @example
13858
13771
  * import {mountCallback} from '@cypress/vue'
13859
13772
  * beforeEach(mountVue(component, options))
13773
+ *
13774
+ * Removed as of Cypress 11.0.0.
13775
+ * @see https://on.cypress.io/migration-11-0-0-component-testing-updates
13860
13776
  */
13861
13777
  function mountCallback(component, options = {}) {
13862
13778
  return () => {
13863
- return mount(component, options);
13779
+ // @ts-expect-error - undocumented API
13780
+ Cypress.utils.throwErrByPath('mount.mount_callback');
13864
13781
  };
13865
13782
  }
13866
13783
  // Side effects from "import { mount } from '@cypress/<my-framework>'" are annoying, we should avoid doing this
@@ -13871,6 +13788,6 @@ function mountCallback(component, options = {}) {
13871
13788
  // import { registerCT } from 'cypress/<my-framework>'
13872
13789
  // registerCT()
13873
13790
  // Note: This would be a breaking change
13874
- setupHooks();
13791
+ setupHooks(cleanup);
13875
13792
 
13876
13793
  export { VueTestUtils, mount, mountCallback };