Hello, I'm seeing this issue in a snapshot for a small 'dumb' component.
The component uses 2 styled components internally
const OverlayNotice = styled.div`
position: absolute;
right: 0;
top: 100px;
padding: 10px;
background-color: #333;
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
box-shadow: -1px 1px 1px 1px #a6a6a6;
color: #fff;
`;
const OverlayNoticeCount = styled.span`
${OverlayNotice} & {
margin-left: 5px;
display: inline-block;
padding: 5px 10px;
border-radius: 50%;
background-color: ${props => (props.error ? '#cc111a' : '#2F79B9')};
text-align: center;
}
`;
In the snapshot generated where props.error is true I'm getting this css output
.c0 .eSznRZ {
margin-left: 5px;
display: inline-block;
padding: 5px 10px;
border-radius: 50%;
background-color: #2F79B9;
text-align: center;
}
.c0 .c2 {
margin-left: 5px;
display: inline-block;
padding: 5px 10px;
border-radius: 50%;
background-color: #cc111a;
text-align: center;
}
The one that has the hashed class name is for the case where props.error is false and obviously isn't actually used in the snapshot anywhere. The snapshot for the case where props.error is false only has one set of (correct) rules generated.
This isn't anything critical so far, but I'm concerned that the hashed class name may change at some point and cause failing snapshots.
Good catch, thank you very much @Flashwit.
I'll fix this ASAP.
@Flashwit, did you manage to overcome this bug?
@MicheleBertoli I've recently began using nested selectors in a heavily tested project and this bug is really getting in the way. I'd like to fix it and submit a PR.
I'm not familiar with the project at all and this looks like a corner case. I assume you have a rough idea of where the bug may be. Can you please point me in the right direction?
If not, I'll dig on my own.
Thanks!
@elektronik2k5 Hey there. I took a look in the codebase to see what happened to this and it looks like it was 'overcome' through refactoring. This particular styled component was replaced with a semantic-ui component so this error doesn't occur anymore and it doesn't seem to have popped up anywhere else among our other styled components.
Thank you very much @elektronik2k5 @Flashwit.
Unfortunately, I didn't have time to solve this issue yet, and any help is much appreciated.
The issue is that Styled Components generate two different CSS blocks for <OverlayNoticeCount error /> and <OverlayNoticeCount />:
.sc-bdVaJa .bpZDEj {
margin-left: 5px;
display: inline-block;
padding: 5px 10px;
border-radius: 50%;
background-color: #cc111a;
text-align: center;
}
.sc-bdVaJa .eSznRZ {
margin-left: 5px;
display: inline-block;
padding: 5px 10px;
border-radius: 50%;
background-color: #2F79B9;
text-align: center;
}
.sc-bdVaJa is the classname for <OverlayNotice />.
.bpZDEj is the class name for <OverlayNoticeCount /> when error is true.
.eSznRZ is the class name for <OverlayNoticeCount /> when erros is false.
The way this package filters out the CSS blocks that don't belong to a snapshot is by checking whether the class names used in the rendered tree are present in the generated styles.
Since both trees are rendering <OverlayNotice />, the .sc-bdVaJa class name is always found (and, therefore, the blocks stay).
However, in the second test, the .eSznRZ class name is not used in the tree and it doesn't get replaced.
.c0 .eSznRZ {
margin-left: 5px;
display: inline-block;
padding: 5px 10px;
border-radius: 50%;
background-color: #2F79B9;
text-align: center;
}
The idea is making the includesClassNames function smarter/stricter.
For example, by splitting the selector when multiple classes are present and making sure all of them are used in the tree.
Thank you @MicheleBertoli for the detailed explanation and guidance! It is very helpful and I'll try to find some time to fix this bug. :)
@MicheleBertoli it was a bit more complex than what you described, but your explanation definitely helped. If styled-components had a hacking guide or wiki, which would document the basic concepts it would have been easier and faster to do get it done.
Please review my PR. Thanks! :bowing_man:
馃檶 thank you very much, @elektronik2k5.