I'm trying to introduce React Testing Library into Create React App project, and I'm hitting a strange problem. For one of my tests, I need to use jest-dom, but I can't seem to import it successfully.
I've yarn add'ed it, and can't think of what step I missed.
expect.extend fails because its toHaveStyle is undefined.
Here's my test file, reduced down to the minimum:
import React from 'react';
import {render, screen} from '#testing-library/react';
import {toHaveStyle} from '#testing-library/jest-dom';
import '#testing-library/jest-dom/extend-expect';
//expect.extend({toHaveStyle});
it('is confusing me', () => {
// (Using `toBe(42) as an ersatz `console.log`)
expect([Object.keys(require('#testing-library/jest-dom')), Object.keys(require('#testing-library/react')), toHaveClass]).toBe(42);
});
The output is:
Expected: 42
Received: [[], ["render", "cleanup", "fireEvent", ...], undefined]
And, here's the relevant part of yarn.lock:
"#testing-library/jest-dom#^5.7.0":
version "5.7.0"
resolved "https://registry.yarnpkg.com/#testing-library/jest-dom/-/jest-dom-5.7.0.tgz#b2e2acb4c088a293d52ba2cd1674b526282a2f87"
integrity sha512-ZV0OtBXmTDEDxrIbqJXiOcXCZ6aIMpmDlmfHj0hGNsSuQ/nX0qPAs9HWmCzXvPfTrhufTiH2nJLvDJu/LgHzwQ==
dependencies:
"#babel/runtime" "^7.9.2"
"#types/testing-library__jest-dom" "^5.0.2"
chalk "^3.0.0"
css "^2.2.4"
css.escape "^1.5.1"
jest-diff "^25.1.0"
jest-matcher-utils "^25.1.0"
lodash "^4.17.15"
redent "^3.0.0"
"#testing-library/react#^10.0.4":
version "10.0.4"
resolved "https://registry.yarnpkg.com/#testing-library/react/-/react-10.0.4.tgz#8e0e299cd91acc626d81ed8489fdc13df864c31d"
integrity sha512-2e1B5debfuiIGbvUuiSXybskuh7ZTVJDDvG/IxlzLOY9Co/mKFj9hIklAe2nGZYcOUxFaiqWrRZ9vCVGzJfRlQ==
dependencies:
"#babel/runtime" "^7.9.6"
"#testing-library/dom" "^7.2.2"
"#types/testing-library__react" "^10.0.1"
Well, jest-dom documentation has been updated.
import {toHaveStyle} from '#testing-library/jest-dom';
would not work anymore. Instead,
import {toHaveStyle} from '#testing-library/jest-dom/matchers'
For reference, see jest-dom
Here is how I use this great library :
// in test file
import '#testing-library/jest-dom/extend-expect';
[...]
// then matchers are available in tests
expect(rtl.getByText('text').toHaveClass('some-class');
My import is slightly different than yours, I could not say precisely what goes wrong with yours but this is how I do.
Good luck !
module not found can't resolve node_modules\react-scripts\node_modules\babel-loader\lib\index.js' in react 17
Okay so if there is anyone looking at this in 2022+ year, After downgrading from react-v18 to react-v17 I faced this issue. I had to run certain commands.
npm install web-vitals#1.0.1
npm install babel-loader --save-dev
npm install -D babel-loader #babel/core #babel/preset-env webpack
I also moved my #testing-library/jest-dom,#testing-library/react,#testing-library/user-event to devDependencies and downgraded them
Worked like a charm.
Related
I'm in an extremely weird situation where the project structure looks like:
Project
MiniProject1
MiniProject2
node_modules
package.json
The mini projects themselves are react apps that get shown within a ruby container. So when a user goes to /route1 it loads the miniProject1 react page. when they go to /route2 it goes to the miniProject2 page.
I've been tasked to update the react version of MiniProject2 but not interfere with MiniProject1 or make any changes that could interfere with MiniProject1.
I went the route of installing react and react-dom as follows:
"react-latest": "npm:react#^16.13.1",
"react-dom-latest": "npm:react-dom#^16.13.1",
so I can then import the latest versions specifically in MiniProject2
The problem that I'm facing is the react-dom has the "React" a peer dependency and it's trying to pull the project react instead of my aliased "react-latest" which makes sense but now I'm stuck trying to figure out how I can force react-dom to require my react-latest alias instead of the default react peer dependency.
I'm also open to potential Webpack config solutions.
Any thoughts?
After some digging I was able to force react-dom to use react-latest by doing the following:
package.json
"react": "^16.3.2",
"react-dom": "16.3.3",
"react-dom-latest": "npm:react-dom#^16.13.1",
"react-latest": "npm:react#^16.13.1",
webpack.config.js
module: {
rules: [
{
test: /\/node_modules\/react-dom-latest\/.*.js/,
resolve: {
alias: {
react: path.resolve('./node_modules/react-latest')
}
}
}]},
Then on the top of the files I need to use the latest react version for, I import react like so:
import React from 'react-latest'
//or
import ReactDOM from 'react-dom-latest' //for your index
On the files I need to use the old react for, I import react like so:
import React from 'react'
//or
import ReactDOM from 'react-dom' //for your index
That's all that needed to be done!
Disclaimer: Don't do this unless you have to and have no choice like I did. It'll increase the size of your bundle since you are bringing in two different versions of react and reactDom
I create a react library using https://www.npmjs.com/package/create-react-library
And successfully used it on other React project.
But when I tried to use react hooks functionalities inside library it gives me following error.
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
.....
My Library
I just tried to use useState as follows in my component.
import React, { useState } from 'react'
const General = (props) => {
const [count, setCount] = useState(0);
return (
<div>
General component
</div>
)
}
export default General
I am using
"react": "^16.8.6" and "react-dom": "^16.8.6"
My React APP
Created a application using https://github.com/facebook/create-react-app and used above library as follows.
import Reactfrom 'react'
import { General } from 'my.lib'
const accountSummary = props => {
return (
<div>
<General>
</div>
)
}
export default accountSummary
Both has same react versions and library has used same react-dom and react versions as peerDependencies
I was including my component library (for that matter any library) in my application as #Janith did using my-comp-lib:"file:../.." (I don't want to publish every time I want to test) and I encountered the same issue.
Invalid hook call. Hooks can only be called inside of the body of a
function component. This could happen for one of the following
reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app See react-invalid-hook-call for tips about how to debug and
fix this problem
I was able to fix this by making my app and library point to the same react (package) location.
Below are the steps I followed :
1. In Your Application:
a) cd node_modules/react && npm link
b) cd node_modules/react-dom && npm link
2. In Your Library
a) npm link react
b) npm link react-dom
3)Stop your dev-server and do `npm start` again.
It works!!
Please refer below links for more details ..
https://github.com/facebook/react/issues/14721
https://github.com/facebook/react/pull/14690
https://github.com/facebook/react/issues/13991
Note : This issue will not happen if you publish your package to artifactory and install because you will have react & react-dom as peer-dependencies and they won't get included in the distribution. So your package and application use the same react which is installed in the application.
I just ran into the same issue. I was able to fix it by pointing to the same react in my example app as in my library:
App Structure
Root
Example
package.json
src (library)
package.json
So, from the example > package.json I changed react to be:
"react": "link:../node_modules/react",
This is much like the npm link listed above but it won't go away every time you npm install.
I had the same issue, working with a rush monorepo, configuring ui-package and building the apps using nextjs.
The solutions was add the follow code on package.json
"resolutions": {
"react": "17.0.1", // verificate your react version
"react-dom": "17.0.1"
}
In the library's package.json:
"peerDependencies": {
"react": "17.0.1",
"react-dom": "17.0.1"
},
See more here: https://github.com/vercel/next.js/issues/9022#issuecomment-728688452
Add to your Components Library's package.json
"peerDependencies": {
"react": "<your version>"
}
so that your lib package will use the same react package as your main app.
https://nodejs.org/es/blog/npm/peer-dependencies/
It worked for me when I changed the link from the app to the library to be "link:../" instead of "file:../", in addition to linking react and react-dom.
React 17 + React Testing Library + Umi(a frontend framework, built-in react-router)
In my case, when I run the unit test, I got an error message "invalid hook call".
After a period of trying, I found two ways to solve.
Downgrade to React 16.x, then all will be fine.
Keep using React 17.x, and
Still have to write import React from 'react'
Install react-router-dom separately
I think it may be a problem with react-router, but due to my limited understanding, I don't have a better solution yet.
Also check your npm version. My version was 7.0.8 which was outdated, after changing it to 6.14.8 everything was working fine!
WHEN TESTING WITH REAL APP IN REACT NATIVE
I have same issue and i delete my node_module file in my custom library and i fixed it..
issue when installing direct module
yarn add c:/user......./react-native-some-lib
In my case I'm building my own common library. Although I was exporting createContext, useContext and useState from "react", I simply forgot to also import the default export, React.
Changing my import statement from this:
import { createContext, useContext, useState } from "react";
to this:
import React, { createContext, useContext, useState } from "react";
fixed it for me. You might have to do this in every React component/context etc that you are exporting from your react library.
Edit:
In another one of my apps that relies on this common library, this issue was also fixed using npm link as described in the React documentation (Invalid Hook Call Warning):
This problem can also come up when you use npm link or an equivalent. In that case, your bundler might “see” two Reacts — one in application folder and one in your library folder. Assuming myapp and mylib are sibling folders, one possible fix is to run npm link ../myapp/node_modules/react from mylib. This should make the library use the application’s React copy.
So in my case, I navigated to my common library and ran npm link ../path-to-my-app/node_modules/react.
Edit (23/02/2022)
Hopefully the final edit - another solution is to simply globally install the problem dependency if all apps expect to use the same version, e.g. npm install react -g
I have created a React library with create-react-library this library is your General component. I have published it to npm here https://www.npmjs.com/package/stackoverflow-test and a React app for use it here https://codesandbox.io/s/mm7yl83o28.
Just click on General component text and count will be incremented.
I cannot reproduce your issue, just use this test to check your implementation.
Im sure this is something simple but for the life of me i can't seem to find an answer to my problem.
Basically Im using react and webpack and I've installed a new package (in this case braintree-web-drop-in), however the package is always appearing as null (undefined) when i import it into my react module and just try to log it out at the top of the module (or anywhere)
package.json:
"dependencies": {
"braintree-web": "^3.32.0",
"braintree-web-drop-in": "^1.10.0",
ReactModel.tsx
import brainTree from 'braintree-web-drop-in'
console.log(brainTree);
I can also see that the package seems to have been added to my generated js file through webpack.
Any help would be appreciated!
Thanks,
James
To me it looks like this module doesn't have a default export (which the import syntax will use if no named export is asked for).
https://github.com/braintree/braintree-web-drop-in/blob/master/src/index.js#L534
So, in order to see if the module is installed, try this:
import { VERSION } from 'braintree-web-drop-in';
console.log('brain tree version: ', VERSION);
If that works you can use the create with a named import:
import { create} from 'braintree-web-drop-in';
NOTE: I fixed this by moving all of the code inside my src/nod_modules folder into the src folder directly and deleting src/node_modules as per this short thread: https://github.com/facebook/create-react-app/issues/4241
I am using create-react-app and having trouble running Jest.
When I attempt to import any one of my React components into my test file, I get an error when I yarn test:
Test suite failed to run
.../src/node_modules/common/ErrorMessage.js:1
({"Object.<anonymous>":function(
module,exports,require,__dirname,__filename,global,jest)
{import React from 'react'
^^^^^^
SyntaxError: Unexpected token import
This is what my test file looks like:
// test.test.js
// attempting to import
import ErrorMessage from '../node_modules/common/ErrorMessage.js'
// dummy test
test('adds 1 + 2 to equal 3', () => {
expect(1 + 2).toBe(3)
})
However, the error does not get thrown if I'm at the root of the src file, importing my index.js. At that point, the error gets thrown in the first file that index.js imports. For example:
test.test.js
import index from './index'
index.js
import React from 'react'
import { render } from 'react-dom'
import './style/index.css'
import LoginContainer from './node_modules/user/LoginContainer'
import NewUser from './node_modules/user/NewUser'
// etc.
terminal output
FAIL src/test.test.js
● Test suite failed to run
/Users/hannahmccain/Desktop/DEV/expense-report/fullstack-expense-report/client/src/node_modules/user/LoginContainer.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import React, { Component } from 'react'
^^^^^^
SyntaxError: Unexpected token import
at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/ScriptTransformer.js:289:17)
at Object.<anonymous> (src/index.js:11:164)
at Object.<anonymous> (src/test.test.js:3:14)
It seems like, in the context of Jest, Babel isn't able to compile the files in src/node_modules properly. I'm just at a loss as to how to correct that! Any insights would be appreciated.
FYI, Jest is supposed to work out-of-the-box with create-react-app, and I don't want to eject. Without ejecting, I'm unable to make certain changes I've seen recommended elsewhere, such as updating the Jest settings in my package.json.
To follow up with #Himanshu Singh answer, by adding this in my package.json helped me resolved this error.
{
test: react-scripts test --transformIgnorePatterns \"node_modules/(?!ui-core)/\" --env=jsdom
}
The code inside node_modules/user/LoginContainer.js is not a production release (babelified version) as it still has those import statement.
Jest that comes pre-configured with create-react-app, excludes everything inside node_modules from babel-transformation before running tests assuming that the code inside node_modules would be pre-babelified.
And since your module inside node_modules isn't babelified, jest throws error as soon as it encounters import statement.
Solution
1. You must be having a build script for your node_module in use. Try placing the production release of your module inside node_modules.This will do the trick but will also create further issues (as per my experience).
2. Start configuring jest and its dependencies explicitly without ejecting. Essentially by changing your test script to jest --env=jsdom. You will need to install jest, react-dom, babel-transforms-* explicitly and then configure using jest configuration inside package.json.
Here you need to focus on two major configuration option - transformIgnorePatterns and transform.
In short, transform everything and ingnore everything that is already transformed.
Take a look at Jest configuration section for more details.
I'm setting up a new React with the help of: Create React App
However, I'm running into a linting issue. I'm receiving the following linting error 'PropTypes' is not defined. (no-undef).
Here is the code that is causing the issue:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
class Routers extends Component {
static propTypes = {
history: PropTypes.object.isRequired
};
...
I tried playing around with the react/prop-types rule, but to no avail.
Since react 15.5, PropTypes is included in a separate package, 'prop-types'.
So this line will help
import PropTypes from 'prop-types'
You can read more here
According to this issue comment.
It appears to be because you have installed eslint 4.x when you should just use the eslint version that is shipped with create-react-app. You should remove any eslint you have manually installed and use the one that comes with the repo.
I had the same problem on a project with eslint installed globally.
I solved this case by installing eslint manualy in the project:
npm i eslint --save
bye
jeff
Please Install prop-types
using this code:
npm install --save prop-types
If you're using <script> tags; you can add this tag:
<script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.7.2/prop-types.min.js" integrity="sha512-ssNhh7jlzc+K93ckIlSXFHHz6fSFv0l619WOv8xbFNRbFOujbasb42LVMOggDrQR1ScJncoWb+KAJx1uF3ipjw==" crossorigin="anonymous"></script>
You can get the minified/non-minified and other version here
Good Luck...
Please install the prop-types npm package - react 1.15 and greater on separate package is created.
Here to install package
You can place the PropTypes just after the class (outside the class):
Routers.propTypes = {
history: PropTypes.object.isRequired
}