testing-library / jest-dom

:owl: Custom jest matchers to test the state of the DOM
https://testing-library.com/docs/ecosystem-jest-dom
MIT License
4.4k stars 392 forks source link

toHaveStyle not picking up styles from styled-components #295

Closed barucAlmaguer closed 3 years ago

barucAlmaguer commented 3 years ago

Relevant code or config:

import '@testing-library/jest-dom'
import React from 'react'
import { render } from '@testing-library/react'
import { Button } from '.'; // Internally, "Button" is styled using styled-components
import { defaultTheme } from '../../themes'

test('renders button variants correctly', () => {
  const { container, getByTestId } = render(
    <Button theme={defaultTheme} data-testid='subBtn' variant='secondary' >
      Decrease count
    </Button>
  )
  // Test styles
  expect(getByTestId(/subBtn/)).toHaveStyle('background-color: transparent')
})

What you did:

Trying to test the final styles for a component using "toHaveStyle" matcher. This test worked fine before I yarn upgraded the project.

What happened:

After upgrading my dependencies, some tests stopped working (the ones including toHaveStyle matcher). Other tests (.toBeInTheDocument, .toHaveClassName...) still work fine. It appears to be picking the component base styles (not considering styles applied by classnames / styled-components), The error log looks like this:

  ● renders button variants correctly

    expect(element).toHaveStyle()

    - Expected

    - background-color: transparent;
    + background-color: ButtonFace;

      12 |   )
      13 |   // Test styles
    > 14 |   expect(getByTestId(/subBtn/)).toHaveStyle('background-color: transparent')
         |                                 ^
      15 | })

I never apply a "ButtonFace" style, this makes me think it's jest that is not picking up the stylesheets or the styles for some reason. also relevant: The Button component works just fine, tested imported in other projects and with playroom-js. It's just the tests that are not getting the styles properly (and previously did).

Reproduction:

Unfortunately, this happens in a private repo (not the owner), so it's kind of complicated to provide a full demo. If you need any more information (tests setup, package.json, etc) I can gladly provide it.

Problem description:

Tests were working fine previous to running "yarn upgrade", which updated the testing-related libraries to newer versions

Suggested solution:

I'm not sure how could this be solved, I'm guessing the newer versions of the libraries introduced some breaking changes or changes in configuration which I am not addressing

eps1lon commented 3 years ago

For style related issues we need the full markup.

It's likely that this is caused by jsdom (your testing environment) not jest-dom. How does the test behave in an actual browser?

gugiserman commented 3 years ago

Same here. Tried upgrading project dependencies today and noticed all tests that use .toHaveStyle() started to fail, so I reverted back and upgraded one by one until I came to the conclusion that is styled-components v5.2.0 upgrade that caused it to break. So I created an issue over there: https://github.com/styled-components/styled-components/issues/3297

barucAlmaguer commented 3 years ago

@eps1lon, in an actual browser it works just fine, the problem is with the tests. But as @gugiserman said, it seems to be a problem with styled-components@5.2.0.

I downgraded to 5.1.1 and the tests pass again. I'm not sure if something can be done to avoid this problem in the side of jest-dom, it probably should be solved from SC's side.

thanks, both of you!

felixmagnus commented 3 years ago

Why was this issue closed? We are having the same problem in our project - how are we supposed to continue here?

gnapse commented 3 years ago

@felixmagnus in the jsdom environment where tests usually run the components are mounted in isolation, and stylesheets are not normally loaded/mounted in the DOM. I wrote more about it in https://github.com/testing-library/jest-dom/issues/113#issuecomment-496971128.

Check for instance what we have to do in the very tests of this library so that a bunch of css is loaded, so it can be recognized by getComputedStyle:

https://github.com/testing-library/jest-dom/blob/3fb1835715f57e5f6d938e2d9d3cd94ac675247b/src/__tests__/to-have-style.js#L13-L25

In other words, this library cannot guarantee that some css is injected into the DOM. Any suggestions are welcome as to how to make it easier.

DylanJu commented 3 years ago

Why was this issue closed? We are having the same problem in our project - how are we supposed to continue here?

@felixmagnus styled-component v5.2.0 makes this error. now v5.2.1 does not make this error. see this issue

wilomgfx commented 3 years ago

Same issue here, it's a shame because it works if I'm not overriding styles from another component.

As soon as I override something, it does not pick up the overridden styles.

image

On the left is my unit test and the right is what getComputedStyles returns for that component. Tests: the base component styles Browser: The overridden styles (right one)

FerhatAvdic commented 2 years ago

Same here. I changed the background color of a button via props and it wouldnt pick up the css.

gnapse commented 2 years ago

toHaveStyle is not responsible for making sure the stylesheets are loaded in jsdom. Please see my comment in https://github.com/testing-library/jest-dom/issues/113#issuecomment-496971128.

Can you make sure all needed stylesheets are loaded and properly attached to the DOM in your tests? This is dependent on how your app does CSS.

Unfortunately, when we introduced toHaveStyle we did not realize it would give so many headaches in this regard. We probably should deprecate it, or at the very least, put a very noticeable warning in the documentation that it may not work all the time due to the tests not having stylesheets loaded.

Please consider more end-to-end tests environments for these purposes instead. Test environments that truly work against the fully running app instead of against components mounted in isolation.

FerhatAvdic commented 2 years ago

Since we are talking about styled components here, i am not sure if we are able to get that stylesheet as of now: https://github.com/styled-components/styled-components/issues/1018

DenaldM commented 1 year ago

Why was this issue closed? We are having the same problem in our project - how are we supposed to continue here?

Hello, this issue happened to me as well. I noticed that the styled component version was "styled-components": "^6.0.0-rc.1", which seems to cause the error, what I did I reverted back to version "styled-components": "5.3.3", and now the tests run fine. I hope this helps you!