Skip to content

Commit

Permalink
fix vue2 global directives in component testing
Browse files Browse the repository at this point in the history
  • Loading branch information
Stepan Rusakov committed Nov 1, 2022
1 parent a3770f2 commit 5480fca
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 7 deletions.
29 changes: 25 additions & 4 deletions npm/vue2/README.md
Expand Up @@ -57,10 +57,31 @@ You can pass extensions (global components, mixins, modules to use)
when mounting Vue component. Use `{ extensions: { ... }}` object inside
the `options`.

- `components` - object of 'id' and components to register globally, see [Components](cypress/component/basic/components) example
- `use` (alias `plugins`) - list of plugins, see [Plugins](cypress/component/basic/plugins)
- `mixin` (alias `mixins`) - list of global mixins, see [Mixins](cypress/component/basic/mixins) example
- `filters` - hash of global filters, see [Filters](cypress/component/basic/filters) example
- `components` - object of 'id' and components to register globally. See docs [here](https://v2.vuejs.org/v2/guide/components-registration.html#Global-Registration).
- `use` (alias `plugins`) - list of plugins. See docs [here](https://v2.vuejs.org/v2/guide/plugins.html#Using-a-Plugin).
- `mixin` (alias `mixins`) - list of global mixins. See docs [here](https://v2.vuejs.org/v2/guide/mixins.html#Global-Mixin).
- `filters` - hash of global filters. See docs [here](https://v2.vuejs.org/v2/guide/filters.html).
- `directives` - global directives, see `directives` docs [here](https://v2.vuejs.org/v2/guide/custom-directive.html#ad) and [here](https://vuejs.org/guide/reusability/custom-directives.html).

```js
import Todo from './Todo.vue'
import MyMixin1 from '../mixins/MyMixin1'
import MyMixin2 from '../mixins/MyMixin2'
import MyPlugin from '../plugins/MyPlugin'
import MyGlobalComponent1 from '../global/MyGlobalComponent1.vue'
import MyGlobalComponent2 from '../global/MyGlobalComponent2.vue'
import MyDirective from '../directives/MyDirective'

mount(Todo, {
extensions: {
mixins: [MyMixin1, MyMixin2],
plugins: [MyPlugin],
// or use: [MyPlugin]
components: { MyGlobalComponent1, MyGlobalComponent2 },
directives: { MyDirective },
}
})
```

## Compatibility

Expand Down
37 changes: 37 additions & 0 deletions npm/vue2/src/index.ts
Expand Up @@ -69,6 +69,17 @@ const installMixins = (Vue, options) => {
}
}

const registerGlobalDirectives = (Vue, options) => {
const directives =
Cypress._.get(options, 'extensions.directives')

if (Cypress._.isPlainObject(directives)) {
Object.keys(directives).forEach((name) => {
Vue.directive(name, directives[name])
})
}
}

const hasStore = ({ store }: { store: any }) => Boolean(store && store._vm)

const forEachValue = <T>(obj: Record<string, T>, fn: (value: T, key: string) => void) => {
Expand Down Expand Up @@ -127,6 +138,10 @@ type VueFilters = {
[key: string]: (value: string) => string
}

type VueDirectives = {
[key: string]: Function | Object
}

type VueMixin = unknown
type VueMixins = VueMixin | VueMixin[]

Expand Down Expand Up @@ -211,6 +226,27 @@ interface MountOptionsExtensions {
* @memberof MountOptionsExtensions
*/
plugins?: VuePlugins

/**
* Optional Vue directives to install while mounting the component
*
* @memberof MountOptionsExtensions
* @see https://github.com/cypress-io/cypress/tree/develop/npm/vue#examples
* @example
* const directives = {
* custom: {
* name: 'custom',
* bind (el, binding) {
* el.dataset['custom'] = binding.value
* },
* unbind (el) {
* el.removeAttribute('data-custom')
* },
* },
* }
* mount(Hello, { extensions: { directives }})
*/
directives?: VueDirectives
}

/**
Expand Down Expand Up @@ -400,6 +436,7 @@ export const mount = (
installFilters(localVue, options)
installMixins(localVue, options)
installPlugins(localVue, options, props)
registerGlobalDirectives(localVue, options)
registerGlobalComponents(localVue, options)

props.attachTo = componentNode
Expand Down
2 changes: 1 addition & 1 deletion system-tests/projects/vueclivue2-configured/README.md
@@ -1,4 +1,4 @@
# vueclivue2-unconfigured
# vueclivue2-configured

## Project setup
```
Expand Down
@@ -0,0 +1,9 @@
<template>
<div class="child" v-custom="test" />
</template>

<script>
export default {
name: 'GlobalComponentWithCustomDirective',
}
</script>
@@ -1,5 +1,7 @@
import { mount } from 'cypress/vue2'
import HelloWorld from './HelloWorld.vue'
import GlobalComponentWithCustomDirective from './GlobalComponentWithCustomDirective.vue'
import custom from '../directive'

describe('<Logo />', () => {
it('contains the default slot in its h1', () => {
Expand All @@ -13,4 +15,30 @@ describe('<Logo />', () => {

cy.contains('h1', slotContent)
})

it('Vue2 custom directive should work ', () => {
mount(GlobalComponentWithCustomDirective, {
extensions: {
directives: { custom },
},
})

cy.get('.child').should('have.attr', 'data-custom', 'test')
})

it('Vue2 custom directive should work in nested component', () => {
const slotContent = 'Welcome to testing in Vue CLI'

mount(HelloWorld, {
propsData: {
msg: slotContent,
},
extensions: {
components: { GlobalComponentWithCustomDirective },
directives: { custom },
},
})

cy.get('.child').should('have.attr', 'data-custom', 'test')
})
})
Expand Up @@ -25,6 +25,7 @@
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
<GlobalComponentWithCustomDirective/>
</div>
</template>

Expand Down
9 changes: 9 additions & 0 deletions system-tests/projects/vueclivue2-configured/src/directive.js
@@ -0,0 +1,9 @@
export default {
name: 'custom',
bind (el, binding) {
el.dataset['custom'] = binding.value
},
unbind (el) {
el.removeAttribute('data-custom')
},
}
8 changes: 7 additions & 1 deletion system-tests/projects/vueclivue2-configured/src/main.js
@@ -1,8 +1,14 @@
import Vue from 'vue'
import App from './App.vue'
import GlobalComponentWithCustomDirective from './components/GlobalComponentWithCustomDirective.vue'
import custom from './directive'

Vue.config.productionTip = false
Vue.component('GlobalComponentWithCustomDirective', GlobalComponentWithCustomDirective)
Vue.directive('custom', custom)

new Vue({
render: function (h) { return h(App) },
render (h) {
return h(App)
},
}).$mount('#app')
3 changes: 2 additions & 1 deletion tooling/v8-snapshot/cache/dev-linux/snapshot-meta.cache.json
Expand Up @@ -47,6 +47,7 @@
"./packages/network/node_modules/minimatch/minimatch.js",
"./packages/server/lib/modes/record.js",
"./packages/server/lib/modes/run.ts",
"./packages/server/lib/open_project.ts",
"./packages/server/node_modules/@benmalka/foxdriver/node_modules/graceful-fs/polyfills.js",
"./packages/server/node_modules/glob/node_modules/minimatch/minimatch.js",
"./packages/server/node_modules/graceful-fs/polyfills.js",
Expand Down Expand Up @@ -3526,5 +3527,5 @@
"./tooling/v8-snapshot/cache/dev-linux/snapshot-entry.js"
],
"deferredHashFile": "yarn.lock",
"deferredHash": "95205f49259fe2d246d45ef15d1499f6e3d1d235d6db892124bbd5423f1ba872"
"deferredHash": "b23274a95457555a9102f7f660744b1a8f08324bfcfa01be64771c12fcb3ae35"
}

0 comments on commit 5480fca

Please sign in to comment.