-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Improve support for Enzyme's shallow rendering #1672
Conversation
💥 No ChangesetLatest commit: a298263 Merging this PR will not cause any packages to be released. If these changes should not cause updates to packages in this repo, this is fine 🙂 If these changes should be published to npm, you need to add a changeset. Click here to learn what changesets are, and how to add one. Click here if you're a maintainer who wants to add a changeset to this PR |
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit a298263:
|
c2e66af
to
64d6ddc
Compare
Codecov Report
|
packages/jest-emotion/src/utils.js
Outdated
@@ -189,7 +198,9 @@ export function getStylesFromClassNames( | |||
} | |||
|
|||
export function getStyleElements(): Array<HTMLStyleElement> { | |||
let elements = Array.from(document.querySelectorAll('style[data-emotion]')) | |||
let elements = global.document |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think global
might not be always available - so maybe better to use a simple check of typeof document !== 'undefined'
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also - when this check matters? for the enzyme's case when tests can be run without jsdom available globally?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's right, this code should always be run in node, but the code shouldn't simply fail if JSDOM is not installed.
@mitchellhamilton would you like to also take a look at this? |
04619c0
to
f3a591b
Compare
|
||
const tickle = (wrapper: *) => { | ||
if (typeof wrapper.dive === 'function') { | ||
wrapper.find('EmotionCssPropInternal').forEach(el => el.dive()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couldn't we have a serializer that calls this and then calls out to the printer so we don't have to call enzyme-to-json ourselves?(We'd also want a WeakSet to store which wrappers we've done the printing on so we don't do it infinitely)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue is order, we want to execute this on the enzyme objects, but our serializer works on the JSON objects. The other options would either to be to have two serializers, such as an init-emotion-enzyme
serializer as well as the standard jest-emotion
one, so the user could setup the correct order of ['init-emotion-enzyme', 'enzyme-to-json', 'jest-emotion']
, or to export an initializer so that the get snapshot call would look something like expect(initializer(component)).toMatchSnapshot()
. Both of these seemed awkward DX, this alongside the fact that we really do rely on enzyme-to-json
led to the idea of simply tying them together here. It turns out that this makes it easier to setup, too, as neglecting to include both serializers would cause an error the way it was setup before. Open to other ideas, but this seemed to offer the right balance of DX and functionality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, SGTM
packages/jest-emotion/README.md
Outdated
``` | ||
|
||
To assist with shallow rendering, there's a custon enzyme snapshot serializer, that includes the `enzyme-to-json` | ||
serializer, which is available by importing `jest-emotion/enzyme`: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a note mentioning that people should remove the enzyme-to-json serializer if they have it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds good
</div> | ||
) | ||
|
||
expect(toJson(wrapper, { mode: 'deep' })).toMatchSnapshot() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this toJson call meant to be here, I thought that's happening at the snapshot serializer level?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this particular test requires the deep
option, which enforces all the nodes to have their render methods called.
packages/jest-emotion/src/utils.js
Outdated
@@ -189,15 +203,17 @@ export function getStylesFromClassNames( | |||
} | |||
|
|||
export function getStyleElements(): Array<HTMLStyleElement> { | |||
let elements = Array.from(document.querySelectorAll('style[data-emotion]')) | |||
const elements = isBrowser |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about this, I feel like if we're not in a browser environment when serializing an element we should throw.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
while i agree with you, i feel we should do it at a higher level if we are to do so, with an informative error message. should i add such to this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If by higher level you mean check in the module scope then I don't think that would be ideal because the module that the serializer is in should be runnable outside of a browser environment so that a user can add the serializer to the snapshotSerializers
option but still have some tests that use the node jest environment. An informative message would be great though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, that makes sense. Added a warning.
Co-Authored-By: Mateusz Burzyński <mateuszburzynski@gmail.com>
Co-Authored-By: Mateusz Burzyński <mateuszburzynski@gmail.com>
Co-Authored-By: Mitchell Hamilton <mitchell@hamil.town>
813e750
to
02030da
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
* Improve support for Enzyme's shallow rendering * Remove empty className from snapshots * Fix flow errors * Remove [transformed] from plain objects, add interesting test case * Clean-up code * don't transfrom DOM elements * Updating interesting test case, the plot thickens * Resolved the curious test isolatiion issue - clean JSDOM after each test * Move enzyme-specific serialization to subpackage * Update docs/testing.mdx Co-Authored-By: Mateusz Burzyński <mateuszburzynski@gmail.com> * Update packages/jest-emotion/README.md Co-Authored-By: Mateusz Burzyński <mateuszburzynski@gmail.com> * Add types to jest-emotion/enzyme * Changes per code review * Update packages/jest-emotion/test/react-enzyme.test.js Co-Authored-By: Mitchell Hamilton <mitchell@hamil.town> * Add message to remove enyzme-to-json if it's present * Add warning if no JSOM when getting styles * Update utils.js * Update utils.js * Update utils.js Co-authored-by: Mateusz Burzyński <mateuszburzynski@gmail.com> Co-authored-by: Mitchell Hamilton <mitchell@hamil.town>
What:
NOTE: this was originally merged to master, but was backed out as it introduced a breaking change to existing snapshots.
Fix #949, also support better snapshot serialization when using shallow rendering
Why:
While using shallow rendering is generally considered unwise, there are projects that wish to convert from CSS to CSS-in-JS and that already use shallow rendering in their tests.
How:
The
jest-emotion
package was updated to dive into shallow rendered components to trigger the addition of the styles to the DOM to supporttoHaveStyleRule
. Snapshots are supported by adding classNames to the shallow-rendered object by leveraging thecss
prop.Checklist: