Open twhoff opened 3 years ago
UPDATE: After a bit of digging, I've found that the window.coverage object is missing from the output of the mount()
function used in mounting React components. So it looks like the instrumentation needs to be baked into this somehow... Any ideas?
I've tried using the browserify
pre-processor with the use-browserify-istanbul
plugin added onBundle
but still no effect:
const injectDevServer = require('@cypress/react/plugins/react-scripts')
const browserify = require('@cypress/browserify-preprocessor')
module.exports = (on, config) => {
injectDevServer(on, config)
require('@cypress/code-coverage/task')(on, config)
on(
'file:preprocessor',
browserify({
onBundle(bundle) {
bundle.plugin('@cypress/code-coverage/use-browserify-istanbul')
},
})
)
console.log('THE CONFIG: ', config)
return config
}
Same goes for the webpack pre-processor with istanbul
added as a babel-loader rule plugin... will keep trying.
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
}
@twhoff thank you so much for this post! Just got coverage working for my component tests using your strat here :)
@twhoff thank you so much for this post! Just got coverage working for my component tests using your strat here :)
Glad I could help!
Another thank you here @twhoff! Spent all morning trying to get this to work before coming across your config file.
@twhoff, your resource was the most relevant and best one in an internet scattered with loose solutions on this problem. I took some ideas and tried them out but could not get it working in my repro (small differences in that it's not a CRA and just a component library using Cypress for unit tests). I know you are busy, but if there are any similarities and your deeper experience on the problem, could you point me on what else I may have to do to get my minimal repro working in https://github.com/cypress-io/code-coverage/issues/472?
Thanks a lot!
@twhoff Thank you for example, it works like a charm.
Thank you @twhoff I have wasted so much time and this worked perfectly - I should have checked the issues as soon as it didn't work!
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
Card.test.js
cypress.json
plugins/index.js
support/index.js
package.json
Basically I do this:
The out.json in
.nyc_output/out.json
just contains an empty object{}
I should also note that when I do
yarn start
and checkwindow.__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.