jest-styled-components icon indicating copy to clipboard operation
jest-styled-components copied to clipboard

v7.0.0 No styles found when shallow rendering nested styled-components

Open functionalDev opened this issue 5 years ago • 6 comments

When upgrading to styled-components v5 and jest-styled-components v7, we had multiple components missing styling rules in tests when shallow rendering and checking with toHaveStyleRule.

I came to the conclusion that it happens, when a styled-component has another styled-component as the root element in the mark up. Example Test:

import { shallow } from "enzyme";

it("nested with styling", () => {
  const WrapperComponent = styled.section`
    background: papayawhip;
  `;

  const MyComponent = ({className}) => <WrapperComponent className={className} />;
  const MyStyledComponent = styled(MyComponent)`
    color: red;
  `;

  const wrapper = shallow(
    <MyStyledComponent >{sampleText}</MyStyledComponent >,
  );
  expect(wrapper).toHaveStyleRule('color', 'red');
});

In my opinion this is a very common thing when using styled-components and should be supported by this library.

Something that is probably obvious, but just to be sure I point it out: There is no test for that case in toHaveStyleRule.spec.js and it fails when I add it.

functionalDev avatar Feb 19 '20 14:02 functionalDev

We have exactly the same problem - any news here? We are aware of the cheap solution -> switch tests to use mount instead of shallow to make them green, but we would definitely like to avoid taking this path as it increases time needed by tests significantly.

dumbNickname avatar Feb 26 '20 14:02 dumbNickname

The native version of toHaveStyleRule only tries to find style prop in the top-most level of a given styled-components like this:

component.props.styles

However, Enzyme will only render the first level and not any further, so style prop will be undefined.

If we dive three times into the given styled-components, the underlying components will be exposed, thus exposing the style prop:

component.dive().dive().dive().debug()
// <View style={{...}}
component.dive().dive().dive().prop('style')
// works

kennethnym avatar Mar 08 '20 20:03 kennethnym

@MrCreeper1008 thx for the explaination, but I don't quite get it. If I understand properly, then I am testing the top-most level of the given styled component and not some deeper level.

I created a pull request which fixes the issue for me. The cause seems to be that the className is not retrieved properly for the case describes above. I also added a test for the use case to toHaveStyleRule.spec.js.

functionalDev avatar Mar 09 '20 13:03 functionalDev

It works differently for react native. I forgot to put that

kennethnym avatar Mar 09 '20 13:03 kennethnym

v7.0.1 might help

quantizor avatar Apr 09 '20 04:04 quantizor

I have posted a possible reason here: https://github.com/styled-components/jest-styled-components/issues/297#issuecomment-639362675

And I currently use v7.0.2

Tokimon avatar Jun 24 '20 15:06 Tokimon