Skip to content

Commit 741019d

Browse files
crazyk2lmiller1990ZachJW34
authored
fix: vue2 global directives in component testing (#24488)
* fix vue2 global directives in component testing * fix vue2 global directives in component testing * update test * comment out flaky spec [skip ci] Co-authored-by: Lachlan Miller <[email protected]> Co-authored-by: Zachary Williams <[email protected]>
1 parent cd23432 commit 741019d

File tree

9 files changed

+108
-4
lines changed

9 files changed

+108
-4
lines changed

npm/vue2/src/index.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@ const installMixins = (Vue, options) => {
6767
}
6868
}
6969

70+
const registerGlobalDirectives = (Vue, options) => {
71+
const directives =
72+
Cypress._.get(options, 'extensions.directives')
73+
74+
if (Cypress._.isPlainObject(directives)) {
75+
Object.keys(directives).forEach((name) => {
76+
Vue.directive(name, directives[name])
77+
})
78+
}
79+
}
80+
7081
const hasStore = ({ store }: { store: any }) => Boolean(store && store._vm)
7182

7283
const forEachValue = <T>(obj: Record<string, T>, fn: (value: T, key: string) => void) => {
@@ -125,6 +136,10 @@ type VueFilters = {
125136
[key: string]: (value: string) => string
126137
}
127138

139+
type VueDirectives = {
140+
[key: string]: Function | Object
141+
}
142+
128143
type VueMixin = unknown
129144
type VueMixins = VueMixin | VueMixin[]
130145

@@ -209,6 +224,27 @@ interface MountOptionsExtensions {
209224
* @memberof MountOptionsExtensions
210225
*/
211226
plugins?: VuePlugins
227+
228+
/**
229+
* Optional Vue directives to install while mounting the component
230+
*
231+
* @memberof MountOptionsExtensions
232+
* @see https://github.com/cypress-io/cypress/tree/develop/npm/vue#examples
233+
* @example
234+
* const directives = {
235+
* custom: {
236+
* name: 'custom',
237+
* bind (el, binding) {
238+
* el.dataset['custom'] = binding.value
239+
* },
240+
* unbind (el) {
241+
* el.removeAttribute('data-custom')
242+
* },
243+
* },
244+
* }
245+
* mount(Hello, { extensions: { directives }})
246+
*/
247+
directives?: VueDirectives
212248
}
213249

214250
/**
@@ -382,6 +418,7 @@ export const mount = (
382418
installFilters(localVue, options)
383419
installMixins(localVue, options)
384420
installPlugins(localVue, options, props)
421+
registerGlobalDirectives(localVue, options)
385422
registerGlobalComponents(localVue, options)
386423

387424
props.attachTo = componentNode

packages/app/cypress/e2e/runner/reporter-ct-mount-hover.cy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ type ProjectDirs = typeof fixtureDirs
44

55
const PROJECTS: {projectName: ProjectDirs[number], test: string}[] = [
66
{ projectName: 'angular-14', test: 'app.component' },
7-
{ projectName: 'vueclivue2-configured', test: 'HelloWorld.cy' },
7+
// TODO: Flaky. { projectName: 'vueclivue2-configured', test: 'HelloWorld.cy' },
88
{ projectName: 'react-vite-ts-configured', test: 'App.cy' },
99
{ projectName: 'react18', test: 'App.cy' },
1010
{ projectName: 'create-react-app-configured', test: 'App.cy' },

system-tests/projects/vueclivue2-configured/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# vueclivue2-unconfigured
1+
# vueclivue2-configured
22

33
## Project setup
44
```
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<template>
2+
<div class="child" v-custom="test" />
3+
</template>
4+
5+
<script>
6+
export default {
7+
name: 'GlobalComponentWithCustomDirective',
8+
data () {
9+
return {
10+
test: 'testing123'
11+
}
12+
}
13+
}
14+
</script>

system-tests/projects/vueclivue2-configured/src/components/HelloWorld.cy.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import { mount } from 'cypress/vue2'
22
import HelloWorld from './HelloWorld.vue'
3+
import GlobalComponentWithCustomDirective from './GlobalComponentWithCustomDirective.vue'
4+
import custom from '../directive'
35

46
describe('<Logo />', () => {
57
it('contains the default slot in its h1', () => {
@@ -9,8 +11,43 @@ describe('<Logo />', () => {
911
propsData: {
1012
msg: slotContent,
1113
},
14+
extensions: {
15+
components: {
16+
// stubbing for simplicity, this smoke test does not depend on
17+
// GlobalComponent
18+
GlobalComponentWithCustomDirective: {
19+
render: h => h('div')
20+
}
21+
},
22+
}
1223
})
1324

1425
cy.contains('h1', slotContent)
1526
})
27+
28+
it('Vue2 custom directive should work ', () => {
29+
mount(GlobalComponentWithCustomDirective, {
30+
extensions: {
31+
directives: { custom },
32+
},
33+
})
34+
35+
cy.get('.child').should('have.attr', 'data-custom', 'testing123')
36+
})
37+
38+
it('Vue2 custom directive should work in nested component', () => {
39+
const slotContent = 'Welcome to testing in Vue CLI'
40+
41+
mount(HelloWorld, {
42+
propsData: {
43+
msg: slotContent,
44+
},
45+
extensions: {
46+
components: { GlobalComponentWithCustomDirective },
47+
directives: { custom },
48+
},
49+
})
50+
51+
cy.get('.child').should('have.attr', 'data-custom', 'testing123')
52+
})
1653
})

system-tests/projects/vueclivue2-configured/src/components/HelloWorld.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
2626
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
2727
</ul>
28+
<GlobalComponentWithCustomDirective/>
2829
</div>
2930
</template>
3031

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export default {
2+
name: 'custom',
3+
bind (el, binding) {
4+
el.dataset['custom'] = binding.value
5+
},
6+
unbind (el) {
7+
el.removeAttribute('data-custom')
8+
},
9+
}
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
import Vue from 'vue'
22
import App from './App.vue'
3+
import GlobalComponentWithCustomDirective from './components/GlobalComponentWithCustomDirective.vue'
4+
import custom from './directive'
35

46
Vue.config.productionTip = false
7+
Vue.component('GlobalComponentWithCustomDirective', GlobalComponentWithCustomDirective)
8+
Vue.directive('custom', custom)
59

610
new Vue({
7-
render: function (h) { return h(App) },
11+
render (h) {
12+
return h(App)
13+
},
814
}).$mount('#app')

tooling/v8-snapshot/cache/dev-linux/snapshot-meta.cache.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3528,4 +3528,4 @@
35283528
],
35293529
"deferredHashFile": "yarn.lock",
35303530
"deferredHash": "ce60d1d6cc0c77f20dcfc741105a5c53593752f814bf3cab816a3024faf68bfc"
3531-
}
3531+
}

0 commit comments

Comments
 (0)