0
votes

I got a AngularJS WebApp, which I test with Karma and Jasmine.js

But it throws an error if I use navigator.webkitGetUserMedia() in my controller.

TypeError: 'undefined' is not a function (evaluating 'navigator.webkitGetUserMedia')

Here is a sample of my Controller

app.controller('appCtrl', function ($scope, $interval, $location, globVal, loginService) {

        
        navigator.webkitGetUserMedia({video: true, audio: false},
        function (stream) {
            globVal.webcam = window.URL.createObjectURL(stream);
        },
                function (err) {
                    console.log("error happened:" + err);
                }
        );

        
        $scope.startTimeout = $interval(function () {
            // do something
        }, 2000);


    });

my testspec

'use strict';

describe("Controller: appCtrl", function () { var $rootScope, $scope, controller, globVal, location;

beforeEach(function () {
    module('myModul');

    globVal = {
        customer: {why: 'idle'},
        goHome: 1,
        goHomeCounter:1
    };

    module(function ($provide) {
        $provide.value('globVal', globVal);
    });
    
    inject(function ($injector, $location) {
        $rootScope = $injector.get('$rootScope');
        $scope = $rootScope.$new();
        controller = $injector.get('$controller')("appCtrl", {$scope: $scope});
        location = $location;
    });
}); 

describe("init", function () {

    it('Should init', function () {
        expect($scope).toBeDefined();
    });

});

describe("globVal idle", function () {

    it('should globVal be idle', function () {
        expect(globVal.customer.why).toBe('idle');
    });

});

describe("startTimeout", function () {
    
    it('Should have method startTimeout ', function () {
        expect($scope.startTimeout).toBeDefined();
    });

});

How should I mock navigator object?

3

3 Answers

0
votes

Use spyOn(navigator, 'webkitGetUserMedia'); And if that doesn't work just create your own webkitGetUserMedia function as part of the navigator object in your test spec.

0
votes

You could inject $window in beforeEach or in the it("should ...") function and replace the entire navigator object in $window.

Like this:

it("should ... when running in an obscure environment", inject(function ($window) {
  $window.navigator = {
    userAgent: 'Mozilla/5.0 (NodeJS; Karma 0.0.0) (Cucumber/0.0 like virtualisation) Fantasy/0.0',
    appVersion: '5.0 (NodeJS; Karma 0.0.0) (Cucumber/0.0 like virtualisation) Fantasy/0.0',
    platform: 'nodeKarma'
  };

  scope.$digest();
  .......
}));

Be sure to include enough properties!

0
votes

The issue is likely that you are not using protocol "https:" in your karma.conf.js

I had the exact same issue until i added the following lines (with the correct certificates of course).

  config.set({
    protocol: 'https:',
    httpsServerOptions: {
      key: fs.readFileSync('server.key', 'utf8'),
      cert: fs.readFileSync('server.crt', 'utf8')
    },