You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
TL;DR: expect().toHaveStyleRule's target parameter has changed behavior. In Emotion 10 it seems to match against the last-declared selector that partially matches the target selector, while Emotion 11 seems to use the most precise selector.
We have a large Emotion 10 codebase that we're trying to port to Emotion 11, and it uses the toHaveStyleRule matcher pretty heavily. One of the styling idioms we use is similar to App.tsx in this repro setup, where we apply a style to all tags of a given type in the children of a component and selectively override this based on a prop. In this case, spans are red unless blueHeaders or greenHeaders is set, in which case only the spans in the th are recolored. Since the rules that these props add are more specific, they take precedence in the th.
When using toHaveStyleRule, however, using { target: 'span' } will match against the most specific rules applied to the table, in this case th span { ... }. As far as I can tell there is no way to assert that spans that are not in the th have a particular property. Emotion 10's matcher seems to ignore specificity and simply look at the last selector defined that matches (at least part of) the target. Since all of our tests were written under Emotion 10, some of them implicitly rely on this behavior and fail under Emotion 11.
Observe that only matches properly when not conflicting passes.
Expected behavior:
Emotion 10 behavior to be preserved: matches properly when not conflicting and matches properly when conflicting pass, and matches properly when conflicting the other way fails.
Failing this (it would be a breaking change after all), some way to preserve the old behavior would be greatly appreciated; something like a legacyTarget option to fall back to the old behavior or exactTarget that only matches exact selectors (rather than allowing e.g. div to match a rule declared with header div) would be perfect.
Environment information:
react version: 18.0.0
@emotion/react version: 11.9.0
The text was updated successfully, but these errors were encountered:
Current behavior:
TL;DR:
expect().toHaveStyleRule
'starget
parameter has changed behavior. In Emotion 10 it seems to match against the last-declared selector that partially matches thetarget
selector, while Emotion 11 seems to use the most precise selector.We have a large Emotion 10 codebase that we're trying to port to Emotion 11, and it uses the
toHaveStyleRule
matcher pretty heavily. One of the styling idioms we use is similar toApp.tsx
in this repro setup, where we apply a style to all tags of a given type in the children of a component and selectively override this based on a prop. In this case,span
s arered
unlessblueHeaders
orgreenHeaders
is set, in which case only thespan
s in theth
are recolored. Since the rules that these props add are more specific, they take precedence in theth
.When using
toHaveStyleRule
, however, using{ target: 'span' }
will match against the most specific rules applied to thetable
, in this caseth span { ... }
. As far as I can tell there is no way to assert thatspan
s that are not in theth
have a particular property. Emotion 10's matcher seems to ignore specificity and simply look at the last selector defined that matches (at least part of) thetarget
. Since all of our tests were written under Emotion 10, some of them implicitly rely on this behavior and fail under Emotion 11.To reproduce:
Stackblitz repro setup here
npm test
matches properly when not conflicting
passes.Expected behavior:
Emotion 10 behavior to be preserved:
matches properly when not conflicting
andmatches properly when conflicting
pass, andmatches properly when conflicting the other way
fails.Failing this (it would be a breaking change after all), some way to preserve the old behavior would be greatly appreciated; something like a
legacyTarget
option to fall back to the old behavior orexactTarget
that only matches exact selectors (rather than allowing e.g.div
to match a rule declared withheader div
) would be perfect.Environment information:
react
version: 18.0.0@emotion/react
version: 11.9.0The text was updated successfully, but these errors were encountered: