-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
Storyshots: Fix preact@10 compatibility #11145
Conversation
@marvinhagemeister So it turns out #10978 broke Here is the relevant code: In
In
Can you suggest an update that might restore the old behavior for If you're interested in running this on your machine:
As a side note #10978 also broke Many thanks! 🙏 |
@shilman The serialized output is different, because jest's built in serializers rely heavily on duck-typing (no way around that with JavaScript). In Preact 8.x the returned {
nodeName: "div",
attributes: {...}
children: [...]
} Jest checks those properties and assumes that we have an actual DOM node here. Back then our property names aligned 1:1 with the DOM so the same serializer could be used for Preact coincidentally. With Preact 10.x those properties have changed to allow greater compatibility with third party React libraries. Trouble is that this isn't detected as a DOM node anymore. Jest also has a built-in React serializer, but that only comes into play when an object has the The easiest solution is to add a custom serializer for Preact. It would look like this: // Custom jest serializer for Preact
const renderToString = require('preact-render-to-string/jsx');
module.exports = {
test(value) {
return (
value && typeof value === 'object' && value.constructor === undefined
);
},
print(value, serialize, indent) {
const result = renderToString(value);
return indent(result);
},
}; We should probably publish this as a neat npm package sometime in the future. Maybe I have time to look at that once my vacation is over.
Checking for different Preact versions is doable via feature detection. Preact 8.x doesn't support import * as preact from 'preact';
// Keep track of rendered container for legacy Preact 8.x versions
let renderedStory: Element;
export function renderMain(...) {
// Preact 8.x has no support for Fragments
const isPreact10 = preact.Fragment;
if (isPreact10) {
render(null, rootElement);
} else {
renderedStory = render(null, rootElement, renderedStory);
}
showMain();
if (isPreact10) {
render(element, rootElement);
} else {
renderedStory = render(element, rootElement);
}
} |
@marvinhagemeister thanks so much for the detailed explanation! @fjorgemota any chance you can pick up this as follow-up work to #10978?
If not, I can take a crack at it when I'm done with my current projects |
Hey @shilman, thanks for the ping! I'll look into this issue this week....just one small, maybe even dumb, question: these two itens should be two new pull requests, right? Thanks for the ping. =) |
FYI: I've just published a new version of our jest preset for preact that ships with the serializer. See: https://github.com/preactjs/jest-preset-preact/ |
@marvinhagemeister thanks so much for publishing that--what about your vacation!? 🙈 ❤️ @fjorgemota two PRs would be amazing. i'll do my best to review/test/merge promptly 💪 ❤️ |
@shilman My vacations are over now (unfortunately) 😅 |
Does this "just" need the snapshots updated? Anything else to do on this PR? |
All of the changes here have been rolled into #13928. Will address the rest of the issues in that PR. |
Issue: #11144
What I did
How to test