Skip to content
Advertisement

TypeError: Cannot read property ‘navigator’ of undefined

My unit test case started failing when I started running the unit test in mocha from karma, Earlier we were using karma and –browser to run the test case but it was running fine,

  1) common/browser-detection
       returns the mock object when there is no userAgent:
     TypeError: Cannot read property 'navigator' of undefined
      at Context.<anonymous> (packages/node_modules/@webex/plugin-meetings/test/unit/spec/common/browser-detection.js:115:41)
      at processImmediate (internal/timers.js:464:21)

  2) plugin-meetings
       meeting index
         Public Api Contract
           #addMedia
             should reject promise if user already in left state:
     AssertionError: expected [ReferenceError: navigator is not defined] to be an instance of UserNotJoinedError
      at /Users/nswarnka/Documents/Neeraj/Projects/upstream/webex-js-sdk/packages/node_modules/@webex/plugin-meetings/test/unit/spec/meeting/index.js:763:20

Package.json

"test": "node ./tooling/index.js test",

 "circleci:local": "circleci local execute -c .circleci/github.config.yml",

test file –

It fails for navigator here, TypeError: Cannot read property ‘navigator’ of undefined

  it('returns the mock object when there is no userAgent', () => {
    Object.defineProperty(global.window.navigator, 'userAgent', {
      get: () => undefined,
      configurable: true
    });

ReferenceError: navigator is not defined

/**
 * proxy to browser navigator.mediaDevices.enumerateDevices()
 * @returns {Promise}
 */
Media.getDevices = () => {
  if (navigator && navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {
    return navigator.mediaDevices.enumerateDevices();
  }

  return Promise.reject(new MediaError('enumerateDevices not supported.'));
};

Advertisement

Answer

Accessing global.window.navigator is an error both in a browser (where global is not defined) and in Node.js (where there is no global window object, and also no navigator).

If that test were to run in a browser, you could just redefine the userAgent on navigator (or equivalently window.navigator), i.e.

Object.defineProperty(navigator, 'userAgent', {
  get: () => undefined,
  configurable: true
});

But if you run that test in Node.js without a DOM emulation setup you will run into an error because navigator is undefined. You could mock navigator of course before mocking userAgent, but then for your test to pass you would also need to mock navigator.mediaDevices and navigator.mediaDevices.enumerateDevices, and in the end you would test nothing but the mock code itself.

Conclusion: use DOM emulation (JSDom, cheerio) or run your test in a real browser with Karma or Puppeteer.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement