TypeError: Cannot read property 'twoArgumentPooler' of undefined - reactjs

Recently we have upgraded the react-native-web package to latest version 0.17.0 From that time we are getting the issue TypeError: Cannot read property 'twoArgumentPooler' of undefined while running yarn test
To analyse this issue, gone through the code which is implemented by our developers but we didn't have anything like twoArgumentPooler but it's available in react-native-web package in the path
at Object.<anonymous> (node_modules/react-native-web/dist/cjs/exports/Touchable/BoundingDimensions.js:19:46)
How to resolve this issue

Can you show your jest config file? I had a similar issue and it turned out that I was (manually) setting up the moduleNameMapper incorrectly. I had the following:
moduleNameMapper: {
'react-native': 'react-native-web',
},
which, upon running the tests, effectively invalidated an import on line 10 inside react-native-web/dist/exports/Touchable/BoundingDimensions.js (the file mentioned in your stacktrace) and surely a lot of other imports.
This
import PooledClass from '../../vendor/react-native/PooledClass';
var twoArgumentPooler = PooledClass.twoArgumentPooler;
turned into this (notice the changed and incorrect path)
import PooledClass from '../../vendor/react-native-web/PooledClass';
var twoArgumentPooler = PooledClass.twoArgumentPooler;
This ultimately resulted in the exact same error as you got, and was resolved by correctly defining the remapper entry like this:
moduleNameMapper: {
'^react-native$': 'react-native-web',
},
Hope it helps! If nothing else, perhaps this will help someone in the future!

Related

The current testing environment is not configured to support act(...) - #testing-library/react

I'm trying to upgrade my project to React 18, everything works in dev and production mode in the browser. But after upgrading to the latest version of #testing-library/react some of my unit tests are failing and a lot of them are logging the following warning:
console.error
Warning: The current testing environment is not configured to support act(...)
at printWarning (node_modules/.pnpm/react-dom#18.0.0_react#18.0.0/node_modules/react-dom/cjs/react-dom.development.js:86:30)
at error (node_modules/.pnpm/react-dom#18.0.0_react#18.0.0/node_modules/react-dom/cjs/react-dom.development.js:60:7)
at isConcurrentActEnvironment (node_modules/.pnpm/react-dom#18.0.0_react#18.0.0/node_modules/react-dom/cjs/react-dom.development.js:25057:7)
at warnIfUpdatesNotWrappedWithActDEV (node_modules/.pnpm/react-dom#18.0.0_react#18.0.0/node_modules/react-dom/cjs/react-dom.development.js:27351:12)
at scheduleUpdateOnFiber (node_modules/.pnpm/react-dom#18.0.0_react#18.0.0/node_modules/react-dom/cjs/react-dom.development.js:25292:5)
at setLoading (node_modules/.pnpm/react-dom#18.0.0_react#18.0.0/node_modules/react-dom/cjs/react-dom.development.js:17342:16)
at _callee2$ (node_modules/.pnpm/#cubejs-client+react#0.29.51_react#18.0.0/node_modules/#cubejs-client/react/src/hooks/cube-query.js:56:7)
First thing I did was check my versions, cleared node modules and lock file just in case:
react 18.0.0
react-dom 18.0.0
#testing-library/react version: "13.1.1",
Testing Framework and version: "jest": "27.5.1",
DOM Environment: jsdom 16.7.0
But everything looks right?
I checked the migration docs for React 18: https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html
Which says the latest version of #testing-library/react shouldn't require the globalThis.IS_REACT_ACT_ENVIRONMENT = true setting.
But I tried setting that manually anyway before my tests run. But that didn't fix it either, (I tried several versions)
// #ts-ignore
global.IS_REACT_ACT_ENVIRONMENT = true
// #ts-ignore
globalThis.IS_REACT_ACT_ENVIRONMENT = true
// #ts-ignore
self.IS_REACT_ACT_ENVIRONMENT = true
// #ts-ignore
window.IS_REACT_ACT_ENVIRONMENT = true
// #ts-ignore
this.IS_REACT_ACT_ENVIRONMENT = true
None of those fixes the Warning or the unit tests.
I'm using jest v. 27.x with jsdom which I imagine would be the most common configuration? So I'm quite surprised to be running into this error?
Here is my jest.config
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
moduleNameMapper: {
'^src/(.*)$': '<rootDir>/src/$1',
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
},
transform: {
'^.+\\.(t|j)sx?$': ['ts-jest'],
},
setupFilesAfterEnv: ['./src/setupTests.tsx'],
modulePathIgnorePatterns: ['src/common/config.ts'],
coverageReporters: ['text', 'json'],
}
Any ideas why a relatively simple setup like this, would be running into this warning with RTL v. 13.1.1?
In my case this warning was appearing because I had accidentally imported act from react-dom/test-utils instead of #testing-library/react. Fixing the import made the warning disappear.
In my case this happened because I had a useless act that I implemented as a workaround in v12.
await act(async () => {
const hours = await screen.findByText('-6h')
expect(hours).toBeInTheDocument()
})
I removed the useless act around my assertion in this test, and the warning about the "environment not configured to support act" was resolved.
In my case, this particular test was failing after upgrading to v13, which is how I ended up trying to clean it up.
The warning message was essentially not helpful in debugging this.
I didn't find the reason why the global flag was not working for me, so the following monkey patch resolved the log lines for me
const originalConsoleError = console.error;
console.error = (...args) => {
const firstArg = args[0];
if (
typeof args[0] === 'string' &&
(args[0].startsWith(
"Warning: It looks like you're using the wrong act()"
) ||
firstArg.startsWith(
'Warning: The current testing environment is not configured to support act'
) ||
firstArg.startsWith('Warning: You seem to have overlapping act() calls'))
) {
return;
}
originalConsoleError.apply(console, args);
};
Yes, it's super ugly and likely not the best solution to the problem, but then again React does something pretty similar in their codebase.
It can also happen if the tested code has a timeout that executes a callback after the test has finished. For instance with a throttle on a user input.
It can be avoided by either using the done callback provided by jest or to make the timers to finish instantly with the timer mocks.

ESLint: 'cy' is not defined (Cypress)

I've just started using Cypress with my React Typescript project. I've gotten some simple tests to run:
describe('settings page', () => {
beforeEach(() => {
cy.visit('http://localhost:3000')
});
it('starts in a waiting state, with no settings.', () => {
cy.contains('Waiting for settings...')
});
it('shows settings once settings are received', () => {
const state = cy.window().its('store').invoke('getState')
console.log(state) // different question: how do I get this to be the state and not a $Chainer?
});
});
It runs in Cypress just fine. But I get Typescript errors in Webstorm, saying that cy is not defined (a TS and ESlint error) and an error on describe saying all files must be modules when the --isolatedModules flag is provided.
I can make it a JS file instead of a TS file, then I still get cy is not defined.
I've tried import cy from 'cypress' but then I get ParseError: 'import' and 'export' may appear only with 'sourceType: module' which is a whole other can of worms (I'm taking baby steps in writing my tests and haven't had to import anything yet...)
/// <reference types="cypress" /> does not work.
Update (sort of)
I've followed instructions here and have made a little progress. To my already very full React webpack.config.dev.js I added the recommended code:
{ // TODO inserted for cypress https://stackoverflow.com/a/56693706/6826164
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
}
]
},
to the end of the list of rules (just before the file loader).
When I do this as well as setting up the plugins/index file as indicated in the article, the cypress "home screen" runs but when I click to open my tests, it takes very many seconds and then shows lots of errors, starting with
integration\settings.spec.ts
This occurred while Cypress was compiling and bundling your test code. This is usually caused by:
A missing file or dependency
A syntax error in the file or one of its dependencies
Fix the error in your code and re-run your tests.
./cypress/integration/settings.spec.ts
Module build failed (from ./node_modules/ts-loader/index.js):
Error: TypeScript emitted no output for C:\Users\...\...\front_end\cypress\integration\settings.spec.ts.
# multi ./cypress/integration/settings.spec.ts main[0]
Followed by, actually, a lot of Typescript output such as this:
C:\Users\jtuzman\dev\...\...\src\__tests__\Errors.test.tsx
[tsl] ERROR in C:\Users\jtuzman\dev\...\...\src\__tests__\Errors.test.tsx(37,41)
TS2339: Property 'toBeTruthy' does not exist on type 'Assertion'.
C:\Users\jtuzman\dev\...\...\src\__tests__\Errors.test.tsx
[tsl] ERROR in C:\Users\jtuzman\dev\...\...\src\__tests__\Errors.test.tsx(41,45)
TS2339: Property 'toBeDefined' does not exist on type 'Assertion'.
Notice that these are now errors for code outside the test files (although perhaps that makes sense). Many of them are for files in which I'm using Jest rather than Cypress, and many errors, as you can see, seem to be related to it inferring an Assertion type on expect that is not Jest, such that it thinks the toEqual matcher is wrong.
All the while, in Webstorm ESLint is still complaining about all my cy and TypeScript is underlining all those Jest assertions mentioned in the output.
This is all with a ts test file. If I rename the file to js, it says the file has no tests.
Any help? I love Cypress but I'm having a hell of a time getting it to work fully!
I got that error after upgrading to cypress version 4+. I installed the eslint-plugin-cypress
https://github.com/cypress-io/eslint-plugin-cypress
and activated it in the extends configuration either in package.json or in separate config file:
"eslintConfig": {
"extends": [
"plugin:cypress/recommended"
]
},
Add .eslintrc.json to cypress directory
In .eslintrc.json
{
"extends": [
"plugin:cypress/recommended"
]
}
I do not install eslint-plugin-cypress, and it fix the problem
Specify cy in eslintrc globals
Answered here
cy is a global variable. Much like location. So really it is window.cy. You can add it to the globals in Eslint. Don't import cy from cypress.
{
"globals": {
"cy": true
}
}
Added that to my .eslintrc and fixed the issue
The Cypress ESLint plugin will get rid of these warnings:
yarn add -D eslint-plugin-cypress (https://github.com/cypress-io/eslint-plugin-cypress)
add .eslintrc to the root of your project with the following:
{
"plugins": ["cypress"],
"extends": ["plugin:cypress/recommended"],
"rules": {
"jest/expect-expect": "off"
}
}
Try.. import cy from "cypress" this solved the problem for me.
at the top of your file put
/// <reference types="cypress" />
or download the official types
source: official cypress intellisense docs
I struggled a lot then this helped...
by adding same line in two files, eslintrc.json and eslintrc.js
(if u have other dependencies in extends, append them as well after it)
extends: ['plugin:cypress/recommended'],
Just add these lines to your tsconfig.json file for e2e tests:
"compilerOptions": {
"types": ["cypress"]
}
This adds support for cypress types.
/* global cy */
import above in your test file
example:
suppose you have login test ("cypress test file ex: cypress/integration/login.js")
I replaced the old style of type referencing,
/// <reference types="cypress" />
with this silly import
import type {} from 'cypress';
And the IDE now both recognizes Cypress's globals while also avoiding the "isolatedModules" issue it has with tsconfig.json
Seems I found a remedy that works (at least) for me. Adding this import to the top of the test:
import _Cypress from "cypress";
relaxes and comforts the ESLint plugin. Actually any name for the import can be used instead of "_Cypress": any that conforms your sense of beauty, does not conflict with anything and starts with underscore (to not provoke ESLint again). Of course, it looks like a kind of voodoo. I don't know why it works and probably there are better ways to present ESLint Cypress's globals, but I don't know them.
add this to jest.config.js
testPathIgnorePatterns: [
'/cypress',
],
Wrap your config object with defineConfig in the cypress.confi.ts file
like so
import { defineConfig } from "cypress";
export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
return config;
},
},
component: {
devServer: {
framework: "create-react-app",
bundler: "webpack",
},
},
});
For me adding .eslintignore in root directory and placing *.cy.js for all my test files was only workaround.
It seems that for the rest of us the working solution really is installing eslint-plugin-cypress and adding:
"eslintConfig": {
"extends": [
"plugin:cypress/recommended"
]
},
but idt didn't helped in my case because this plugin is no longer supported (almost for a year now) so it ended with critical error when combined with cypress-axe.

Property 'hot' does not exist on type 'NodeModule'.ts(2339)

I have a purchased react template with the following lines, but its not clear to me whats the purpose of this, the template its in JS and I want to change it to Typescript
The following lines were present in the template
if (module.hot) {
module.hot.accept('./dashApp.js', () => {
const NextApp = require('./dashApp').default;
ReactDOM.render(<NextApp />, document.getElementById('root'));
});
}
However when renamed to .TS, I get this error:
Property 'hot' does not exist on type 'NodeModule'.ts(2339)
What does this code really does? in plain english
This code is related to Webpack's hot module replacement feature (HMR). module.hot works like this:
module.hot.accept(
dependencies, // Either a string or an array of strings
callback // Function to fire when the dependencies are updated
);
So the code you included does this: *when the code of ./dashApp.js or one of the module it requires/imports in the requirement/import tree gets updated, re-render the whole React app.
The hot property on node modules it not standard, thus the TS error - make sure you install the required type definitions! npm install --save-dev #types/webpack-env should do the trick.
Related reads:
Hot Module Replacement concept: high-level Webpack doc on HMR
Hot Module Replacement API low-level Webpack doc on HMR, explaining how to use it and how does module.hot.accept does
Property 'hot' does not exist on type 'NodeModule': Github issue resolving the TS error
Just to add to the accepted answer: After installing #types/webpack-env you might have to add "types": ["webpack-env"] to your tsconfig.json in compilerOptions. Only then it finally worked for me.
So your tsconfig.json would look like this:
{
"compilerOptions": {
...
"types": ["webpack-env"]
},
...
}

Cannot assign to read only property '__esModule'

When compiling a React and Redux application with Webpack and Babel I get:
Uncaught TypeError: Cannot assign to read only property '__esModule' of #<Object>
In some older browsers (<= Chrome 1, Android 4, Safari 5).
This issue seems to stem from redux and react-redux outputting the line exports.__esModule = true; in the lib build but my application using Object.defineProperty instead (because they build loosely and I do not).
Two solutions are:
Building my application in loose mode also.
Importing react-redux/src and redux/src and building it with the same .babelrc as the application (everything is not loose).
As long as they are consistent and both:
Object.defineProperty(exports, "__esModule", {
value: true
});
and exports.__esModule = true; do not co-exist in my output, everything works.
My question is, what is the right solution? Why does this only affect older browsers? And why do they conflict?
Here is a similar question.
Object.defineProperty is broken on some Android 4 stock browser versions and probably other browsers that made use of a buggy implementation in Webkit.
Check this bug report
and and this other one reported to the chromium project.
The good news is you can apply this polyfill to fix the problem.
To make thing easy, you can simply copy and paste that polyfill on a <script> tag before your bundle.
This will fix your issues.
My guess is, you need to install babel-plugin-add-module-exports and in your .babelrc register this plugin:
"plugins": [
"babel-plugin-add-module-exports"
]
For more information visit this website.
In my case, I solved to add babel-register library in entry points.
In webpack.config.js (Webpack 1.x version of configuration)
// As is
entry: {
main: 'index.js'
},
// To be
entry: {
main: ['babel-register', 'index.js']
},
We met this problem on Android 4.0 and currently we cannot cut the support for Android 4.0.
For webpack 1.0, just set loose: true when you are using babel-preset-env.
However for Webpack 2, loose mode can't resolve this problem.
Finally, we found this trick, a little ugly.
// client_patch.js, For Android 4.0
var defineProperty = Object.defineProperty;
Object.defineProperty = function (exports, name) {
if (name === '__esModule') {
exports[name] = true;
return;
}
return defineProperty.apply(this, arguments);
};
And in your webpack config file.
// webpack.config.js
entry: {
main: [
path.resolve(__dirname, 'client_patch.js'),
'index.js'
]
}

`_Symbol.'for'`: Is that actually valid ES6? Webpack built it from React source

I'm trying to take React 0.14 for a spin before I upgrade it in my project. However, with a simple "hello world" prototype, Webpack is throwing an error:
ERROR in ./~/react/lib/ReactElement.js
Module parse failed: /home/dan/Demos/reactiflux/node_modules/babel-loader/index.js!/home/dan/Demos/reactiflux/node_modules/react/lib/ReactElement.js Line 25: Unexpected string
You may need an appropriate loader to handle this file type.
| // The Symbol used to tag the ReactElement type. If there is no native Symbol
| // nor polyfill, then a plain number is used for performance.
| var REACT_ELEMENT_TYPE = typeof _Symbol === 'function' && _Symbol.'for' && _Symbol.'for'('react.element') || 0xeac7;
|
| var RESERVED_PROPS = {
# ./~/react/lib/ReactMount.js 18:19-44
I do have babel-loader configured, and when I downgrade to React 0.13, everything works. What really stands out to me, is _Symbol.'for', in the middle of the error message.
In react/lib/ReactElement.js on line 21 (not 25), that line looks much more correct, with square brackets around the 'for' key:
var REACT_ELEMENT_TYPE = typeof Symbol === 'function' && Symbol['for'] && Symbol['for']('react.element') || 0xeac7;
I assume that the code shown in the error message is either in an intermediate state during compilation, or is the final compiled output. Does anyone know what could cause Webpack to produce something that looks so wrong? Has anyone successfully used Webpack, Babel and React ~0.14.1 together yet?
update
There is an issue for this: https://github.com/babel/babel/issues/2377
It's closed, but it looks like it came back for me. This was fixed in 5.8.25, but I have 5.8.29 and I still hit the bug.
It appears that the problem has something to do with me including babel runtime. My .babelrc was copied from an older project:
{
"optional": "runtime",
"stage": 0
}
In this little hello-world demo, there is nothing that requires bundling the runtime, so I just removed it, after noticing that https://github.com/DominicTobias/universal-react/, which also uses the same build tools, does not need it. That was the only change I needed to make to get this to build.
My webpack config is super simple:
var path = require("path");
module.exports = {
entry: "./index.js",
output: {
path: path.join(__dirname, "/dist"),
filename: "index.min.js"
},
module: {
loaders: [{
test: /\.js$/,
loader: "babel"
}]
}
};
I guess that's what I get for copying a config file from a more complex project into what was supposed to be a simplest possible demo.
I see that there is a babel-plugin-runtime as well as a babel-runtime on NPM, but when I tried out BPR for the sake of completeness, Babel complains: Module build failed: ReferenceError: The plugin "runtime" collides with another of the same name. Since I don't actually need the runtime, the linked GH repo is a 404, and since this really belongs in the issue trackers after all, this is as far as I am going to take this for now.
No, that is not valid code. That was an issue in Babel project, but it has been fixed in the 6.0 version which was released recently.
I was run into this issue too, and now I have checked this with latest version, and it is works fine. Here is my test steps:
# install Babel and plugins
npm install babel-cli babel-preset-es2015 babel-plugin-transform-runtime
# install React
npm install react
# run babel against problem react file
./node_modules/.bin/babel node_modules/react/lib/ReactElement.js --plugins transform-runtime --presets es2015
It is provides valid output, so the issue seems to be resolved.
And there is good news for you, babel-loader for webpack already supports 6 version of Babel. Check out its docs for details

Resources