Testing library fails due to TypeError: IMask is not a function
Matt-Tranzact opened this issue · comments
Describe the bug
After migration to 7.0.0. tests fails due to some TypeError when running testing-library.
To Reproduce
import React from 'react'
import { render } from '@testing-library/react'
import CustomNumber from './CustomNumber'
const createWrapper = () => render(<CustomNumber />)
describe('Test Component', () => {
describe('Rendering', () => {
it('should match snapshot', () => {
const wrapper = createWrapper()
expect(wrapper).toMatchSnapshot()
})
})
})
import React from 'react'
import { IMaskInput } from 'react-imask'
const CustomNumber: React.FC = () => {
return <IMaskInput mask="(#00) 000-0000" />
}
export default CustomNumber
It throws following error in console:
Expected behavior
Unit Test should work as previous Imask version (6.6.3)
Environment:
- OS: Windows
- Testing Env
- IMask v7.0.0
- React with Testing library v14.0.0, typescript: 5.1.3, react: 18.2.0
Additional context
It seems the error is thrown when using mask property only, if I remove mask="(#00) 000-0000"
the unit test works fine.
brw, the component seems to render fine in browser:
The error is happening only in test mode
@Matt-Tranzact may be related to handling imports. Make sure that your build config for tests allows to use default imports such as
import IMask from 'imask'
and not just import { default as IMask } from 'imask'
I checked my tsconfig which is the same being used for browser config, is has "esModuleInterop": true,
an d "allowSyntheticDefaultImports": true,
already enabled but the error is still being reported. Btw, it is the same configuration I used for v6.6.3.
I also notice that ther error has some more logs which points to an specific lib section, could that be related?
I'm attaching the full log for references.
console.error
Error: Uncaught [TypeError: IMask is not a function]
at reportException (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jsdom\lib\jsdom\living\helpers\runtime-script-errors.js:66:24)
at innerInvokeEventListeners (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:353:9)
at invokeEventListeners (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:286:3)
at HTMLUnknownElementImpl._dispatch (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:233:9)
at HTMLUnknownElementImpl.dispatchEvent (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:104:17)
at HTMLUnknownElement.dispatchEvent (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jsdom\lib\jsdom\living\generated\EventTarget.js:241:34)
at Object.invokeGuardedCallbackDev (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:4213:16)
at invokeGuardedCallback (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:4277:31)
at reportUncaughtErrorInDEV (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:22838:5)
at captureCommitPhaseError (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:27126:5)
at commitLayoutMountEffects_complete (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:24690:9)
at commitLayoutEffects_begin (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:24674:7)
at commitLayoutEffects (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:24612:3)
at commitRootImpl (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:26823:5)
at commitRoot (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:26682:5)
at finishConcurrentRender (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:25981:9)
at performConcurrentWorkOnRoot (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:25809:7)
at flushActQueue (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react\cjs\react.development.js:2667:24)
at act (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react\cjs\react.development.js:2582:11)
at C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\@testing-library\react\dist\act-compat.js:46:25
at renderRoot (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\@testing-library\react\dist\pure.js:161:26)
at render (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\@testing-library\react\dist\pure.js:247:10)
at createWrapper (C:\Users\Proyect\Cuy.ApplicationComponents\src\components\Transfer\CustomNumber\CustomNumber.test.tsx:7:35)
at Object.createWrapper (C:\Users\Proyect\Cuy.ApplicationComponents\src\components\Transfer\CustomNumber\CustomNumber.test.tsx:12:23)
at Promise.then.completed (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\utils.js:293:28)
at new Promise (<anonymous>)
at callAsyncCircusFn (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\utils.js:226:10)
at _callCircusTest (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:297:40)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at _runTest (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:233:3)
at _runTestsForDescribeBlock (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:135:9)
at _runTestsForDescribeBlock (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:130:9)
at _runTestsForDescribeBlock (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:130:9)
at run (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:68:3)
at runAndTransformResultsToJestFormat (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\legacy-code-todo-rewrite\jestAdapterInit.js:122:21)
at jestAdapter (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\legacy-code-todo-rewrite\jestAdapter.js:79:19)
at runTestInternal (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-runner\build\runTest.js:367:16)
at runTest (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-runner\build\runTest.js:444:34) {
detail: TypeError: IMask is not a function
at MaskedComponent.IMask [as initMask] (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-imask\src\mixin.ts:212:22)
at MaskedComponent.initMask [as componentDidMount] (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-imask\src\mixin.ts:175:12)
at commitLayoutEffectOnFiber (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:23310:28)
at commitLayoutMountEffects_complete (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:24688:9)
at commitLayoutEffects_begin (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:24674:7)
at commitLayoutEffects (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:24612:3)
at commitRootImpl (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:26823:5)
at commitRoot (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:26682:5)
at finishConcurrentRender (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:25981:9)
at performConcurrentWorkOnRoot (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-dom\cjs\react-dom.development.js:25809:7)
at flushActQueue (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react\cjs\react.development.js:2667:24)
at act (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react\cjs\react.development.js:2582:11)
at C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\@testing-library\react\dist\act-compat.js:46:25
at renderRoot (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\@testing-library\react\dist\pure.js:161:26)
at render (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\@testing-library\react\dist\pure.js:247:10)
at createWrapper (C:\Users\Proyect\Cuy.ApplicationComponents\src\components\Transfer\CustomNumber\CustomNumber.test.tsx:7:35)
at Object.createWrapper (C:\Users\Proyect\Cuy.ApplicationComponents\src\components\Transfer\CustomNumber\CustomNumber.test.tsx:12:23)
at Promise.then.completed (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\utils.js:293:28)
at new Promise (<anonymous>)
at callAsyncCircusFn (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\utils.js:226:10)
at _callCircusTest (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:297:40)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at _runTest (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:233:3)
at _runTestsForDescribeBlock (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:135:9)
at _runTestsForDescribeBlock (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:130:9)
at _runTestsForDescribeBlock (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:130:9)
at run (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\run.js:68:3)
at runAndTransformResultsToJestFormat (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\legacy-code-todo-rewrite\jestAdapterInit.js:122:21)
at jestAdapter (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-circus\build\legacy-code-todo-rewrite\jestAdapter.js:79:19)
at runTestInternal (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-runner\build\runTest.js:367:16)
at runTest (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\jest-runner\build\runTest.js:444:34),
type: 'unhandled exception'
}
5 | import CustomNumber from './CustomNumber'
6 |
> 7 | const createWrapper = () => render(<CustomNumber />)
| ^
8 |
9 | describe('Transfer CustomNumber Component', () => {
10 | describe('Rendering', () => {
at VirtualConsole.<anonymous> (node_modules/jest-environment-jsdom/build/index.js:60:23)
at reportException (node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:70:28)
at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:353:9)
at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:286:3)
at HTMLUnknownElementImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:233:9)
at HTMLUnknownElementImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:104:17)
at HTMLUnknownElement.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:241:34)
at Object.invokeGuardedCallbackDev (node_modules/react-dom/cjs/react-dom.development.js:4213:16)
at invokeGuardedCallback (node_modules/react-dom/cjs/react-dom.development.js:4277:31)
at reportUncaughtErrorInDEV (node_modules/react-dom/cjs/react-dom.development.js:22838:5)
at captureCommitPhaseError (node_modules/react-dom/cjs/react-dom.development.js:27126:5)
at commitLayoutMountEffects_complete (node_modules/react-dom/cjs/react-dom.development.js:24690:9)
at commitLayoutEffects_begin (node_modules/react-dom/cjs/react-dom.development.js:24674:7)
at commitLayoutEffects (node_modules/react-dom/cjs/react-dom.development.js:24612:3)
at commitRootImpl (node_modules/react-dom/cjs/react-dom.development.js:26823:5)
at commitRoot (node_modules/react-dom/cjs/react-dom.development.js:26682:5)
at finishConcurrentRender (node_modules/react-dom/cjs/react-dom.development.js:25981:9)
at performConcurrentWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:25809:7)
at flushActQueue (node_modules/react/cjs/react.development.js:2667:24)
at act (node_modules/react/cjs/react.development.js:2582:11)
at node_modules/@testing-library/react/dist/act-compat.js:46:25
at renderRoot (node_modules/@testing-library/react/dist/pure.js:161:26)
at render (node_modules/@testing-library/react/dist/pure.js:247:10)
at createWrapper (src/components/Transfer/CustomNumber/CustomNumber.test.tsx:7:35)
at Object.createWrapper (src/components/Transfer/CustomNumber/CustomNumber.test.tsx:12:23)
console.error
The above error occurred in the <IMask(Component)> component:
at MaskedComponent (C:\Users\Proyect\Cuy.ApplicationComponents\node_modules\react-imask\src\mixin.ts:168:7)
at IMaskInputFn
at CustomNumber
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.
5 | import CustomNumber from './CustomNumber'
6 |
> 7 | const createWrapper = () => render(<CustomNumber />)
| ^
8 |
9 | describe('Transfer CustomNumber Component', () => {
10 | describe('Rendering', () => {
at logCapturedError (node_modules/react-dom/cjs/react-dom.development.js:18687:23)
at update.callback (node_modules/react-dom/cjs/react-dom.development.js:18720:5)
at callCallback (node_modules/react-dom/cjs/react-dom.development.js:13923:12)
at commitUpdateQueue (node_modules/react-dom/cjs/react-dom.development.js:13944:9)
at commitLayoutEffectOnFiber (node_modules/react-dom/cjs/react-dom.development.js:23391:13)
at commitLayoutMountEffects_complete (node_modules/react-dom/cjs/react-dom.development.js:24688:9)
at commitLayoutEffects_begin (node_modules/react-dom/cjs/react-dom.development.js:24674:7)
at commitLayoutEffects (node_modules/react-dom/cjs/react-dom.development.js:24612:3)
at commitRootImpl (node_modules/react-dom/cjs/react-dom.development.js:26823:5)
at commitRoot (node_modules/react-dom/cjs/react-dom.development.js:26682:5)
at performSyncWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:26117:3)
at flushSyncCallbacks (node_modules/react-dom/cjs/react-dom.development.js:12042:22)
at commitRootImpl (node_modules/react-dom/cjs/react-dom.development.js:26959:3)
at commitRoot (node_modules/react-dom/cjs/react-dom.development.js:26682:5)
at finishConcurrentRender (node_modules/react-dom/cjs/react-dom.development.js:25981:9)
at performConcurrentWorkOnRoot (node_modules/react-dom/cjs/react-dom.development.js:25809:7)
at flushActQueue (node_modules/react/cjs/react.development.js:2667:24)
at act (node_modules/react/cjs/react.development.js:2582:11)
at node_modules/@testing-library/react/dist/act-compat.js:46:25
at renderRoot (node_modules/@testing-library/react/dist/pure.js:161:26)
at render (node_modules/@testing-library/react/dist/pure.js:247:10)
at createWrapper (src/components/Transfer/CustomNumber/CustomNumber.test.tsx:7:35)
at Object.createWrapper (src/components/Transfer/CustomNumber/CustomNumber.test.tsx:12:23)
````
i tried
import { render } from '@testing-library/react'
const CustomNumber: React.FC = () => {
return <IMaskInput mask="(#00) 000-0000" defaultValue="123" />
}
const createWrapper = () => render(<CustomNumber />)
const {debug} = createWrapper();
debug();
it's working fine. seems like a problem somewhere in jest/ts config
I created a new project using vite sandbox with vitest instead of jest, the same error is being fired too:
here is the sandbox to test it: https://codesandbox.io/p/sandbox/rough-meadow-cwqcdm?file=%2Fsrc%2FReactImask.test.tsx%3A10%2C1
Today I just crossed with a similar error when building a private lib. I'm using rollup to build my library and one of the dependencies is emotion/style. I build cjs and ems.
When building with cjs emotion/styled is bundled as export default styled
Then in my consumer app (in commonjs) when I installed the lib, everything works fine in browser but when running tests with babel and jest, I also got the error styled is not a function
.
After some hours of digging, I found that for commonjs, my app babel config for jest doesn't understand how to read required('emotion/styled').default, it seems due to some issues realted to interop: https://rollupjs.org/configuration-options/#output-interop
What I did was to set interop to 'auto' mode in my lib.
Then the library was recognized successfully in my app for testing mode.
I guess something similar is happening when bundling react-imask in build mode.
Hope this info helps
@Matt-Tranzact thanks for your research and for providing link to the sandbox for reproduction. This helps me a lot.
It seems that jest
does not understand esm
format and uses cjs/umd instead, right?
Haven't tried running my app with lib in esm (It's too attach to some other libs still in cjs). My guess is that if an app is build with type: "module" (esm) the lib should work fine since esm is capable of recognizing interop automatically.
The problem is happening only for cjs mode since browser can detect .default autoamtically but jest can't detect it (i tried with babel and ts-jest with no luck) and interop config needs to be set in lib as a fallback.
This rollup plugin also helped me to understand the problem a little better: https://www.npmjs.com/package/rollup-plugin-es-module-interop?activeTab=readme