Skip to content
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

Expose jsdom to global environment #2460

Closed
thymikee opened this issue Dec 28, 2016 · 17 comments
Closed

Expose jsdom to global environment #2460

thymikee opened this issue Dec 28, 2016 · 17 comments

Comments

@thymikee
Copy link
Collaborator

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

@PauloASilva
Copy link

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.

@cpojer
Copy link
Member

cpojer commented Dec 28, 2016

window.location can be changed using Object.defineProperty(window, 'location', {value: '…'}). There is no need to expose jsdom for this.

@PauloASilva
Copy link

PauloASilva commented Dec 28, 2016

@cpojer It does not have the same behavior than the jsdom.changeURL() one.

@andyearnshaw
Copy link
Contributor

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?

@simon360
Copy link

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.

@aaronabramov
Copy link
Contributor

@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.

@simon360
Copy link

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.)

@SimenB
Copy link
Member

SimenB commented Jul 21, 2017

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

@Mathspy
Copy link

Mathspy commented Jul 29, 2017

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")

@cpojer
Copy link
Member

cpojer commented Aug 24, 2017

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.

@cpojer cpojer closed this as completed Aug 24, 2017
@cbeckr
Copy link

cbeckr commented Oct 15, 2017

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

@victorhqc
Copy link

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?

@SimenB
Copy link
Member

SimenB commented Oct 21, 2017

Then you can use a custom environment. resources: "usable" is supported in the env linked above your post

@victorhqc
Copy link

oh lol, thanks!

@lod
Copy link

lod commented Nov 7, 2017

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 });

@milesj
Copy link

milesj commented Jan 19, 2018

As of Jest 22/JSDom 11, using Object.defineProperty() no longer works on overriding location. This issue should be reopened and rediscussed.

@SimenB
Copy link
Member

SimenB commented Jan 19, 2018

@milesj see #5124

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests