Jest: Setting window.navigator breaks tests

Created on 18 Feb 2016  路  9Comments  路  Source: facebook/jest

In package.json I have this:

"jest": {
...
"setupTestFrameworkScriptFile": "<rootDir>/prepare.js",
...
}

In prepare.js, I added this line:

window.navigator = {userAgent: "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2454.85 Safari/537.36"};

Now, I get errors like this:

TypeError: console.debug is not a function
        at Object.eval (node_modules/react/lib/ReactDOM.js:66:17)
        at Object.eval (node_modules/react/lib/React.js:14:16)
        at Object.eval (node_modules/react/react.js:3:18)

I also tried setting navigator in config.globals but I get a similar error.

Most helpful comment

@cpojer's solution was partially there for me in terms of a solution. I wanted to mock the navigator.userAgent multiple times within a single test suite. I didn't know how else to mock browser environments besides setting the userAgent dynamically.

I used the following defineProperty to be able to mutate the navigator.userAgent:

Object.defineProperty(window.navigator, "userAgent", (function(_value){
  return {
    get: function _get() {
      return _value;
    },
    set: function _set(v) {
        _value = v;
    }
  };
})(window.navigator.userAgent));

All 9 comments

What happens when you do this:

Object.defineProperty(window.navigator, 'userAgent', {value: '....'});

?

This workaround should work.

@cpojer's solution was partially there for me in terms of a solution. I wanted to mock the navigator.userAgent multiple times within a single test suite. I didn't know how else to mock browser environments besides setting the userAgent dynamically.

I used the following defineProperty to be able to mutate the navigator.userAgent:

Object.defineProperty(window.navigator, "userAgent", (function(_value){
  return {
    get: function _get() {
      return _value;
    },
    set: function _set(v) {
        _value = v;
    }
  };
})(window.navigator.userAgent));

Thanks @ConAntonakos, worked for navigator.appVersion as well.

Hello, i found another solution in this thread: https://stackoverflow.com/a/25518045
You basically have to set userAgent to be configurable like this:

Object.defineProperty(window.navigator, 'userAgent', {value: '....', configurable: true});

I tried the implementation from @maxrru as well as that another time where I left off the value key, maybe I needed a value? Neither worked for me.

I polished up @ConAntonakos answer a bit so I could reuse it easier.

const editableFn = _value => {
  return {
    get: () => _value,
    set: (v) => _value = v
  };
}

Object.defineProperty(navigator, "userAgent", editableFn(navigator.userAgent));
Object.defineProperty(navigator, "appVersion", editableFn(navigator.appVersion));

Let's save a few lines :)

const editableFn = _value => ({
    get: () => _value,
    set: (v) => _value = v
});

Object.defineProperty(navigator, "userAgent", editableFn(navigator.userAgent));
Object.defineProperty(navigator, "appVersion", editableFn(navigator.appVersion));

base on last answer, make sure add configurable: true in paralle with the get and set function, otherwise you can't really redefining the properties properly

I had to use the writable flag for platform:

Object.defineProperty(window.navigator, 'platform', { value: '', writable: true });
navigator.platform = 'Mac-Intel';
Was this page helpful?
0 / 5 - 0 ratings

Related issues

Antho2407 picture Antho2407  路  3Comments

samzhang111 picture samzhang111  路  3Comments

rosiakr picture rosiakr  路  3Comments

hramos picture hramos  路  3Comments

StephanBijzitter picture StephanBijzitter  路  3Comments