Stencil: Can't run a spec if the component uses @capacitor/core

Created on 21 Nov 2018  ·  6Comments  ·  Source: ionic-team/stencil

Stencil version:

@stencil/[email protected]
@ionic/[email protected]
@capacitor/[email protected]

I'm submitting a:

[x] bug report
[ ] feature request
[ ] support request

Current behavior:

npx stencil test --spec my-spec
  ● 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:

    /<path-to-project>/node_modules/@capacitor/core/dist/esm/index.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export * from './core-plugin-definitions';
                                                                                             ^^^^^^

    SyntaxError: Unexpected token export

    > 1 | import { Plugins } from '@capacitor/core';
        | ^
      2 |
      3 | const { Storage } = Plugins;
      4 |

      at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
      at Object.<anonymous> (src/services/storage.ts:1:1)
      at Object.<anonymous> (src/services/request.ts:1:1)

Test Suites: 1 failed, 1 of 2 total
Tests:       0 total
Snapshots:   0 total
Time:        1.82s, estimated 12s

Expected behavior:

I want to be able to test an Ionic/Stencil app that uses Capacitor plugins.

Other information:

I followed the suggested links and found out that according to the Jest docs a setting should be set in order to transpile the package:

{ transformIgnorePatterns: ['node_modules/(?!(@capacitor/core)/)'] }

However that doesn't seem to do anything, same error.

One way to temporarily fix it was to open node_modules/@capacitor/core/package.json and change the "main" field from "dist/esm/index.js" to "dist/capacitor.js", which is a transpiled version. And I also had to add a null-check for Plugins cause it couldn't read property Storage of undefined. However that would break the build, so I have to manually do it only to run tests.

Looking at the Rollup docs, it seems that the "module" field should be used for the ESM version, rather than the "main" field:

{
  "main": "dist/capacitor.js",
  "module": "dist/esm/index.js",
}

But not sure if that raises any other issues. Feel free to move this into the Capacitor repo, however seems like a bug that transformIgnorePatterns doesn't work.

bug

All 6 comments

I have a similar problem.

Importing @capacitor/core works. Although the test fails with the following message:

 ● Test suite failed to run

    TypeError: Cannot read property 'App' of undefined

      22 | import { StorageSelectors } from "../store/storage.selectors";
      23 | 
    > 24 | const { App, Device, Browser } = Plugins;
         |         ^
      25 | 
      26 | @Injectable({
      27 |     providedIn: "root"

When debugging into the issue I discovered, that the capacitor.js doesn't actually export anything. Everything gets initialized but in the end it only gets assigned to the variable capacitorExports but not the usual module.exports.
When manually assigning that to module.exports everything works flawlessly.

I'm using Capacitor 1.0.0-beta.25 and JEST 24.8.0 with following config:

jest.config.js

const esModules = ["@ionic", "@ionic-native", "@capacitor", "lodash-es"].join("|");

const tsconfig = require("./tsconfig.json")
const moduleNameMapper = require("tsconfig-paths-jest")(tsconfig);

module.exports = {
  testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'],
  transform: {
    '^.+\\.(ts|html)$': 'ts-jest',
    '^.+\\.js$': 'babel-jest'
  },
  transformIgnorePatterns: [`node_modules/(?!${esModules})`],
  resolver: '@nrwl/builders/plugins/jest/resolver',
  moduleFileExtensions: ['ts', 'js', 'html'],
  collectCoverage: true,
  coverageReporters: ['html'],
  moduleNameMapper,
};

babel.config.js

module.exports = {
    presets: [
        [
            '@babel/preset-env',
            {
                targets: {
                    node: 'current',
                },
            },
        ],
    ],
    plugins: []
};

I found out two things:

  1. This is the wrong repository... This issue (if it actually is an issue) better belongs to https://github.com/ionic-team/capacitor
  2. This is a problem of the used IIFE module format

I agree that this is a capacitor issue.

BTW you can try adding a file __mocks__/@capacitor/core.ts with the following content:

export const Plugins = {};

to mock it out. Does that make it work for you?

It does indeed!
Once i found out where to put the __mocks__ folder, as NX redefines the rootDir, it worked!

For those finding this issue from google: create the __mocks__ folder in apps/<yourAppName>/. This means your __mocks__ folder is on the same level as the src folder of your app package.

+ my-project
|   +-- apps
|   |   +-- myApp
|   |   |   +-- __mocks__
|   |   |   |   +-- @capacitor
|   |   |   |   |   +-- core.ts
|   |   |   +-- src
|   +-- libs
|   +-- node_modules
...

Ok, good to know. I'll close this here and we can discuss how to smoothen out issues with Capacitor in tests in another issue over there... I think you were on the right track with the export not working for cjs.

I post this here as well since Google pointed me to this issue before the capacitor one. I found a solution without needing a __mocks__ folder or anything.

https://github.com/ionic-team/capacitor/issues/1542#issuecomment-502736804

Was this page helpful?
0 / 5 - 0 ratings