Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v2] Jest + react-testing-library #6551

Closed
LekoArts opened this issue Jul 18, 2018 · 10 comments
Closed

[v2] Jest + react-testing-library #6551

LekoArts opened this issue Jul 18, 2018 · 10 comments
Labels
help wanted Issue with a clear description that the community can help with. type: question or discussion Issue discussing or asking a question about Gatsby

Comments

@LekoArts
Copy link
Contributor

Description

I want to run tests with Jest and react-testing-library in my Gatsby v2 project. The unit tests on my utitilities (which use module.exports, require) with Jest work without problems.

But when I want to use react-testing-library and use import I get the error:

Details:

    E:\Lennart\Documents\GitLab\xxx\node_modules\gatsby\cache-dir\gatsby-browser-entry.js:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import React from "react"
                                                                                             ^^^^^^

    SyntaxError: Unexpected token import

      1 | import React from 'react';
    > 2 | import { graphql } from 'gatsby';
        | ^
      3 | import PropTypes from 'prop-types';
      4 | import styled from 'react-emotion';
      5 | import format from 'date-fns/format';

      at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
      at Object.<anonymous> (src/components/DocFooter.jsx:2:1)
      at Object.<anonymous> (src/components/__tests__/DocFooter.js:3:1)

My files

jest.config.js

module.exports = {
  moduleNameMapper: {
    '\\.(jpg|jpeg|png|gif|mp3|mp4|svg|woff|woff2)$': '<rootDir>/test/__mocks__/fileMock.js',
  },
  testPathIgnorePatterns: ['/node_modules/', '<rootDir>/.cache/', '<rootDir>/src/_examples/'],
  globals: {
    __PATH_PREFIX__: '',
  },
  transform: {
    '^.+\\.js$': '<rootDir>/test/jest-preprocess.js',
    '^.+\\.jsx$': '<rootDir>/test/jest-preprocess.js',
  },
};

jest-preprocess.js

const babelOptions = {
  presets: ['@babel/preset-react', '@babel/preset-env'],
  plugins: ['syntax-class-properties', 'transform-class-properties'],
};

module.exports = require('babel-jest').createTransformer(babelOptions);

package.json

{
  "dependencies": {
    "cross-spawn": "^6.0.5",
    "date-fns": "^1.29.0",
    "emotion": "^9.2.6",
    "emotion-server": "^9.2.6",
    "emotion-theming": "^9.2.6",
    "gatsby": "^2.0.0-beta.42",
    "gatsby-image": "^2.0.0-beta.6",
    "gatsby-plugin-catch-links": "^2.0.2-beta.3",
    "gatsby-plugin-emotion": "^2.0.0-beta.2",
    "gatsby-plugin-lodash": "^3.0.1-beta.2",
    "gatsby-plugin-manifest": "^2.0.2-beta.2",
    "gatsby-plugin-netlify": "^2.0.0-beta.3",
    "gatsby-plugin-netlify-cache": "^0.1.0",
    "gatsby-plugin-offline": "^2.0.0-beta.3",
    "gatsby-plugin-react-helmet": "^3.0.0-beta.3",
    "gatsby-plugin-sharp": "^2.0.0-beta.5",
    "gatsby-plugin-sitemap": "^2.0.0-beta.2",
    "gatsby-plugin-typography": "^2.2.0-beta.2",
    "gatsby-remark-autolink-headers": "^2.0.0-beta.3",
    "gatsby-remark-design-system": "^1.0.16",
    "gatsby-remark-external-links": "^0.0.4",
    "gatsby-remark-prismjs": "^3.0.0-beta.3",
    "gatsby-remark-responsive-iframe": "^2.0.0-beta.2",
    "gatsby-source-filesystem": "^2.0.1-beta.5",
    "gatsby-transformer-remark": "^2.1.1-beta.3",
    "gatsby-transformer-sharp": "^2.1.1-beta.4",
    "polished": "^1.9.2",
    "prismjs": "^1.14.0",
    "prop-types": "^15.6.1",
    "react": "^16.4.1",
    "react-dom": "^16.4.1",
    "react-emotion": "^9.2.3",
    "react-helmet": "^5.2.0",
    "react-media": "^1.8.0",
    "react-transition-group": "^2.3.1",
    "react-typography": "^0.16.13",
    "typeface-lora": "^0.0.54",
    "typeface-source-sans-pro": "^0.0.54",
    "typography": "^0.16.17"
  },
  "devDependencies": {
    "@babel/core": "^7.0.0-beta.54",
    "@babel/preset-env": "^7.0.0-beta.54",
    "@babel/preset-react": "^7.0.0-beta.54",
    "babel-core": "^7.0.0-0",
    "babel-eslint": "^8.2.3",
    "babel-jest": "^23.4.0",
    "eslint": "^4.19.1",
    "eslint-config-airbnb": "^16.1.0",
    "eslint-config-prettier": "^2.9.0",
    "eslint-plugin-import": "^2.12.0",
    "eslint-plugin-jest": "^21.17.0",
    "eslint-plugin-jsx-a11y": "^6.0.3",
    "eslint-plugin-prettier": "^2.6.0",
    "eslint-plugin-react": "^7.9.1",
    "jest": "^23.4.1",
    "jest-dom": "^1.8.1",
    "prettier": "^1.13.5",
    "react-testing-library": "^4.1.3"
  },
  "browserslist": [
    "> 1%",
    "IE >= 9",
    "last 2 versions"
  ]
}

Question

I couldn't find any example for Jest + Gatsby v2. How can I get this working? I already looked at this issue:
#2932

@LekoArts LekoArts added help wanted Issue with a clear description that the community can help with. type: question or discussion Issue discussing or asking a question about Gatsby labels Jul 18, 2018
@ascorbic
Copy link
Contributor

Hey. You need to add this to your jest config:

        "transformIgnorePatterns": [
            "node_modules/(?!(gatsby)/)"
        ]

The problem is the same that I had in #6527. Babel is ignoring node_modules (as it should), but Gatsby has some non-transpiled files in cache-dir. Changing it to the pattern above means it ignores node_modules, except gatsby.

@LekoArts
Copy link
Contributor Author

@ascorbic Thanks! That solved my import issue.

Now I got issues with emotion:

 FAIL  src/components/__tests__/DocFooter.js
  ● Test suite failed to run

    You're trying to use the styled shorthand without babel-plugin-emotion.
    Please install and setup babel-plugin-emotion or use the function call syntax(`styled('div')` instead of `styled.div`)

       6 | import settings from '../../config/settings';
       7 |
    >  8 | const Wrapper = styled.div`
         |                        ^
       9 |   display: flex;
      10 |   justify-items: center;
      11 |   padding: 1rem 0;

      at Object.get (node_modules/create-emotion-styled/src/index.js:201:19)
      at Object.<anonymous> (src/components/DocFooter.jsx:8:24)
      at Object.<anonymous> (src/components/__tests__/DocFooter.js:3:1)

I did install babel-plugin-emotion and put it into the plugins array.

@ascorbic
Copy link
Contributor

You mean the plugins array in jest-preprocess.js?

@LekoArts
Copy link
Contributor Author

LekoArts commented Jul 19, 2018

Yes.

const babelOptions = {
  presets: ['@babel/preset-react', '@babel/preset-env'],
  plugins: ['syntax-class-properties', 'transform-class-properties', 'emotion'],
};

module.exports = require('babel-jest').createTransformer(babelOptions);

I'm using Gatsby's emotion plugin which sets the babel plugin for the rest of the site.

@LekoArts
Copy link
Contributor Author

LekoArts commented Jul 19, 2018

Update: I put emotion in first place, installed jest-emotion and did a jest --clearCache. Solved the issue.

New issue came up:

 FAIL  src/components/__tests__/DocFooter.js
  ● Test suite failed to run

    It appears like Gatsby is misconfigured. Gatsby related `graphql` calls are supposed to only be evaluated at compile time, and then
 compiled away,. Unfortunately, something went wrong and the query was left in the compiled code.

    .Unless your site has a complex or custom babel/Gatsby configuration this is likely a bug in Gatsby.

      88 | };
      89 |
    > 90 | export const fragment = graphql`
         |              ^
      91 |   fragment DocFooter on MarkdownRemark {
      92 |     parent {
      93 |       ... on File {

      at graphql (node_modules/gatsby/cache-dir/gatsby-browser-entry.js:33:9)
      at Object.<anonymous> (src/components/DocFooter.jsx:90:14)
      at Object.<anonymous> (src/components/__tests__/DocFooter.js:3:1)

@LekoArts
Copy link
Contributor Author

LekoArts commented Jul 19, 2018

After removing the fragment, the error obviously went away. I'm fine with that right now, I don't have to use the fragment.

I also had to wrap my component in my ThemeProvider. Is there a better solution instead of wrapping each component in future tests?

import React from 'react';
import { render, cleanup } from 'react-testing-library';
import { ThemeProvider } from 'emotion-theming';
import DocFooter from '../DocFooter';
import theme from '../../../config/theme';

const docMock = {
  parent: {
    relativePath: 'product/foundations/accessibility.md',
  },
};

afterEach(cleanup);

test('Displaying the different options in the DocFooter', () => {
  const { getByTestId, rerender } = render(
    <ThemeProvider theme={theme}>
      <DocFooter doc={docMock} editLink lastUpdated date={1531949762} />
    </ThemeProvider>
  );
});

@LekoArts
Copy link
Contributor Author

@ascorbic Got everything working now also with emotion. Do you want to create a Doc on testing with me? You can reach me on Discord

@ascorbic
Copy link
Contributor

I've made a PR for a first draft doc. I'd welcome feedback: #6678

@LekoArts
Copy link
Contributor Author

Closing this issue as PRs for this will merge soon.

@HriBB
Copy link

HriBB commented Nov 4, 2018

Ran into this problem yesterday. For jest to work, you need to enable modules: 'commonjs' option for @babel/preset-env.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Issue with a clear description that the community can help with. type: question or discussion Issue discussing or asking a question about Gatsby
Projects
None yet
Development

No branches or pull requests

3 participants