9

I'm having the follow error when running my tests with jest.

  console.error
    Error: Could not parse CSS stylesheet
        at exports.createStylesheet ([PERSONAL_PATH]/node_modules/jsdom/lib/jsdom/living/helpers/stylesheets.js:34:21)
        at HTMLStyleElementImpl._updateAStyleBlock ([PERSONAL_PATH]/node_modules/jsdom/lib/jsdom/living/nodes/HTMLStyleElement-impl.js:68:5)
        at HTMLStyleElementImpl._childTextContentChangeSteps ([PERSONAL_PATH]/node_modules/jsdom/lib/jsdom/living/nodes/HTMLStyleElement-impl.js:36:12)
        at HTMLStyleElementImpl._insert ([PERSONAL_PATH]/node_modules/jsdom/lib/jsdom/living/nodes/Node-impl.js:832:14)
        at HTMLStyleElementImpl._preInsert ([PERSONAL_PATH]/node_modules/jsdom/lib/jsdom/living/nodes/Node-impl.js:768:10)
        at HTMLStyleElementImpl._append ([PERSONAL_PATH]/node_modules/jsdom/lib/jsdom/living/nodes/Node-impl.js:868:17)
        at HTMLStyleElementImpl.appendChild ([PERSONAL_PATH]/node_modules/jsdom/lib/jsdom/living/nodes/Node-impl.js:610:17)
        at HTMLStyleElement.appendChild ([PERSONAL_PATH]/node_modules/jsdom/lib/jsdom/living/generated/Node.js:395:60)
        at StyleSheet.insert ([PERSONAL_PATH]/node_modules/@emotion/sheet/dist/sheet.cjs.dev.js:121:11)
        at Object.insert ([PERSONAL_PATH]/node_modules/@emotion/cache/dist/cache.cjs.dev.js:168:19) {width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;}/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ[BLOB]== */

      at VirtualConsole.<anonymous> (node_modules/jsdom/lib/jsdom/virtual-console.js:29:45)
      at exports.createStylesheet (node_modules/jsdom/lib/jsdom/living/helpers/stylesheets.js:38:63)
      at HTMLStyleElementImpl._updateAStyleBlock (node_modules/jsdom/lib/jsdom/living/nodes/HTMLStyleElement-impl.js:68:5)
      at HTMLStyleElementImpl._childTextContentChangeSteps (node_modules/jsdom/lib/jsdom/living/nodes/HTMLStyleElement-impl.js:36:12)
      at HTMLStyleElementImpl._insert (node_modules/jsdom/lib/jsdom/living/nodes/Node-impl.js:832:14)
      at HTMLStyleElementImpl._preInsert (node_modules/jsdom/lib/jsdom/living/nodes/Node-impl.js:768:10)

I've tried to set a jsdom version on my packages.json, also tried to update jest packages. Didn't changed the error. It's not actually causing the tests to fail, but it is polluting the jest output.

If need to more details please ask in comments than I edit this question.

Edit

Here is the sass file to the tested component:

$spacing-medium: 2.4rem
$spacing-small: 1.6rem
$color-green: #3aa537
$color-white: #ffffff
$color-super-pale-gray: #f0f0f0
$color-pale-gray: #e6e6e6
$color-border-pale-gray: #b3b3b3
$tundora: #4d4d4d
$boulder: #757575
$electric-blue: #2251ff
$font-size-large: 1.6rem
$font-family-regular: "Arial", sans-serif
$font-family-bold: "Arial Bold", sans-serif
$[PRIVATE]-sans-regular-font-family: '[PRIVATE] Sans Regular', $font-family-regular
$[PRIVATE]-sans-medium-font-family: '[PRIVATE] Sans Medium', $font-family-bold
$font-size-medium: 1.4rem

@font-face
  font-family: [PRIVATE] Sans Medium
  src: url('https://cdn.[PRIVATE].com/assets/fonts/web/[PRIVATE]Sans-Medium.woff2') format('woff2')

@font-face
  font-family: [PRIVATE] Sans Regular
  src: url('https://cdn.[PRIVATE].com/assets/fonts/web/[PRIVATE]Sans-Regular.woff2') format('woff2')

.margin-cell
  margin-left: -12px

.active
  color: $color-green
  font-family: $[PRIVATE]-sans-medium-font-family
  margin-left: -12px

section
  margin: 1rem 0

  nav.sub-navigation
    background-color: $color-white
    padding: $spacing-medium

    a.sub-navigation-active
      display: inline-flex
      color: $electric-blue
      font-size: $font-size-large
      font-family: $[PRIVATE]-sans-medium-font-family
      text-decoration: none
      border-bottom: 4px solid $electric-blue
      padding-bottom: 1rem

  div.grid-container
    padding: $spacing-small 0 $spacing-small 0
    font-size: $font-size-medium
    background-color: $color-white
    display: grid

    .group-key
      font-family: $[PRIVATE]-sans-medium-font-family
      color: $tundora
      margin-bottom: 10px

    .input-style
      width: 100%
      font-family: $[PRIVATE]-sans-regular-font-family
      height: 30px
      padding: 0 $spacing-small
      color: $tundora
      font-size: $font-size-medium

    .group-divider
      padding: $spacing-small 10px $spacing-small 10px

    .advanced-configurations-container
      width: 100%
      font-size: $font-size-medium

    .advanced-configurations-header
      font-size: $font-size-medium
      color: $electric-blue
      width: unset

  div.info-group
    padding: 0 0 $spacing-small $spacing-medium
    font-size: 1.4rem
    background-color: $color-white
    border-top: 2px solid $color-super-pale-gray
    display: grid
    grid-template-columns: 1fr 1fr

    div.group-subsection
      display: grid
      padding: 0.8rem 0
      margin: 10px 25px 10px 0
      height: 50px
      &.variable-height
        height: unset
        min-height: 50px

    .group-key
      font-family: $[PRIVATE]-sans-medium-font-family
      color: $tundora
      margin-bottom: 10px

    .info-group-internal
      display: grid
      grid-template-columns: 1fr 1fr

  .icons-holder
    display: flex
    justify-content: center
    gap: 26px

.tab
  margin-top: $spacing-medium

.filter-wrapper
  padding: $spacing-small $spacing-medium $spacing-small $spacing-medium
  background-color: $color-white
  border-top: 1px solid $color-pale-gray

.search-input
  width: 300px
  height: 32px

.modal-form

  .form-row
    display: flex
    margin: $spacing-medium 0
    gap: $spacing-medium

    > .form-column
      flex: 1

      .input-wrapper
        height: 32px

        textarea
          //border: $color-pale-gray solid 1px
          color: $tundora
          height: 24px
          min-height: 9rem
          overflow: hidden
          padding: 10px
          resize: none

    .question-label
      color: $tundora
      font-family: $[PRIVATE]-sans-medium-font-family
      display: block
      font-weight: bold
      margin-bottom: 10px
      font-size: 1.4rem

Here is my jest.config.js:

module.exports = {
  clearMocks: true,
  collectCoverageFrom: ['src/**/*.{ts,tsx,js,jsx}'],
  coverageDirectory: 'coverage',
  coveragePathIgnorePatterns: [
    '/node_modules/',
    'src/index.tsx',
    'src/temp/',
    'src/types/',
    'src/helpers/testHelper.ts',
    'src/helpers/constants.ts',
    'src/pages/Errors/*',
  ],
  coverageThreshold: {
    global: {
      branches: 90,
      functions: 90,
      lines: 90,
      statements: 90,
    },
  },
  moduleFileExtensions: ['js', 'json', 'jsx', 'ts', 'tsx'],
  moduleNameMapper: {
    '\\.(css|scss|sass)$': 'identity-obj-proxy',
    '\\.svg$': '<rootDir>/__mocks__/genericMock.js',
    '^@src/(.*)$': '<rootDir>/src/$1',
    '^@helpers/(.*)$': '<rootDir>/src/helpers/$1',
    '^@appConfig(.*)$': '<rootDir>/config/application/appConfigTypes.ts',
  },
  preset: 'ts-jest',
  setupFilesAfterEnv: ['./src/helpers/jestHelper.ts'],
  testEnvironment: 'jsdom',
  testMatch: ['**/*.(test|spec).(ts|tsx)'],
  transform: {
    '^.+\\.(ts|tsx)$': 'ts-jest',
  },
  transformIgnorePatterns: ['node_modules/(?!(react-native|[PRIVATE]|lodash)/)'],
};

Update

I've begun to isolate the things from the component that I was testing, got to the point of having just a single component in it. So I've found a date-picker from a third-party library was causing the problem. I did clone it, run their tests, notice that they were using another library to render the component in the tests. Found out that they also had testing-library/react, created another test using it to render, but had no success to reproduce the error. Does anyone have any suggestions about what I may try next? I'm running out of ideas.

wviana
  • 1,619
  • 2
  • 19
  • 47

3 Answers3

11

There was an issue open for it here: https://github.com/jsdom/jsdom/issues/2230, saying you should change your jsdom configuration to:

const jsdom = require('jsdom');
const { JSDOM } = jsdom;
const virtualConsole = new jsdom.VirtualConsole();
virtualConsole.on("error", () => {
  // No-op to skip console errors.
});
const dom = new JSDOM(``, { virtualConsole });

(copied directly from that git issue).

That same answer is also available here: JSDOM: Could not parse CSS stylesheet.

There's also another issue mentioned here, https://github.com/styled-components/styled-components/issues/1931, where it seems that changing the multiline comments to single line comments fixed the issue for some people.

I believe jsdom doesn't have that great CSS support or it seems like it's breaking on weird things trying to parse CSS.

However I don't believe that the solution is to parse the CSS anyways, you should be using jest transformations or moduleNameMapper to mock the css and import an empty object, no reason to test the styles.

According to the jest documentation, https://jestjs.io/docs/webpack#mocking-css-modules, you can use moduleNameMapper:

"moduleNameMapper": {
  "\\.(css|less)$": "<rootDir>/__mocks__/styleMock.js",
  "\\.(gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
}

Then inside the fileMock.js you can just export an empty object.

You can also use transform:

"transform": {
  "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/fileTransformer.js"
}

Then in that fileTransformer.js file you can also just export an empty object.

  • Hi there, thanks for trying to help. I've checked the `modulesNameMapper` I already have this config `'\\.(css|scss|sass)$': 'identity-obj-proxy'`. About the jsdom config, where should I place it?The only string with `jsdom` that I have is in *jest.config.js* the follow `testEnvironment: 'jsdom'`. – wviana Nov 17 '21 at 21:45
  • Remove ````identity-obj-project```` and just uninstall that, all you need is an empty ````mock.js```` file and all it has to do is ````module.exports = {}````, then use that file in your ````moduleNameMapper````, i.e. ````\\.css$: /tests/mock.js````, so that you map any css imports to an empty object import instead. –  Nov 17 '21 at 22:00
0

Use identity-obj-proxy in Jest to transform your scss for the tests only: npm install identity-obj-proxy.

npm i -D identity-obj-proxy.

Also see this answer: https://stackoverflow.com/a/63638444/11067065.

Robert-Jan Kuyper
  • 2,418
  • 12
  • 22
0

The error message pops up...

due to the stylesheet using (legitimate) features that [the jsdom] CSS parser does not support. source comment on GitHub issue

In the same thread there is a solution which worked for me. I modified it slightly:

// in setupTests.js
const originalConsoleError = console.error
console.error = function (msg) {
  if (msg.startsWith('Error: Could not parse CSS stylesheet')) return
  originalConsoleError(msg)
}
borisdiakur
  • 10,387
  • 7
  • 68
  • 100