This is a question/discussion topic.
While discussing this issue #2453 and earlier conversation here #890 I came to conclusion that it may be worth exposing jsdom
somehow to the environment. What do you think?
@cpojer @dmitriiabramov
On my use case I need to change the window.location
per it()
so that jsdom
behaves like modern browsers. This way the package.json testURL property/configuration wont be enough :(
As jsdom
only allows this through the jsdom.changeURL() method, exposing jsdom
would be the only way around to accomplish the use case.
window.location
can be changed using Object.defineProperty(window, 'location', {value: '…'})
. There is no need to expose jsdom for this.
@cpojer It does not have the same behavior than the jsdom.changeURL()
one.
I have a script that does different things based on whether it is at the top level or not. window.top
cannot be reconfigured without access to the jsdom instance created by Jest. How about also exposing the instance via something like jest.dom
, which would allow us to use the reconfigure()
method?
In our case, we have traditionally used Jest to test our React components using snapshots or, sometimes, more involved tests around events - those tests require a full mock DOM. Our components are held in a component library monorepo, and included in a separate project that does server-side rendering later on.
We recently had an issue where a component had an unchecked reference to document
. This didn't cause any failures in our unit tests, but when we tried to integrate into our other project, the server-side rendering failed because it couldn't find window
.
The solution to this is easy - just check if window
is undefined - but we'd like to add some regression tests. Currently, I don't see a way to do this, because (as far as I know) we can only have jsdom
enabled or disabled for all of our tests, not on a test-by-test basis. If we disable jsdom
, all our previous tests will need to be re-written; if we leave it enabled, we can't test for this different category of errors.
Some sort of way to access and modify jsdom
would be great, especially if it could help with this scenario.
@simon360 i think what you're looking for is this http://facebook.github.io/jest/blog/2017/05/06/jest-20-delightful-testing-multi-project-runner.html#multi-project-runner-configuration-overhaul
you can have two configs and run test twice in jsdom env and node env.
But honestly, writing tests for things like this is an overkill. If you use proper flow types, those kind of bugs will not be an issue at all.
Oh, that looks perfect. Thanks @aaronabramov!
(I'd love to use flow, but it isn't a good fit for our project right now. It's on our radar, but we just can't set the time aside for it at the moment.)
You can use @jest-environment jsdom
in all tests requiring jsdom, and have node
in package.json
.
https://facebook.github.io/jest/docs/en/configuration.html#testenvironment-string
I am using a library that access "protocol", "host" and "port" on the location object.
@cpojer's work around does work if I do this:
Object.defineProperty(window.location, "protocol", {
writable: true,
value: "http:"
});
Object.defineProperty(window.location, "host", {
writable: true,
value: "localhost:14187"
});
Object.defineProperty(window.location, "port", {
writable: true,
value: "14187"
});
But fails if I try to do this
Object.defineProperty(window, "location", {
writable: true,
value: {
protocol: "http:",
host: "localhost:14187",
port: "14187"
}
});
I believe that exposing jsdom would actually make this solution a lot neater:
jest.jsdom.changeURL("http://localhost:14187")
Not planning to do this in jest-environment-jsdom. People can fork jest-environment-jsdom and build their own environment on top of it which will expose any globals people need.
Not planning to do this in jest-environment-jsdom. People can fork jest-environment-jsdom and build their own environment on top of it which will expose any globals people need.
FWIW, here's an up-to date template: https://github.com/mes/jest-environment-jsdom-external-scripts
What if I need to configure jsdom
to have resources: "usable"
in the configuration? or any other configuration that may be needed. Expoding jsdom
configuration doesn't harm and it can provide a lot of flexibility. Any plan to expose the configuration? Or accept a pull request that enables this?
Then you can use a custom environment. resources: "usable"
is supported in the env linked above your post
oh lol, thanks!
Changing the href location as suggested by @cpojer did not work for me, I had to follow the technique from @Mathspy
const url = "...";
Object.defineProperty(window.location, 'href', { value: url });
As of Jest 22/JSDom 11, using Object.defineProperty()
no longer works on overriding location. This issue should be reopened and rediscussed.
@milesj see #5124
Most helpful comment
As of Jest 22/JSDom 11, using
Object.defineProperty()
no longer works on overriding location. This issue should be reopened and rediscussed.