jest-dom icon indicating copy to clipboard operation
jest-dom copied to clipboard

Suggestion: toContainStyle

Open aldrichdev opened this issue 4 years ago • 4 comments

Describe the feature you'd like:

I would like a toContainStyle jest matcher, similar to toHaveStyle but not requiring the full CSS prop name and value to be entered into the test. For example, if I have a CSS prop like this:

animation: fadeIn 0.25s linear, scrollLeft 60s linear infinite;

And I just want a test that makes sure it is scrolling, right now I have to make a test like this:

    expect(myElement).toHaveStyle(
      `animation: ${fadeInKeyframes.name} 0.25s linear, ${scrollLeftKeyframes.name} 60s linear infinite;`
    )

I really have no interest in confirming it is fading, but I have to put the whole prop in there or the test fails. Maybe there is a workaround that I don't know about, but I have not been able to find a way to test only part of a CSS prop.

Suggested implementation:

Ideally it would work similar to toHaveStyle but the code would be doing a contains check, so that this test would succeed:

expect(myElement).toContainStyle(`${scrollLeftKeyframes.name} 60s linear infinite;`)

Describe alternatives you've considered:

The only alternatives I could think of are using toHaveStyle sub-optimally or not using it at all.

Teachability, Documentation, Adoption, Migration Strategy:

aldrichdev avatar Nov 08 '21 18:11 aldrichdev

I haven't checked again, but I recall that there was a previous complaint that toHaveStyle did not work with combined CSS properties. That is, that you had to use the individual CSS properties instead. The animation CSS property is a shorthand of various other properties. Have you checked if, instead of this:

expect(element).toHaveStyle('animation: 3s infinite alternate slidein;')

you can do this:

  animation-duration: 3s;
  animation-name: slidein;
  animation-iteration-count: infinite;
  animation-direction: alternate;

That way, you can feel free to omit from that second version the parts of the animation rules that you are not interested in.

Let me know how it goes.

gnapse avatar Nov 08 '21 18:11 gnapse

Thank you @gnapse. In my case, because I have two animations specified in one animation prop, animation-name would not work since I would have to provide the full value, which would be something like: animation-name: fadeIn, scrollLeft.

aldrichdev avatar Nov 08 '21 20:11 aldrichdev

So you want to validate that animation-name contains scrollLeft, but without having to mention that fadeIn is also in the mix. Is that it?


Regardless of your answer, my take on this request is influenced by my regret of ever having added .toHaveStyle to the matchers in this library in the first place. This matcher is by far the one that gives us more headaches, and the one for which more issues are opened reporting unexpected behaviours. Adding yet another one that does something similar, but with even more angles for unexpected behaviours, seems something I'm not a fan of.

I can recommend that you do this for now: shamelessly clone/copy the implementation of toHaveStyle off the code in this repository, and create your desired toContainStyle matcher in your own project. Tweak it, polish it, and use it for a while to first validate if it's feasible. Get a feel of how it works.

If you validate that it's valuable enough, you can contribute a PR to this repo to propose it. I can help you along the way if needed.

gnapse avatar Nov 08 '21 20:11 gnapse

So you want to validate that animation-name contains scrollLeft, but without having to mention that fadeIn is also in the mix. Is that it?

That is correct.

Thank you for the suggestion. I will take a crack at implementing it on my side as I have time.

aldrichdev avatar Nov 09 '21 15:11 aldrichdev