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

Media queries #113

Closed
gregberge opened this issue May 29, 2019 · 7 comments
Closed

Media queries #113

gregberge opened this issue May 29, 2019 · 7 comments

Comments

@gregberge
Copy link

First thank you for this awesome library!

I would like to use toHaveStyle to test a media query. I am migrating xstyled tests from jest-styled-components to jest-dom since the approach is better for me.

My question is simple. How to do the equivalent with toHaveStyle?

expect(container.firstChild).toHaveStyleRule('color', 'red', {
   media: '(min-width: 768px)',
})
gregberge added a commit to styled-components/xstyled that referenced this issue May 29, 2019
It is currently not possible to test media queries, see testing-library/jest-dom#113
@gnapse
Copy link
Member

gnapse commented May 29, 2019

My question is simple.

It may look simple, but it is far from it, I think 😄

I'm unfamiliar with both jest-styled-components and xstyled, and only somewhat familiar with styled-components, but on a quick glance to jest-styled-components, it seems to me what you want to transfer from the usage of it to this library is not easily achievable.

About jest-styled-components

That library (jest-styled-components) seems to be pretty tied up to how styled-components are implemented internally. For example, what it seems to be testing internally is related to the structure of React elements as returned by React.createElement (see this). It does not seem to actually run the components it is "rendering" through the full react stack to end up with the finished result of the DOM structure created by rendering those components. Therefore this jest-styled-components library seems to be having access to the raw props of elements and the raw styled-component-specific style objects given to those elements, in order to check for the style conditions.

The difference compared to jest-dom

This library jest-dom however, is React-agnostic, and tests an actual DOM structure that can be rendered with anything (React, Vue, Angular, etc.). When you render something for jest-dom to consume (for example by using react-testing-library) you no longer have the raw props and style objects that went through styled-components. You end up instead with what a browser would end up when rendering all that.

Stylesheets in jest-dom

Stylesheets in this context are also a bit of a complex thing to test in this detail that you intend to test them. For starters, our style checking matchers will not work properly unless you manually setup attaching a css stylesheet to the document, as done here for instance.

What you'd need to do, hypothetically

I'm not sure therefore if you can:

  1. Get the stylesheet content that styled-components generated under the hood, and...
  2. Attach it to the document manually during tests as shown in the linked lines above, and...
  3. I'm, not sure how jsdom (the headless browser context where usually jest-dom runs) would allow you then to check for specific media queries.

On setting the browser width in tests

On that last point, what our toHaveStyle matcher does is inspect the actual computed styles of the element being tested (think of the "computed styles" panel you see in a browser dev tools). So I guess that for styles applied only under a certain media query, you'd need to somehow tell the browser where the tests are being run to set a specific window size first, then test the styles of the element that you want to test to see if they change in response to changes in window size. Ideally something like this:

const { container } = render(<ComponentBeingTestedHere />)

// TODO: Attach at this point the stylesheet source code to the document...
// as shown here https://github.com/testing-library/jest-dom/blob/09f7f041805b2a4bcf5ac5c1e8201ee10a69ab9b/src/__tests__/to-have-style.js#L12-L18

browser.setWindowWidth(1280) // Note: This is not a real API!!!
expect(container.firstChild).toHaveStyle("color: blue")
browser.setWindowWidth(768) // Note: This is not a real API!!!
expect(container.firstChild).toHaveStyle("color: red")

The above hypothetical test would "prove" there's a media query somehow, without actually testing it in terms of the css source code that sets it up. However, it's up to you to see if there's a way to tell the browser in the tests to set a specific window size. I'm not sure jsdom supports that, unfortunately.

Bottomline

But this all boils down to the intent of this library (and the entire set of testing libraries it is part of): tests should be testing the end result, and not the implementation details.

That's not to say your approach is wrong. If you still prefer to test things in this level of details, and your project is nevertheless intrinsically tied to styled-components, it may not be a bad thing that you keep testing the internals of the styles set in this way. And in that case jest-dom may not be the best fit for your purpose.

Hope all this helps, and please, if you do pursue checking out the pointers I give here to try make this work, please share your findings here, wether positive or not.

@gregberge
Copy link
Author

Hello @gnapse,

I agree, jest-styled-components tests the underlying implementation, and I want to switch to jest-dom to test the end result (the CSS applied on the element).

I suspected that I had to change the size of the browser in order to test media queries. But I was not sure it will work that way.

I hoped that someone had already the problem and was able to give me a real working example in order to gain time.

I will work on it, as soon as I have something that work I will post it here.

Thank you!

@gregberge
Copy link
Author

gregberge commented May 30, 2019

It looks like it is not currently possible https://github.com/jsdom/jsdom/blob/d6f8a97b5fb7709d6ad0215c1ae95fd4cab58489/lib/jsdom/level2/style.js#L29

@gnapse
Copy link
Member

gnapse commented Aug 17, 2019

I'm going to be closing this for the time being. Feel free to open if there's something actionable stemming from this proposal.

@gnapse gnapse closed this as completed Aug 17, 2019
@weyert
Copy link

weyert commented Aug 17, 2019

I would suggest consider testing media queries through Cypress or similar framework were stylesheet actually get rendered and/or interpreted.

@alexkrolick
Copy link
Contributor

Interestingly, even @media all seems to be excluded from window.getComputedStyle(el) in JSDOM

@Yankovsky
Copy link

Hey! This library worked for me https://github.com/dferber90/jest-transform-css

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants