cypress 10.10.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.
- package/angular/CHANGELOG.md +27 -0
- package/angular/dist/index.d.ts +124 -1
- package/angular/dist/index.js +59 -59
- package/lib/cli.js +15 -1
- package/lib/tasks/download.js +3 -7
- package/lib/util.js +2 -2
- package/mount-utils/CHANGELOG.md +7 -63
- package/mount-utils/README.md +5 -23
- package/mount-utils/dist/index.d.ts +25 -39
- package/mount-utils/dist/index.js +33 -112
- package/mount-utils/package.json +1 -0
- package/package.json +5 -4
- package/react/CHANGELOG.md +12 -55
- package/react/README.md +2 -22
- package/react/dist/cypress-react.cjs.js +92 -219
- package/react/dist/cypress-react.esm-bundler.js +92 -220
- package/react/dist/index.d.ts +111 -4
- package/react18/CHANGELOG.md +6 -106
- package/react18/dist/cypress-react.cjs.js +117 -180
- package/react18/dist/cypress-react.esm-bundler.js +103 -167
- package/react18/dist/index.d.ts +78 -6
- package/react18/package.json +1 -0
- package/svelte/CHANGELOG.md +20 -0
- package/svelte/dist/cypress-svelte.cjs.js +19 -114
- package/svelte/dist/cypress-svelte.esm-bundler.js +19 -114
- package/svelte/dist/index.d.ts +201 -1
- package/types/cypress-npm-api.d.ts +1 -1
- package/types/cypress.d.ts +43 -21
- package/vue/CHANGELOG.md +13 -101
- package/vue/README.md +4 -8
- package/vue/dist/cypress-vue.cjs.js +70 -153
- package/vue/dist/cypress-vue.esm-bundler.js +70 -153
- package/vue/dist/index.d.ts +1352 -104
- package/vue/package.json +1 -1
- package/vue2/CHANGELOG.md +15 -50
- package/vue2/README.md +3 -7
- package/vue2/dist/cypress-vue2.cjs.js +87 -211
- package/vue2/dist/cypress-vue2.esm-bundler.js +86 -210
- package/vue2/dist/index.d.ts +341 -172
- package/vue2/package.json +1 -3
- package/angular/dist/mount.d.ts +0 -112
- package/react/dist/createMount.d.ts +0 -31
- package/react/dist/getDisplayName.d.ts +0 -8
- package/react/dist/mount.d.ts +0 -8
- package/react/dist/mountHook.d.ts +0 -12
- package/react/dist/types.d.ts +0 -45
- package/svelte/dist/mount.d.ts +0 -30
- package/vue/dist/@vue/test-utils/baseWrapper.d.ts +0 -63
- package/vue/dist/@vue/test-utils/components/RouterLinkStub.d.ts +0 -21
- package/vue/dist/@vue/test-utils/config.d.ts +0 -30
- package/vue/dist/@vue/test-utils/constants/dom-events.d.ts +0 -900
- package/vue/dist/@vue/test-utils/createDomEvent.d.ts +0 -9
- package/vue/dist/@vue/test-utils/domWrapper.d.ts +0 -18
- package/vue/dist/@vue/test-utils/emit.d.ts +0 -5
- package/vue/dist/@vue/test-utils/errorWrapper.d.ts +0 -1
- package/vue/dist/@vue/test-utils/index.d.ts +0 -11
- package/vue/dist/@vue/test-utils/interfaces/wrapperLike.d.ts +0 -56
- package/vue/dist/@vue/test-utils/mount.d.ts +0 -35
- package/vue/dist/@vue/test-utils/stubs.d.ts +0 -22
- package/vue/dist/@vue/test-utils/types.d.ts +0 -125
- package/vue/dist/@vue/test-utils/utils/autoUnmount.d.ts +0 -5
- package/vue/dist/@vue/test-utils/utils/compileSlots.d.ts +0 -2
- package/vue/dist/@vue/test-utils/utils/componentName.d.ts +0 -4
- package/vue/dist/@vue/test-utils/utils/find.d.ts +0 -10
- package/vue/dist/@vue/test-utils/utils/flushPromises.d.ts +0 -1
- package/vue/dist/@vue/test-utils/utils/getRootNodes.d.ts +0 -2
- package/vue/dist/@vue/test-utils/utils/isElement.d.ts +0 -1
- package/vue/dist/@vue/test-utils/utils/isElementVisible.d.ts +0 -6
- package/vue/dist/@vue/test-utils/utils/matchName.d.ts +0 -1
- package/vue/dist/@vue/test-utils/utils/stringifyNode.d.ts +0 -1
- package/vue/dist/@vue/test-utils/utils/vueCompatSupport.d.ts +0 -8
- package/vue/dist/@vue/test-utils/utils/vueShared.d.ts +0 -3
- package/vue/dist/@vue/test-utils/utils.d.ts +0 -13
- package/vue/dist/@vue/test-utils/vueWrapper.d.ts +0 -35
- package/vue/dist/@vue/test-utils/wrapperFactory.d.ts +0 -14
package/vue/README.md
CHANGED
@@ -34,23 +34,19 @@ describe('HelloWorld component', () => {
|
|
34
34
|
|
35
35
|
Look at the examples in [cypress/component](cypress/component) folder. Here is the list of examples showing various testing scenarios.
|
36
36
|
|
37
|
-
###
|
37
|
+
### Styles
|
38
38
|
|
39
|
-
|
39
|
+
One option for styling your components is to import stylesheets into your test file. See [docs/styles.md](./docs/styles.md) for full list of options.
|
40
40
|
|
41
41
|
```js
|
42
42
|
import Todo from './Todo.vue'
|
43
|
+
import '../styles/main.css'
|
43
44
|
const todo = {
|
44
45
|
id: '123',
|
45
46
|
title: 'Write more tests',
|
46
47
|
}
|
47
48
|
|
48
|
-
mount(Todo, {
|
49
|
-
propsData: { todo },
|
50
|
-
stylesheets: [
|
51
|
-
'https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.css',
|
52
|
-
],
|
53
|
-
})
|
49
|
+
mount(Todo, { props: { todo } })
|
54
50
|
```
|
55
51
|
|
56
52
|
### Global Vue Options
|
@@ -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
|
-
|
71
|
-
|
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
|
-
*
|
130
|
-
*
|
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
|
-
//
|
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
|
-
|
13796
|
-
|
13797
|
-
|
13798
|
-
|
13799
|
-
|
13800
|
-
|
13801
|
-
|
13802
|
-
|
13803
|
-
|
13804
|
-
|
13805
|
-
|
13806
|
-
|
13807
|
-
|
13808
|
-
|
13809
|
-
|
13810
|
-
|
13811
|
-
}
|
13812
|
-
|
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
|
-
|
13815
|
-
|
13816
|
-
|
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,29 +13734,43 @@ 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 =
|
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 (
|
13849
|
-
|
13850
|
-
|
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
|
-
|
13853
|
-
|
13854
|
-
|
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
|
}
|
13858
13771
|
/**
|
13859
|
-
* Extract the
|
13860
|
-
* @param componentOptions the
|
13772
|
+
* Extract the component name from the object passed to mount
|
13773
|
+
* @param componentOptions the component passed to mount
|
13861
13774
|
* @returns name of the component
|
13862
13775
|
*/
|
13863
13776
|
function getComponentDisplayName(componentOptions) {
|
@@ -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
|
-
|
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
|
-
|
48
|
-
|
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
|
-
*
|
107
|
-
*
|
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
|
-
//
|
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
|
-
|
13773
|
-
|
13774
|
-
|
13775
|
-
|
13776
|
-
|
13777
|
-
|
13778
|
-
|
13779
|
-
|
13780
|
-
|
13781
|
-
|
13782
|
-
|
13783
|
-
|
13784
|
-
|
13785
|
-
|
13786
|
-
|
13787
|
-
|
13788
|
-
}
|
13789
|
-
|
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
|
-
|
13792
|
-
|
13793
|
-
|
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,29 +13711,43 @@ 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 =
|
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 (
|
13826
|
-
|
13827
|
-
|
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
|
-
|
13830
|
-
|
13831
|
-
|
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
|
}
|
13835
13748
|
/**
|
13836
|
-
* Extract the
|
13837
|
-
* @param componentOptions the
|
13749
|
+
* Extract the component name from the object passed to mount
|
13750
|
+
* @param componentOptions the component passed to mount
|
13838
13751
|
* @returns name of the component
|
13839
13752
|
*/
|
13840
13753
|
function getComponentDisplayName(componentOptions) {
|
@@ -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
|
-
|
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 };
|