Get code coverage from Cypress with babel, nyc and istanbul plugin? - reactjs

For a React/Redux project I use Cypress to test the UI. I need to get code coverage from thoses tests to have the details in Sonar (but that's another story).
So I began reading the docs from Cypress: https://docs.cypress.io/guides/tooling/code-coverage.html
I followed the instructions and found the differents plugins but nothing work. After running Cypress tests I have no coverage results and when I try to run the server with instrumented code on transpilation and try to get window.__coverage__ it's undefined.
So here is my configuration.
My devDep and NYC conf in package.json:
"devDependencies": {
"#cypress/code-coverage": "^1.8.0",
"babel-cli": "^6.26.0",
"babel-plugin-istanbul": "^5.2.0",
"babel-plugin-react-intl": "^2.4.0",
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-preset-react-app": "^3.1.2",
"cross-env": "^5.2.0",
"cypress": "3.1.0",
"istanbul-lib-coverage": "^2.0.5",
"jest-junit-reporter": "^1.1.0",
"junit": "^1.4.9",
"nyc": "^14.1.1",
"react-test-renderer": "^16.3.0"
[...]
},
"scripts": {
"start": "react-scripts start",
[...]
"test:unit:local": "react-scripts test --env=jsdom .*_test.js",
"test:unit": "npm run test:unit:local -- --ci --coverage --testResultsProcessor ./node_modules/jest-junit-reporter",
"test:integ:local": "cypress run --reporter junit",
"test:integ": "start-server-and-test start http://localhost:3000 test:integ:local",
"test": "cross-env NODE_ENV=test && npm run test:unit && npm run test:integ"
},
"nyc": {
"sourceMap": false,
"instrument": false
}
My .babelrc file:
{
"presets": ["#babel/preset-react"],
"plugins": [
[ "react-intl", {
"messagesDir": "./src/messages",
"extractSourceLocation": true
}],
"transform-class-properties",
"istanbul"
],
"env": {
"test": {
"plugins": [ "transform-class-properties", "istanbul" ]
}
}
}
My \cypress\support\index.js contains this line :
import '#cypress/code-coverage/support'
And here is my \cypress\plugins\index.js:
module.exports = (on, config) => {
on('task', require('#cypress/code-coverage/task'))
on('file:preprocessor', require('#cypress/code-coverage/use-babelrc'))
return config
}
So I expect to have a result like you can see on the Cypress docs.
The website is generated but the files containing coverage reports are empty.
And I don't understand what's wrong in my configuration.

Try the following line:
"start": "react-scripts -r #cypress/instrument-cra start",

I faced this issue too. Wasn't able to get code coverage. Downgrading nyc version from 14.x.x to 13.x.x fixed the problem, as mentioned here.

Related

Nextjs Cypress Only found unit test code coverage

I am trying to add code coverage to cypress following this tutorial
I added #cypress/code-coverage and babel-plugin-istanbul to my package.json file below
{
"name": "quiz",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"cypress": "cypress open"
},
"dependencies": {
"next": "12.0.10",
"react": "17.0.2",
"react-dom": "17.0.2",
"sass": "^1.49.7"
},
"devDependencies": {
"#cypress/code-coverage": "^3.9.12",
"#types/node": "17.0.15",
"#types/react": "17.0.39",
"babel-plugin-istanbul": "^6.1.1",
"cypress": "^9.4.1",
"eslint": "8.8.0",
"eslint-config-next": "12.0.10",
"typescript": "4.5.5"
}
}
I configured my cypress/support/index.js
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')
import '#cypress/code-coverage/support'
I configured my cypress/plugins/index.js
/**
* #type {Cypress.PluginConfig}
*/
// eslint-disable-next-line no-unused-vars
module.exports = (on, config) => {
require('#cypress/code-coverage/task')(on, config)
on('file:preprocessor', require('#cypress/code-coverage/use-babelrc'))
return config
}
My .babelrc
{
"presets": [
"next/babel"
],
"plugins": [
"istanbul"
]
}
After I run my test I get the following message
Only found unit test code coverage. [#cypress/code-coverage]
After I run my quiz.spec.js test, I run
npx nyc report --reporter=text-summary
And get an empty coverage summary
What am I doing wrong?
My github
I think it was just a node_modules problem, as your repo worked after download and initialization. I think babel can fail silently if it's dependencies are out of order.
I removed package.lock (because I use yarn to manage things) and then yarn to init the dependecies.

setting up lint-staged for jest

I have to try to set up a husky with lint-staged. Initially, I was trying to set up like the following but that does not work.
"lint-staged": {
"*.js": [
"prettier --write",
"eslint src/ --fix",
"npm run test",
"git add"
]
}
then I after some searching I changed my setting to the following but thats again reported diff error
"lint-staged": {
"*.js": [
"prettier --write",
"eslint src/ --fix",
"jest --bail --findRelatedTests",
"git add"
]
}
Error description
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation to specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
when I run npm run test in terminal it works fine. So why it is not working with `lint-staged. Am I doing something wrong here?
my package.json
{
"name": "myproject",
"version": "0.1.0",
"private": true,
"dependencies": {
"axios": "^0.18.0",
"react": "^16.8.4",
"react-dom": "^16.8.4",
"react-redux": "^6.0.1",
"react-router-dom": "^5.0.0",
"react-scripts": "2.1.8",
"redux": "^4.0.1",
"redux-thunk": "^2.3.0",
"standard-http-error": "^2.0.1",
"styled-components": "^4.1.3"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"devDependencies": {
"eslint-config-airbnb": "^17.1.0",
"eslint-config-prettier": "^4.1.0",
"eslint-plugin-import": "^2.16.0",
"eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-plugin-prettier": "^3.0.1",
"eslint-plugin-react": "^7.12.4",
"husky": "^1.3.1",
"install": "^0.12.2",
"lint-staged": "^8.1.5",
"prettier": "1.16.4"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"*.js": [
"prettier --write",
"eslint src/ --fix",
"jest --bail --findRelatedTests",
"git add"
]
}
}
Your lint-staged glob pattern is only set to run on *.js files on root. You have to change it to **/*.js to include ALL *.js files in your project.
"lint-staged": {
"**/*.js": [
"prettier --write",
"eslint src/ --fix",
"jest --bail --findRelatedTests",
"git add"
]
}
Using a Create React App means that you have to test using the react-scripts because they have the babel configuration that jest alone is missing.
There is a work around to set husky lint-staged using react-scripts test and avoid ejecting and configuring your own babel and jest.
Use the package cross-env that will allow us to configure a CI environment variable in whatever environment we’re currently in.
Install using:
yarn add --dev cross-env
or
npm install cross-env --save-dev
Then on your package.json you should have something like this:
{
"scripts" {
...,
"lint": "eslint src --fix"
"test": "cross-env CI=true react-scripts test --env=jsdom",
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"**/*.js": [
"yarn lint",
"yarn test"
]
},
}
If you are using npm you can change yarn test for npm run test, same for lint.
Hope it helps ;).
Main source of this answer: here

How to use jaeger-client from react component?

From react application (App.js ) imported jaeger-client.
import jaegerClient from 'jaeger-client'
Got exception 'TypeError: _fs2.default.readFileSync is not a function' from following line of /node_modules/jaeger-client/dist/src/thrift.js:168
source: _fs2.default.readFileSync(_path2.default.join(__dirname, './jaeger-idl/thrift/jaeger.thrift'), 'ascii')
Trying to solve it. Thanks for any help.
Complete package.json is like below
{
"name": "calculator",
"version": "0.1.0",
"private": true,
"homepage": "http://ahfarmer.github.io/calculator",
"devDependencies": {
"gh-pages": "^1.1.0",
"react-scripts": "^1.0.17"
},
"dependencies": {
"ajv": "^6.4.0",
"ajv-keywords": "^3.1.0",
"big.js": "^5.0.3",
"bufferutil": "^3.0.3",
"fs": "0.0.1-security",
"github-fork-ribbon-css": "^0.2.1",
"hexer": "^1.5.0",
"jaeger-client": "^3.10.0",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-tracing": "^0.1.5",
"thrift": "^0.11.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject",
"deploy": "gh-pages -d build"
},
"eslintConfig": {
"extends": "./node_modules/react-scripts/config/eslint.js"
}
}
Forked from https://github.com/ahfarmer/calculator and I am trying to trace every user action ( button press ). To test tracing from react.js application.
node-jaeger-client currently doesn't run in the browser. There is ongoing work to make jaeger-client browser friendly. This issue: readFileSync is not a function contains relevant information to why you're seeing the error message. Essentially, you're trying to run jaeger-client (a nodejs library) using react-scripts which doesn't contain the modules that jaeger-client needs.
Not jaeger, able to send traces to zipkin server, using zipkin-simple.
Related code is in repository https://github.com/debmalya/calculator
import zipkinSimple from 'zipkin-simple'
const zipkinTracerSimple = new zipkinSimple({
debug: true,
host: "localhost",
port: "9411",
path: "/api/v2/spans",
sampling: 1.0,
})
var zipkinSimpleTraceData
zipkinSimpleTraceData= zipkinTracerSimple.getChild(zipkinSimpleTraceData);
zipkinSimpleTraceData =
zipkinTracerSimple.sendClientSend(zipkinSimpleTraceData, {
service: '<service_name>',
name: "<span_name>"
})

How to find .babelrc?

I want to create React app with Ant Design
In the docs, it says I need to change .babelrc to modularly load the files, also from https://medium.com/#GeoffMiller/how-to-customize-ant-design-with-react-webpack-the-missing-guide-c6430f2db10f..
But, I can't find any.. I'm very new to Webpack/Babel/other things...
I used create-react-app to make React app
Please help..
This is my package.json:
{
"name": "ant",
"version": "0.1.0",
"private": true,
"dependencies": {
"antd": "^3.0.3",
"jquery": "^3.2.1",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-scripts": "1.0.17"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"devDependencies": {
"babel-plugin-import": "^1.6.3",
"css-loader": "^0.28.7",
"less": "^2.7.3",
"less-loader": "^4.0.5",
"less-vars-to-js": "^1.2.1",
"style-loader": "^0.19.1"
}
}
for anyone that ends up here in the future, some clarification: when you create your project with CRA, the babel configuration exists as part of the react-scripts setup (react-scripts is the package responsible for all the tooling magic of CRA). this means all babel related controls are nested somewhere inside of your project's node_modules directory. for all intents and purposes, they are not editable, and ejecting is required.
If you have created React app using create-react-app, first you need to eject from the app so that you can use custom configuration. Check this official doc about custom setup : link
Note: this is a one-way operation. Once you eject, you can’t go back!
Once you run "npm run eject" when you are in a react app, you can then use custom babel presets. After ejecting from project, go to package.json and you will find babel presets.
There are two ways to edit your Babel configuration in your react app
1) Edit directly using package.json :
{
"babel": { // nest config under "babel"
"presets": [
"es2015",
],
"plugins": ["transform-class-properties"]
}
}
2) Create new .babelrc file and edit the configuration :
//.babelrc
{
"presets": [
"es2015",
],
"plugins": ["transform-class-properties"]
}

React Jest causing "SyntaxError: Unexpected token ."

I am now using React Jest to test code. If a component is single, and not importing anything else, "npm test" runs smoothly. Now I want to test multiple components together, and I immediately get this error:
SyntaxError: Unexpected token .
It seemed whenever React is importing something else, such as this one:
require( './style/fixed-data-table.css' );
require( './style/jnpr-datatable.scss' );
and then using Jest, it is throwing the unexpected token "." error.
There must be something wrong in my settings, but where? My package.json file contains:
"jest": {
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react/",
"<rootDir>/node_modules/react-dom/",
"<rootDir>/node_modules/react-addons-test-utils/"
]
}
And the .babelrc file is already in the root. Also babel-jest is included.
Have a look at the Jest documentation for Webpack integration. The problem is that Jest can’t work with other stuff than JavaScript. So you have to mock all non-JavaScript files you import. The easiest way is to configure a moduleNameMapper in your Jest configuration.
{
"jest": {
"moduleNameMapper": {
"\\.(css|scss)$": "<rootDir>/__mocks__/styleMock.js"
}
}
}
With a __mocks__/styleMock.js, that looks like this.
module.exports = {};
The easiest is to add an identity-obj-proxy package:
yarn add --dev identity-obj-proxy
And use it to automatically mock CSS/SCSS modules.
Add this to the package.json:
"jest": {
"moduleNameMapper": {
"\\.(css|scss)$": "identity-obj-proxy"
}
}
Or the following to jest.config.ts:
moduleNameMapper: {
'\\.(css|scss)$': 'identity-obj-proxy'
}
This way (S)CSS module class names will be automatically retrieved in tests.
Here is the source.
npm i -D identity-obj-proxy
Add the below to file jest.config.js
moduleNameMapper: {
"\\.(css|less|scss|sass)$": "identity-obj-proxy"
}
File jest.config.js:
testEnvironment: 'jsdom',
The way I got away with this was by adding these two lines to my .babelrc file:
{
"presets": ["env", "react"],
"plugins": ["transform-class-properties"]
}
And my package.json file looks like this:
{
"name": "crud-redux",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.4.0",
"react-dom": "^16.4.0",
"react-scripts": "1.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "NODE_ENV=test jest",
"eject": "react-scripts eject"
},
"devDependencies": {
"babel-jest": "^18.0.0",
"babel-loader": "^6.4.1",
"babel-plugin-transform-decorators-legacy": "^1.3.5",
"enzyme": "^2.9.1",
"jest": "^23.1.0",
"react-addons-test-utils": "^15.6.2",
"react-test-renderer": "^15.6.2",
"redux-mock-store": "^1.5.1",
"webpack": "^1.15.0",
"webpack-dev-server": "^1.16.5"
}
}

Resources