29

I have the following function to test

function tradePage() {
  setTimeout(function() {
    window.location.pathname = document
      .getElementById('button')
      .getAttribute('new-page');
  }, 100);
}

And I've written the following test:

test('should change page when button is clicked', () => {
  var button = document.querySelector('#button');

  jest.useFakeTimers();
  button.dispatchEvent(createEvent('click'));
  jest.runAllTimers();

  expect(window.location.pathname).toEqual('/new-url');
});

But when I run the test I get this error:

    expect(received).toEqual
    Expected value to equal:
    "/new-url"
    Received:
    "blank"

Things I've already done/tried

  • My packages.json already have the "testURL" set up.

  • I found this possible solution (that didn't work):

     Object.defineProperty(window.location, 'pathname', {
       writable: true,
       value: '/page/myExample/test',
     });
    

Any ideas what else I can try?

Kiss
  • 896
  • 1
  • 10
  • 14

4 Answers4

25

I found a working method by declaring in the beginning of the test a global variable:

global.window = { location: { pathname: null } };

and checked this variable like this:

expect(global.window.location.pathname).toContain('/new-url');

That worked fine.

Kiss
  • 896
  • 1
  • 10
  • 14
5

instead of having to set the pathname to null, you can just check it like

expect(global.window.location.href).toContain('/new-url').

so that way you don't have to assign null to the pathname.

meewog
  • 1,690
  • 1
  • 22
  • 26
Ibrahimj
  • 53
  • 1
  • 5
  • 1
    Good answer ( at least for my case which is very similar to this one). Besides all it works also in TS smoothly while answer from @Kiss does not (types mismatch). – Kiszuriwalilibori Mar 17 '22 at 12:13
1

There's a few ways this can be done, depending on the degree of test granularity you're looking for.

Globally

Jest provides a testEnvironmentOptions property that can have a url:

// jest.config.js
module.exports = {
  ...
  testEnvironmentOptions: {
    url: "https://yourtesturl.com/some-path"
  },
  ....
};

Test Suite

Method based on the answer here.

const OLD_LOCATION = window.location;

beforeEach(() => {
  Object.defineProperty(window, 'location', {
    value: new URL("https://yourtesturl.com/some-path"),
    writable: true,
  });
});

afterAll(() => {
  Object.defineProperty(window, 'location', {
    value: OLD_LOCATION,
    writable: true,
  });
});

Per Test

test("Some test", () => {
  const OLD_LOCATION = window.location;

  Object.defineProperty(window, 'location', {
    value: new URL("https://yourtesturl.com/some-path"),
    writable: true,
  });

  Object.defineProperty(window, 'location', {
    value: OLD_LOCATION,
    writable: true,
  });
});

NOTE

The window.location object can be overwritten. Just be sure to restore it after your test suite has finished so you don't mess up other tests that would be affected by the change.

TheScrappyDev
  • 4,375
  • 2
  • 21
  • 25
0
Object.assign(location, { host: "www.newhost.com", pathname: 'file.txt' });

It will update all the location URL object properties (origin, href, hostname, host).

so the final href property will be https://www.newhost.com/file.txt.

Do this in a beforeEach block.

just call console.log(location) to verify the results. Happy coding!

Mist
  • 913
  • 6
  • 11