1
+ const Vue = require ( 'vue/dist/vue' )
1
2
const { stripIndent } = require ( 'common-tags' )
2
3
4
+ // mountVue options
5
+ const defaultOptions = [ 'html' , 'vue' , 'base' , 'mountId' , 'extensions' ]
6
+
7
+ // default mount point element ID for root Vue instance
8
+ const defaultMountId = 'app'
9
+
10
+ const parentDocument = window . parent . document
11
+ const projectName = Cypress . config ( 'projectName' )
12
+ const appIframeId = `Your App: '${ projectName } '`
13
+ const appIframe = parentDocument . getElementById ( appIframeId )
14
+
3
15
// having weak reference to styles prevents garbage collection
4
16
// and "losing" styles when the next test starts
5
17
const stylesCache = new Map ( )
@@ -23,10 +35,6 @@ const copyStyles = component => {
23
35
return
24
36
}
25
37
26
- const parentDocument = window . parent . document
27
- const projectName = Cypress . config ( 'projectName' )
28
- const appIframeId = `Your App: '${ projectName } '`
29
- const appIframe = parentDocument . getElementById ( appIframeId )
30
38
const head = appIframe . contentDocument . querySelector ( 'head' )
31
39
styles . forEach ( style => {
32
40
head . appendChild ( style )
@@ -42,59 +50,20 @@ const deleteCachedConstructors = component => {
42
50
Cypress . _ . values ( component . components ) . forEach ( deleteConstructor )
43
51
}
44
52
45
- const getVuePath = options =>
46
- options . vue || options . vuePath || '../node_modules/vue/dist/vue.js'
47
-
48
- const getVuexPath = options => options . vuex || options . vuexPath
49
-
50
53
const getPageHTML = options => {
51
- if ( options . html ) {
52
- return options . html
53
- }
54
- const vue = getVuePath ( options )
55
- let vuex = getVuexPath ( options )
56
- if ( vuex ) {
57
- vuex = `<script src="${ vuex } "></script>`
58
- }
59
-
60
- // note: add "base" tag to force loading static assets
61
- // from the server, not from the "spec" file URL
62
- if ( options . base ) {
63
- if ( vue . startsWith ( '.' ) ) {
64
- console . error (
65
- 'You are using base tag %s and relative Vue path %s' ,
66
- options . base ,
67
- vue
68
- )
69
- console . error ( 'the relative path might NOT work' )
70
- console . error (
71
- 'maybe pass Vue url using "https://unpkg.com/vue/dist/vue.js"'
72
- )
73
- }
74
- return stripIndent `
75
- <html>
76
- <head>
77
- <base href="${ options . base } " />
78
- </head>
79
- <body>
80
- <div id="app"></div>
81
- <script src="${ vue } "></script>
82
- </body>
83
- </html>
84
- `
85
- }
86
-
87
- const vueHtml = stripIndent `
54
+ return (
55
+ options . html ||
56
+ stripIndent `
88
57
<html>
89
- <head></head>
58
+ <head>
59
+ ${ options . base ? `<base href="${ options . base } " />` : '' }
60
+ </head>
90
61
<body>
91
- <div id="app"></div>
92
- <script src="${ vue } "></script>
93
- ${ vuex || '' }
62
+ <div id="${ options . mountId || defaultMountId } "></div>
94
63
</body>
95
64
</html>
96
65
`
97
- return vueHtml
66
+ )
98
67
}
99
68
100
69
const registerGlobalComponents = ( Vue , options ) => {
@@ -128,18 +97,16 @@ const installMixins = (Vue, options) => {
128
97
}
129
98
}
130
99
131
- const isOptionName = name =>
132
- [ 'vue' , 'html' , 'vuePath' , 'base' , 'extensions' ] . includes ( name )
100
+ const isOptionName = name => defaultOptions . includes ( name )
133
101
134
102
const isOptions = object => Object . keys ( object ) . every ( isOptionName )
135
103
136
104
const isConstructor = object => object && object . _compiled
137
105
138
106
const hasStore = ( { store } ) => store && store . _vm
139
107
140
- const forEachValue = ( obj , fn ) => {
108
+ const forEachValue = ( obj , fn ) =>
141
109
Object . keys ( obj ) . forEach ( key => fn ( obj [ key ] , key ) )
142
- }
143
110
144
111
const resetStoreVM = ( Vue , { store } ) => {
145
112
// bind store public getters
@@ -177,38 +144,51 @@ const mountVue = (component, optionsOrProps = {}) => () => {
177
144
props = optionsOrProps
178
145
}
179
146
180
- const vueHtml = getPageHTML ( options )
181
- const document = cy . state ( 'document' )
182
- document . write ( vueHtml )
183
- document . close ( )
184
-
185
- // TODO: do not log out "its(Vue)" command
186
- // but it currently does not support it
187
- return cy
188
- . window ( { log : false } )
189
- . its ( 'Vue' )
190
- . then ( Vue => {
191
- // refresh inner Vue instance of Vuex store
192
- if ( hasStore ( component ) ) {
193
- component . store = resetStoreVM ( Vue , component )
194
- }
195
- installMixins ( Vue , options )
196
- installPlugins ( Vue , options )
197
- registerGlobalComponents ( Vue , options )
198
- deleteCachedConstructors ( component )
199
-
200
- if ( isConstructor ( component ) ) {
201
- const Cmp = Vue . extend ( component )
202
- Cypress . vue = new Cmp ( props ) . $mount ( '#app' )
203
- copyStyles ( Cmp )
204
- } else {
205
- const allOptions = Object . assign ( { } , component , { el : '#app' } )
206
- Cypress . vue = new Vue ( allOptions )
207
- copyStyles ( component )
208
- }
209
-
210
- return Cypress . vue
211
- } )
147
+ // display deprecation warnings
148
+ if ( options . vue ) {
149
+ console . warn ( stripIndent `
150
+ [DEPRECATION]: 'vue' option has been deprecated.
151
+ 'node_modules/vue/dis/vue' is always used.
152
+ Please remove it from your 'mountVue' options.` )
153
+ }
154
+
155
+ // insert base app template
156
+ const doc = appIframe . contentDocument
157
+ doc . write ( getPageHTML ( options ) )
158
+ doc . close ( )
159
+
160
+ // get root Vue mount element
161
+ const mountId = options . mountId || defaultMountId
162
+ const el = doc . getElementById ( mountId )
163
+
164
+ // set global Vue instance:
165
+ // 1. convenience for debugging in DevTools
166
+ // 2. some libraries might check for this global
167
+ appIframe . contentWindow . Vue = Vue
168
+
169
+ // refresh inner Vue instance of Vuex store
170
+ if ( hasStore ( component ) ) {
171
+ component . store = resetStoreVM ( Vue , component )
172
+ }
173
+
174
+ // setup Vue instance
175
+ installMixins ( Vue , options )
176
+ installPlugins ( Vue , options )
177
+ registerGlobalComponents ( Vue , options )
178
+ deleteCachedConstructors ( component )
179
+
180
+ // create root Vue component
181
+ // and make it accessible via Cypress.vue
182
+ if ( isConstructor ( component ) ) {
183
+ const Cmp = Vue . extend ( component )
184
+ Cypress . vue = new Cmp ( props ) . $mount ( el )
185
+ copyStyles ( Cmp )
186
+ } else {
187
+ Cypress . vue = new Vue ( component ) . $mount ( el )
188
+ copyStyles ( component )
189
+ }
190
+
191
+ return cy . wrap ( Cypress . vue )
212
192
}
213
193
214
194
module . exports = mountVue
0 commit comments