I'm using react with redux and testing with cypress, I was able to access the store using cy.window().its('store').invoke('getState').then((state) => {} But how do i access a component's local state rather than the application store?
I tried
cy.get('.simple-component').its('getState')
or
cy.get('.simple-component').invoke('getState')
but Cypress is returning "CypressError: Timed out retrying: cy.invoke() errored because the property: 'getState' does not exist on your subject" And on the Cypress console (in chrome) it's yeilding:
Yielded:
<div class="simple-component" getstate="[object Object]"></div>
It seems that's caused by React removing the methods from the DOM so i need to access it in React rather than in the DOM?
import React, { Component } from 'react';
class simpleComponent extends Component {
constructor(props) {
super(props)
this.state = {
sample: "hello"
}
}
// getState() just for testing on cypress
getState() {
return this.state
}
render(){
return <div className="simple-component" getState={this.getState()}></div>
}
}
As an alternative can i export the local component state at the end of the simple-component using window.store?
As of Cypress 7.0, the new Component Test Runner is now bundled with Cypress
From https://www.cypress.io/blog/2021/04/06/cypress-component-testing-react:
We still need to install the react adapter to mount components:
yarn add -D cypress @cypress/react @cypress/webpack-dev-server
add a glob pattern matching your component tests to cypress.json
:
{
"component": {
"testFiles": "**/*.test.{js,ts,jsx,tsx}",
"componentFolder": "src"
}
}
Tell Cypress to use @cypress/webpack-dev-server for component tests. in cypress/plugins/index.js
:
const injectDevServer = require("@cypress/react/plugins/react-scripts")
module.exports = (on, config) => {
injectDevServer(on, config)
return config
}
This will configure the Cypress Webpack Dev Server to use the same Webpack configuration as Create React App uses.
If you are using a different template, like Next.js, we have some other adapters available. It's also possible to create your own adapter.
There's a Cypress Plugin for that, called react-unit-test
. It gives you the ability to mount React
components directly (adds a cy.mount()
command) and provides access to the component's internal state.
Here's an example from the repo's readme:
// load Cypress TypeScript definitions for IntelliSense
/// <reference types="cypress" />
// import the component you want to test
import { HelloState } from '../../src/hello-x.jsx'
import React from 'react'
describe('HelloState component', () => {
it('works', () => {
// mount the component under test
cy.mount(<HelloState />)
// start testing!
cy.contains('Hello Spider-man!')
// mounted component can be selected via its name, function, or JSX
// e.g. '@HelloState', HelloState, or <HelloState />
cy.get(HelloState)
.invoke('setState', { name: 'React' })
cy.get(HelloState)
.its('state')
.should('deep.equal', { name: 'React' })
// check if GUI has rerendered
cy.contains('Hello React!')
})
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With