Ionic-framework: Jest testing fails using Ionic React Beta with create-react-app

Created on 22 Feb 2019  ·  15Comments  ·  Source: ionic-team/ionic-framework

Bug Report

I get an error with Jest testing if I create a new React application using _create-react-app_ and add Ionic imports according to the announcement here:

https://blog.ionicframework.com/announcing-the-ionic-react-beta/?utm_campaign=React%2BNewsletter&utm_medium=email&utm_source=React_Newsletter_150

Ionic version:
@ionic/[email protected]
@ionic/[email protected]

Current behavior:
The application runs fine but when I run through the instructions to create an Ionic project using _create-react-app_, I end up with Jest tests that fail with a 'SyntaxError: Unexpected token export' around one of the @ionic/react imports.

Expected behavior:
Testing with Jest is an important part of any React project and it would be useful if either this just worked, or there was a documented method to work around this problem, particularly with _create-react-app_ which obviously has limitations on the configuration.

Steps to reproduce:
Please refer to the blog post documented above.

Other information:
I happen to be using a Mac and Yarn, but the error is a typical JS module type of problem so I doubt this is relevant.

react

Most helpful comment

We identified the root cause in @ionic/core and ionicons and will be making releases to fix those packages.

All 15 comments

I am using jest testing on the project itself with a series of mocks to get around this issue for now. You will need to create a mock folder at the base of your project. Please reference the contents of this directory: https://github.com/ionic-team/ionic/tree/master/react/__mocks__ and please let me know if this works for you.

We identified the root cause in @ionic/core and ionicons and will be making releases to fix those packages.

I realise that Ionic React is still in beta, so thank you for looking into this Josh. I wasn't able to make the __mocks__ solution work for me, but I did find that I was able to get the tests running by making this adjustment to the _package.json_ scripts entries, generated by create-react-app:

"scripts": {
   "start": "react-scripts start",
   "build": "react-scripts build",
   "test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!(@ionic))/\"",
   "eject": "react-scripts eject"
}

I'll look forward to a more solid solution appearing in the ionic codebase.

As a followup this is also an issue for ionic/vue

I was able to bypass the Unexpected token: export error by setting transformIgnorePatterns to a RegExp that excludes ionic & ionicons, so Jest start to transpile them:

npm test -- src/app --transformIgnorePatterns 'node_modules/(?!(@ionic|ionicons))'

But then I encountered this error:

  TypeError: (0 , _ionicons.addIcons) is not a function

And it looks very similar to what I get when I try to use @ionic/react in Storybook. There is a detailed ticket about Storybook, maybe it can help: https://github.com/ionic-team/ionicons/issues/670.

Needs Vue tag and an update to the title as it's not React specific

@anatoliyarkhipov
You'll have to mock the addIcons part. I was only able to finally run my tests after using this repo as reference (by @michaeltintiuc )
You'll see that it has a __mock__ folder to mock some parts of ionic.

After that, you MAY run into issues while trying to use some other ionic features. For example, right now I'm having trouble with toastController getting a null reference of document. I guess that's because it opens async, and well, you cant' mock $ionic, since it's installed at the same moment that you add the ionic components. I'll have a look into it later.

P.S.: We COULD have a way to add only ionic/vue components, without creating the $ionic inside the Vue instance... Would be easier to mock it tests.

I wasn't able to get this working with __mocks__, only with @anatoliyarkhipov 's suggestion of using
npm test -- src/app --transformIgnorePatterns 'node_modules/(?!(@ionic|ionicons))'

Would be nice to get this working out of the box, so looking forward to a proper fix 😄

Problem running jest on Ionic React project written in Typescript.

Error:

➜  ionic-react-test git:(master) ✗ npx jest
 FAIL  src/App.test.tsx
  ● Test suite failed to run

    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 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.

    You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    /mnt/c/Users/[redacted]/Projects/ionic-react-test/node_modules/@ionic/react/dist/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export * from './components';
                                                                                             ^^^^^^

    SyntaxError: Unexpected token export

      1 | import React from 'react';
      2 | import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
    > 3 | import { IonApp, IonPage } from '@ionic/react';
        | ^
      4 | import '@ionic/core/css/core.css';
      5 | import '@ionic/core/css/ionic.bundle.css';
      6 | import './App.css';

      at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:471:17)
      at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:513:25)
      at Object.<anonymous> (src/App.tsx:3:1)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        2.774s
Ran all test suites.

package.json:

{
  "name": "my-react-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@capacitor/android": "^1.0.0",
    "@capacitor/cli": "1.0.0-beta.24",
    "@capacitor/core": "^1.0.0",
    "@ionic/core": "^4.4.2",
    "@ionic/pwa-elements": "^1.3.0",
    "@ionic/react": "0.0.5",
    "@stencil/core": "^0.18.1",
    "@types/nanoid": "^2.0.0",
    "@types/node": "12.0.2",
    "@types/react": "16.8.17",
    "@types/react-dom": "16.8.4",
    "@types/react-redux": "^7.0.9",
    "@types/react-router-dom": "^4.3.3",
    "nanoid": "^2.0.3",
    "react": "^16.8.6",
    "react-dom": "^16.8.6",
    "react-redux": "^7.0.3",
    "react-router-dom": "^5.0.0",
    "react-scripts": "3.0.1",
    "redux": "^4.0.1",
    "redux-thunk": "^2.3.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "jest",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "@types/jest": "^24.0.13",
    "@types/react-test-renderer": "^16.8.1",
    "jest": "^24.8.0",
    "react-test-renderer": "^16.8.6",
    "ts-jest": "^24.0.2",
    "typescript": "^3.4.5"
  },
  "jest": {
    "preset": "ts-jest",
    "testEnvironment": "node",
    "transformIgnorePatterns": [
      "/node_modules/"
    ],
    "transform": {
      "^.+\\.tsx?$": "ts-jest"
    }
  }
}

tsconfig.json:

{
  "compilerOptions": {
    "target": "es6",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react",
    "noErrorTruncation": true
  },
  "include": [
    "src"
  ]
}

I'm trying to integrate @ionic/react in our own framework and the build still fails with this message. It seems there were no changes to ionicons regarding the build process since February @jthoms1?

Using --transformIgnorePatterns 'node_modules/(?!(@ionic|ionicons))' works to solve the first issue, but now i'm getting

Details:

    /node_modules/@ionic/react/node_modules/ionicons/dist/ionicons/svg/ios-add-circle-outline.svg:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M346.5 240H272v-74.5c0-8.8-7.2-16-16-16s-16 7.2-16 16V240h-74.5c-8.8 0-16 6-16 16s7.5 16 16 16H240v74.5c0 9.5 7 16 16 16s16-7.2 16-16V272h74.5c8.8 0 16-7.2 16-16s-7.2-16-16-16z"/><path d="M256 76c48.1 0 93.3 18.7 127.3 52.7S436 207.9 436 256s-18.7 93.3-52.7 127.3S304.1 436 256 436c-48.1 0-93.3-18.7-127.3-52.7S76 304.1 76 256s18.7-93.3 52.7-127.3S207.9 76 256 76m0-28C141.1 48 48 141.1 48 256s93.1 208 208 208 208-93.1 208-208S370.9 48 256 48z"/></svg>
                                                                                             ^
SyntaxError: Unexpected token <

FYI: The link that Josh provided above is not quite right due to MD messing with it. The correct link is:

https://github.com/ionic-team/ionic/tree/master/react/__mocks__

I've added an issue and PR for the failing tests on the latest release of Ionic React and starter projects:

https://github.com/ionic-team/starters/issues/821

Tests should now pass in apps created with the CLI in Ionic React RC0+. Going to close this, but if you still see the issue let us know.

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Ionic, please create a new issue and ensure the template is fully filled out.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mhartington picture mhartington  ·  75Comments

rvanbaalen picture rvanbaalen  ·  72Comments

Sturgelose picture Sturgelose  ·  83Comments

Z3roCoder picture Z3roCoder  ·  67Comments

vonovak picture vonovak  ·  66Comments