question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Component tests with create-react-app (react-scripts-v4) don't instrument

See original GitHub issue

I’ve been trying to get code coverage working for the last few days using the fragments of documentation I can find throughout the Cypress offical site and code repos…

App is CRA Using @cypress/instrument-cra@latest

Using example react-scripts-v4

Simple test using Card.js

import React from 'react'

const Card = () => <div>Card</div>

export default Card

Card.test.js

import React from 'react'
import { mount } from '@cypress/react'
import Card from './Card'

it('renders learn react link', () => {
    mount(<Card />)
    expect(cy.get('div').contains('Card'))
})

cypress.json

{
  "testFiles": "**/*.test.{js,ts,jsx,tsx}",
  "componentFolder": "src"
}

plugins/index.js

const injectDevServer = require('@cypress/react/plugins/react-scripts')

module.exports = (on, config) => {
    injectDevServer(on, config)
    require('@cypress/code-coverage/task')(on, config)

    // add other tasks to be registered here

    // IMPORTANT to return the config object
    // with the any changed environment variables
    return config
}

support/index.js

require('@cypress/code-coverage/support')

package.json

{
  "name": "react-scripts-v4",
  "description": "Instrumented code for react-scripts v4",
  "private": true,
  "scripts": {
    "start": "react-scripts -r @cypress/instrument-cra start",
    "test": "cypress open-ct",
    "cy:open": "cypress open",
    "check-coverage": "check-coverage src/App.js src/calc.js src/Child.js src/index.js",
    "only-covered": "only-covered src/App.js src/calc.js src/Child.js src/index.js"
  },
  "devDependencies": {
    "@cypress/code-coverage": "^3.9.6",
    "@cypress/instrument-cra": "^1.4.0",
    "@cypress/react": "^5.9.1",
    "@cypress/webpack-dev-server": "^1.3.1",
    "check-code-coverage": "^1.10.0",
    "cypress": "^7.5.0",
    "cypress-expect": "^2.4.1",
    "html-webpack-plugin": "4",
    "react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-scripts": "^4.0.3"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

Basically I do this:

> yarn start

> yarn test

The out.json in .nyc_output/out.json just contains an empty object {}

I should also note that when I do yarn start and check window.__coverage__ in the web console, it shows the expected output. The issue is when I run the component tests, the nyc output doesn’t have any coverage info.

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:4
  • Comments:9

github_iconTop GitHub Comments

11reactions
twhoffcommented, Jun 11, 2021

Okay, I’ve resolved my issue!

Following the docs, you most likely end up with a plugins/index.js file which looks like this:

// cypress/plugins/index.js

const injectDevServer = require('@cypress/react/plugins/react-scripts')

module.exports = (on, config) => {
  // Webpack Dev Server for rendering React components using the `mount()` function
  injectDevServer(on, config)

  // Cypress code coverage
  require('@cypress/code-coverage/task')(on, config)

  // Supposedly instrument unit tests (component) specs
  on(
    'file:preprocessor',
    require('@cypress/code-coverage/use-browserify-istanbul')
  )
  return config
}

The file:preprocessor step does not work.

Instead, I found that spinning up a custom webpack dev server using the Cypress presets and loading the babel-plugin-istanbul (similar to how @cypress/instrument-cra works) works a treat.

Here is my current plugins/index.js:

const { startDevServer } = require('@cypress/webpack-dev-server')
const findReactScriptsWebpackConfig = require('@cypress/react/plugins/react-scripts/findReactScriptsWebpackConfig')

const customDevServer = (
    on,
    config,
    { webpackConfigPath } = {
        webpackConfigPath: 'react-scripts/config/webpack.config',
    }
) => {
    on('dev-server:start', async (options) => {
        const webpackConfig = findReactScriptsWebpackConfig(config, {
            webpackConfigPath,
        })
        const rules = webpackConfig.module.rules.find(
            (rule) => !!rule.oneOf
        ).oneOf
        const babelRule = rules.find((rule) => /babel-loader/.test(rule.loader))
        babelRule.options.plugins.push(require.resolve('babel-plugin-istanbul'))
        return startDevServer({
            options,
            webpackConfig,
        })
    })

    config.env.reactDevtools = true

    return config
}

module.exports = (on, config) => {
    customDevServer(on, config)
    require('@cypress/code-coverage/task')(on, config)

    return config
}
2reactions
EricPalmer22commented, Jun 23, 2021

@twhoff thank you so much for this post! Just got coverage working for my component tests using your strat here 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Running Tests | Create React App
There is a broad spectrum of component testing techniques. They range from a “smoke test” verifying that a component renders without throwing, ...
Read more >
Unit testing React components in Cypress without CRA and ...
So you have an app or component library that you have created without create-react-app and you want to unit test it using Cypress....
Read more >
react-scripts update from 3.4 to 4.0 causes Jest version error
Open the terminal in the current directory and run npm ls babel-jest - this will show u what other dependency in your project...
Read more >
UNIT testing your create React app Components VISUALLY
That's right - visual unit testing. Cypress is great for integration testing. But why not take it a step further and use it...
Read more >
Testing Recipes - React
Testing Recipes. Common testing patterns for React components. Note: This page assumes you're using Jest as a test runner. If you use a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found