Skip to content
This repository has been archived by the owner on Dec 12, 2020. It is now read-only.

Commit

Permalink
feat: rest render function components (#343)
Browse files Browse the repository at this point in the history
```
<app-component :elementtype = "'div,blue,30,div1'">Hello World</app-component>
```

for individual component to be mounted

```js
mount(appComponent, {
  propsData: {
    elementtype: 'h3,red,30,h3tag',
  },
})
```
  • Loading branch information
bahmutov authored Jul 7, 2020
1 parent e0fa815 commit ac778f3
Show file tree
Hide file tree
Showing 5 changed files with 206 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,7 @@ Spec | Description
Spec | Description
--- | ---
[mocking-imports](cypress/component/advanced/mocking-imports) | Stub ES6 imports from the tests
[render-functions](cypress/component/advanced/render-functions) | Mounting components with a [render function](https://www.tutorialandexample.com/vue-js-render-functions/)
<!-- prettier-ignore-end -->

### Full examples
Expand Down
7 changes: 7 additions & 0 deletions cypress/component/advanced/render-functions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# render functions

Based on examples from [Vue.js Render Functions](https://www.tutorialandexample.com/vue-js-render-functions/) tutorial.

See [spec.js](spec.js) for examples of mounting a component, using multiple components, passing props data.

![Components](./images/colors.png)
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
189 changes: 189 additions & 0 deletions cypress/component/advanced/render-functions/spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
/// <reference types="cypress" />
import { mount } from 'cypress-vue-unit-test'

describe('Single render function component', () => {
// the component definition
const appComponent = {
template: '<h1>hi! This is a Render Function Example</h1>',
data() {
return {}
},
}

const mountOptions = {
// we want to use custom app component above
extensions: {
components: {
'app-component': appComponent,
},
},
}

it('loads', () => {
mount(
{
template: `
<div>
<app-component></app-component>
</div>
`,
},
mountOptions,
)
cy.contains('h1', 'hi!')
})

it('loads 3 times', () => {
// tip: always have top level single root element
mount(
{
template: `
<div>
<app-component></app-component>
<app-component></app-component>
<app-component>foo</app-component>
</div>
`,
},
mountOptions,
)
cy.get('h1')
.should('have.length', 3)
.each(($el) => {
expect($el).to.contain('hi!')
})
})
})

describe('Component with slot', () => {
// the component definition
const appComponent = {
template: '<h1><slot></slot></h1>',
data() {
return {}
},
}

const mountOptions = {
// we want to use custom app component above
extensions: {
components: {
'app-component': appComponent,
},
},
}

it('loads', () => {
mount(
{
template: `
<div>
<app-component>Hello</app-component>
</div>
`,
},
mountOptions,
)
cy.contains('h1', 'Hello')
})

it('loads 3 different components', () => {
// tip: always have top level single root element
mount(
{
template: `
<div>
<app-component>Hello World</app-component>
<app-component>Hello John</app-component>
<app-component>Hello Peter</app-component>
</div>
`,
},
mountOptions,
)
cy.get('h1')
.should('have.length', 3)
.and(($el) => {
expect($el[0]).to.have.text('Hello World')
expect($el[1]).to.have.text('Hello John')
expect($el[2]).to.have.text('Hello Peter')
})
})
})

describe('Component with arguments', () => {
// the component definition
const appComponent = {
render: function (createElement) {
var a = this.elementtype.split(',')
return createElement(
a[0],
{
attrs: {
id: a[3],
style: 'color:' + a[1] + ';font-size:' + a[2] + ';',
},
},
this.$slots.default || '<EMPTY>',
)
},
props: {
elementtype: {
attributes: String,
required: true,
},
},
}

const mountOptions = {
// we want to use custom app component above
extensions: {
components: {
'app-component': appComponent,
},
},
}

it('renders different colors', () => {
// tip: always have top level single root element
mount(
{
template: `
<div>
<app-component :elementtype = "'div,blue,30,div1'">Hello World</app-component>
<app-component :elementtype = "'h3,red,30,h3tag'">Hello Peter</app-component>
<app-component :elementtype = "'p,green,30,ptag'">Hello John</app-component>
<app-component :elementtype = "'div,violet,30,divtag'">Hello Herry</app-component>
</div>
`,
},
mountOptions,
)

cy.contains('h3', 'Hello Peter').should(
'have.attr',
'style',
'color:red;font-size:30;',
)

cy.contains('p', 'Hello John').should(
'have.attr',
'style',
'color:green;font-size:30;',
)
})

it('mounts just the component and passes props', () => {
mount(appComponent, {
propsData: {
elementtype: 'h3,red,30,h3tag',
},
})
// the component appears and the styling is applied
cy.contains('<EMPTY>').should(
'have.attr',
'style',
'color:red;font-size:30;',
)
})
})
9 changes: 9 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,15 @@ const mountVue = (component, optionsOrProps = {}) => {
component.store = resetStoreVM(Vue, component)
}

// render function components should be market to be properly initialized
// https://github.com/bahmutov/cypress-vue-unit-test/issues/313
if (
Cypress._.isPlainObject(component) &&
Cypress._.isFunction(component.render)
) {
component._compiled = true
}

return cy.window({ log: false }).then((win) => {
win.Vue = Vue

Expand Down

0 comments on commit ac778f3

Please sign in to comment.