Co-authored-by: Дмитрий Коваленко <dmitrijkovalenko@Dmitrijs-MacBook-Pro.local> Co-authored-by: Dmitriy Kovalenko <dmtr.kovalenko@outlook.com>
example: Next.js
A typical project using next.js
Configuration
In order to reuse next's webpack configuration and all the custom configuration defined in next.config.js connect special plugin in plugin file
const preprocessor = require('@cypress/react/plugins/next')
module.exports = (on, config) => {
preprocessor(on, config)
return config
}
Usage
- Run
npm installin this folder to install dependencies.
# in this folder
npm install
- Start Cypress
npm run cy:open
# or just run headless tests
npm test
Server side props
⚠️⚠️ Important: ⚠️⚠️ Please do not test the page components using component testing. These components have too much responsibility and need to be tested as a part of your application flow. Consider using cypress integration tests.
But if you still want to test the page component, make sure that it will be mounted as any other pure React component. It means that next's specific functions like getInitialProps or getStaticProps won't be called.
But still you can call them manually:
IndexPage.getInitialProps().then(props => {
mount(<IndexPage {...props} />)
})
cy.contains(
'`.getInitialProps()` was called and passed props to this component',
)
Find more examples in Page.spec.jsx.
Router mocking
If your components depends on the next.js router (using useRouter or withRouter) we recommend to cover this component with integration tests, because this component is likely not reusable and depends on application flow. But if you still need to write component test for it you will likely meet the problem like cannot read property 'pathname' of undefined.
It happens because we render the component just like any other react component – without any specific next.js features. In order to make router work it is required to provide specific context that would be picked up by useRouter:
import { mount } from '@cypress/react'
import { RouterContext } from 'next/dist/next-server/lib/router-context'
// Create a router value you need for the components. Here are all available values as for next v9.5
// P.S. using cy.spy() here is not required, it is possible to pass simple () => {} function
const router = {
pathname: '/testPath',
route: '/testPath',
query: {},
asPath: '/testPath',
components: {},
isFallback: false,
basePath: '',
events: { emit: cy.spy(), off: cy.spy(), on: cy.spy() },
push: cy.spy(),
replace: cy.spy(),
reload: cy.spy(),
back: cy.spy(),
prefetch: cy.spy(),
beforePopState: cy.spy(),
}
// And wrap your component with special provider
mount(
<RouterContext.Provider value={router}>
<YourComponent />
</RouterContext.Provider>,
)
Find more examples in Router.spec.jsx
Mocking imports
Mocking imports is not working yet, seems the plugin we are inserting for loose mode causes problems, see issue 439.
