11

I am setting up some tests using JSDom where I need the window and document globals and also need to pass a different URL/href for each tests. How do I set the location.hash and location.href properties?

global.document = jsdom({url: 'http://localhost?something=not#test', 'html': ''});
global.window = document.defaultView;
console.log(window.location.href); // returns 'about:blank'
console.log(window.location.hash); // returns no value

I have tried assigning values directly to window.location.hash with same result.

cyberwombat
  • 38,105
  • 35
  • 175
  • 251

4 Answers4

5

I ran into this issue too, but was having trouble getting the jsdom.env(...) solution to work. I ended up following the recommendation here, and using jsdom's changeURL function. My test fixture setup looked something like this:

beforeEach(function() {
  // snip...
  jsdom.changeURL(window, 'http://foo/bar')
  // snip...
})
killthrush
  • 4,859
  • 3
  • 35
  • 38
4

A lot of these answers are old. Newer jsdom versions don't allow you to overwrite things like before. What you're looking for is probably the reconfigure function.

import { JSDOM } from 'jsdom';

const jsdom = new JSDOM();

// ...
jsdom.reconfigure({
  url: 'https://www.test.com/whatever/url/you/want',
});
// ...

Documentation for reconfigure() can be found here.

Check out this article from 2020 for more information.

Shane Bishop
  • 3,905
  • 4
  • 17
  • 47
1

You can set location.hash by inputting string just after # in url. Refer to the follow my code.

var jsdom = require("jsdom");

jsdom.env({
    url: 'http://localhost?something=not#hash', 'html': '',
    onload: function( window ) {
        console.log(window.location.href); // http://localhost/?something=not#hash
        console.log(window.location.hash); // #hash
    }
});
Alfred
  • 1,276
  • 11
  • 19
  • I realize I didn't quite phrase my question correctly as it was mostly why was href blank. Your answer suggest I need the callback. Is there a way around that? it's very messy doing that in my tests as I need to change the href for each test. – cyberwombat Nov 25 '15 at 16:56
  • @Yashua, right! Because page loading is asynchronous, as [jsdom guide in github](https://github.com/tmpvar/jsdom), It is recommended to use `config.done, config.onload, config.created.` – Alfred Nov 25 '15 at 17:09
  • I ended up mocking out my own window object - jsdom was way overkill for my tests. http://stackoverflow.com/questions/4792281/mocking-window-location-href-in-javascript – cyberwombat Nov 25 '15 at 17:11
1

This one worked for me.

Object.defineProperty(window.location, 'href', {
  writable: true,
  value: 'some url'
});
Aliaksandr Sushkevich
  • 11,550
  • 7
  • 37
  • 44
  • This answer solved a problem I was having trying to test a component using `HashRouter` from React Router, which was dying with the opaque error `TypeError: Cannot read property 'substr' of undefined` when trying to use `createHashHistory()`. The *undefined* was `window.location.hash`, which JSDom doesn't provide, so defining it this way in my test fixed the problem. Hopefully this will help anyone encountering the same issue. – Scott Martin Mar 17 '21 at 13:42