Cypress jump

Create a React component using JSX and inject it into live application from a Cypress test.

Crazy cool thing I found out about Cypress today:

  • you can use JSX inside Cypress specs, just make sure to require React
spec.js
1
2
3
const React = require('react')
const Welcome = (props) =>
<p onClick={props.onClick}>Hello, {props.name}</p>
  • you can mount React component from spec into application
spec.js
1
2
3
4
5
6
7
8
const ReactDOM = require('react-dom')
it('injects dynamic React component and it works', () => {
cy.visit('index.html')
cy.get('#app').then(el$ => {
const welcomeGleb = <Welcome name="Gleb"/>
ReactDOM.render(welcomeGleb, el$[0])
})
})

and the application under test is a static html without ANY code

index.html
1
2
3
4
<body>
<div id="app">Some text</div>
<div>Some text after it</div>
</body>
  • you can pass Cypress Sinon stub as a property and make assertions against it
spec.js
1
2
3
4
5
6
7
8
9
10
11
12
13
it('injects dynamic React component and it works', () => {
cy.visit('index.html')
const onClick = cy.stub().as('click')
cy.get('#app').then(el$ => {
const welcomeGleb = <Welcome name="Gleb" onClick={onClick} />
ReactDOM.render(welcomeGleb, el$[0])
})

cy.log('Testing injected element by clicking on it')
// notice that we are using text that is created by `welcomeGleb` element
cy.contains('Hello, Gleb').click().click()
cy.get('@click').should('have.been.calledTwice')
})

and this crazy contraption somehow works!

Working test with injected React component

You can find the source code for this blog post in https://github.com/bahmutov/cypress-injects-react-element repo.

In related news, check out cypress-react-unit-test - maybe the example shown in this blog post will make cypress-react-unit-test obsolete?