0

(I couldn't think of a good title for this question, so feel free to edit it if you have a better idea)

My question

When I try to run tests for a specific component, I get this error:

Target container is not a DOM element.

I already found an answer to that in this SO question, but what I want to understand is:

  • Why does this happens in Typescript but not in Javascript?
  • Is this related to how Typescript imports modules?

My code

For this question purpose, I am removing unnecessary code.

index.tsx

import ReactDOM from 'react-dom'
import App from './app'

// This fooFunction needs to be declared here (project requirements)
export const fooFunction = (): string => 'foo'


ReactDOM.render(
  <App />,
  document.getElementById("root")
);

My component

import React from 'react'
import { fooFunction } from './index.js'

const MyComponent = () => {
  const result = fooFunction()
  return {
    <p>{result}</p>
  }
}

Now, when I write a test to my component, (I think) because my component is importing fooFunction from index.ts, index.ts is compiled and since "root" does not exist in my test world (jsdom), the line document.getElementById("root") fails and throws the error above.

However, I tried to reproduce the same thing in my Javascript project and it works fine. Any ideas why this is happening?

Update with additional files

Jest config (in package.json):

"moduleNameMapper": {
  "\\.(css|less|scss)$": "<rootDir>/__mocks__/styleMock.js",
  "\\.(jpg|jpeg|png|svg)$": "<rootDir>/__mocks__/fileMock.js",
  "^@App/(.*)$": "<rootDir>/src/$1",
  "^lib/(.*)$": "<rootDir>/common/$1",
  "^test/(.*)$": "<rootDir>/src/test/$1",
  "^utils/(.*)$": "<rootDir>/src/utils/$1"
},
"transform": {
  "^.+\\.(js|jsx|ts|tsx)?$": "babel-jest"
},

babel.config.js:

module.exports = function (api) {
  api.cache(true)

  const presets = [
    '@babel/preset-env',
    '@babel/preset-typescript',
    '@babel/react',
    [
      '@babel/preset-react',
      {
        'runtime': 'automatic'
      },
      'preset-react-setting'
    ]]
  const plugins = ['@babel/plugin-proposal-class-properties', '@babel/plugin-transform-runtime']

  return {
    presets,
    plugins
  }
}

tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": "src",
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": false,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "noImplicitAny": false,
    "jsx": "react-jsx",
    "sourceMap": true,
    "declaration": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "incremental": true,
    "noFallthroughCasesInSwitch": true,
    "downlevelIteration": true
  },
  "include": [
    "src/**/*",
    "scripts"
  ],
  "exclude": [
    "node_modules",
    "build",
    "**/*.spec.ts"
  ]
}
Bruno Monteiro
  • 4,153
  • 5
  • 29
  • 48
  • What does your test file, `tsconfig.json`, babel config and Jest config look like? Your `index.ts` files contains JSX, maybe it should be re-named to `index.tsx` as there may be transforms that apply to `.tsx` and not `.ts`. – chipit24 Jul 13 '21 at 03:59
  • 1
    Some things you can try for debugging: Comment out the `ReactDOM.render` call in `index.ts`. Add TS to your JS project (with a minimal and lax config) and see if you end up with the same error there. Run your test on your transpired code. It seems like the root cause of your error is still the same as described in the SO question you linked to. – chipit24 Jul 13 '21 at 04:02
  • Thanks for the comments @chipit24. My index file is a `.tsx`, was a typo in the question :) I updated the question to include the other files that you asked. – Bruno Monteiro Jul 13 '21 at 23:09
  • I will try the debug ideas that you suggested. – Bruno Monteiro Jul 13 '21 at 23:20

0 Answers0