2

I need to test styles of a component from sass, but only inline styles are loaded in the dom

my test case:

   describe('Danger', () => {
      const dangerLabel = <DangerLabel>TESTE</DangerLabel>;
      it('deve ter class -danger', () => {
        const { container } = render(dangerLabel);
        expect(container.firstChild).toHaveClass('-danger');
      });
      it('deve ter a cor vermelho', () => {
        const { container } = render(dangerLabel);
        const style = window.getComputedStyle(container.firstElementChild);
        expect(style.backgroundColor).toBe('#e74c3c');
      });
    });

jest-config

module.exports = {
  roots: ['<rootDir>'],
  transform: {
    '\\.(js|jsx)?$': 'babel-jest',
  },
  testMatch: [
    '<rootDir>/src/**/?(*.)(spec|test).{js,jsx,mjs}',
  ],
  moduleFileExtensions: ['js', 'jsx', 'json', 'node'],
  testPathIgnorePatterns: ['/node_modules/', '/public/'],
  setupFilesAfterEnv: [
    '@testing-library/jest-dom/extend-expect',
  ],
  moduleNameMapper: {
    '\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$': '<rootDir>/config/jest/__mocks__/fileMock.js',
    '.+\\.(css|scss)$': 'identity-obj-proxy',
  },
};

component export:

 import LabelContainer from './label_container';
    import Label from './DefaultLabel';
    import DangerLabel from './DangerLabel';
    import PrimaryLabel from './PrimaryLabel';
    import WarningLabel from './WarningLabel';
    import SuccessLabel from './SuccessLabel';
    import InfoLabel from './InfoLabel';
    import '../assets/styles/label.scss';
    
    export default Label;
    export {
      LabelContainer,
      PrimaryLabel,
      DangerLabel,
      WarningLabel,
      SuccessLabel,
      InfoLabel,
    };

exec:

expect(received).toBe(expected) // Object.is equality

    Expected: "#e74c3c"
    Received: ""

      30 |       const { container } = render(dangerLabel);
      31 |       const style = window.getComputedStyle(container.firstElementChild);
    > 32 |       expect(style.backgroundColor).toBe('#e74c3c');
         |                                     ^
      33 |     });
      34 |   });
      35 |

I have tried some packages like jest-transform-css and jest-transform-scss but with no success, it is possible to do that test?

As requested DangerLabel Code:

import React from 'react';
import DefaultLabel from './DefaultLabel';

const DangerLabel = props => (
  <DefaultLabel {...props} className="-danger" />
);

export default DangerLabel;

DefaultLabel enter image description here

With toHaveStyle:

 it('deve ter a cor vermelho', () => {
      const { container } = render(dangerLabel);
      expect(container.firstElementChild).toHaveStyle(`
        background-color: rgb(231, 76, 60)};
      `);
    });

Result:

enter image description here

1 Answers1

1

You had been missing the visible prop when rendering DangerLabel in the test file which is why it was not rendering and failing test #1.

const dangerLabel = <DangerLabel visible>TESTE</DangerLabel>;

The next error that you'll face is the empty string for all CSS properties in the style object that you get from the window.getComputedStyle (in test #2). There is a reason to it.

So, I went ahead with an alternate implementation of asserting the background colour CSS property using toHaveStyle from the jest-dom lib. itself.

I had to use an npm module hex-rgb for converting the hex color to a rgba value.

See the solution working here. To view the test results in codesandbox, read this

Bonus: Using style object did not work but there is a declarative way of accessing the CSS properties from the return value of getComputedStyle - const backgroundColor = style. getPropertyValue ('background-color).

ypahalajani
  • 770
  • 1
  • 6
  • 18
  • Thank you for the codesandbox example, about the visible sorry, it was configured as true in default props. I have tried as you did with toHaveStyle, and put color as rgb still not working, i'll put the extra changes on description – Vinicius Henrique Aug 20 '21 at 17:47
  • Did you check the test file in the codesandbox link? The test cases are passing there. Check the test file with the syntax you are using. Also, paste the error and the code using toHaveStyle that you are facing and using respectively. – ypahalajani Aug 20 '21 at 17:57
  • I put the last code and result in the description, I saw the codesandbox but I didn't understand. Any hexadecimal color I put in, returned success, and the css file doesn't contain any label background style, also my case is using scss maybe there is some difference – Vinicius Henrique Aug 20 '21 at 18:39
  • Ok, can you replicate your behaviour in a codesandbox and send a link here so that I can help you better? – ypahalajani Aug 20 '21 at 18:45
  • Got it! It is because of the difference in the version of `@testing-library/jest-dom` npm package that we are using. See it [here](https://stackoverflow.com/a/64998343/2925949) – ypahalajani Aug 20 '21 at 18:55
  • Kindly share your exact version of `@testing-library/jest-dom` so that I can try reproducing the issue. – ypahalajani Aug 20 '21 at 18:57
  • "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^12.0.0", "jest": "^27.0.5", – Vinicius Henrique Aug 20 '21 at 19:10
  • Can you share the exact module version from the lock file? – ypahalajani Aug 20 '21 at 19:16
  • @testing-library/jest-dom = 5.14.1, @testing-library/react = 12.0.0 I'll try to add my code to codesandbox – Vinicius Henrique Aug 20 '21 at 19:22
  • Ok, apparently the string `rgba(321, 76, 60)` works (adding `a` (denoting alpha in rgba)) – ypahalajani Aug 20 '21 at 19:37
  • True, the case passes with rgba but it doesn't matter the color, it always passes, I put in the codesandbox one more case to assert for white and I add the red in the css, both pass. https://codesandbox.io/s/stackoverflow-react-testing-library-forked-lspik?file=/src/App.test.js – Vinicius Henrique Aug 22 '21 at 21:35
  • Yes, even I checked it later - it is weirder – ypahalajani Aug 23 '21 at 12:49