Javascript.confirm() and Angularjs Karma e2e test

All we need is an easy explanation of the problem, so here it is.

I have an Angularjs application that uses simple javascript confirm before executing some actions.


function TokenController($scope) {
  $scope.token = 'sampleToken';

  $scope.newToken = function() {
    if (confirm("Are you sure you want to change the token?") == true) {
      $scope.token = 'modifiedToken';


<div id="tokenDiv">
  Token:{{token}} <button ng-click="newToken()">New Token</button>

Now I want to have an end to end test to check the token is being replaced correctly in the view. How can I intercept the javascript.confirm() call so it doesn’t stop the execution of the test?


it('should be able to generate new token', function () {
   var oldValues = element('#tokenDiv').text();
   element('button[ng-click="newToken()"]').click(); // Here the javascript confirm box pops up.

So far I’ve tried to redefine the window.confirm function but then the actual call complains that it is undefined.

I also wanted to set up a Jasmine spy on window.confirm but in the following syntax spyOn(window, 'confirm'); it gives me an error saying you can not spy on null.

How would I go about making such test work?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Another option would be to directly create a spy and automatically return true:

//Jasmine 2.0
spyOn(window, 'confirm').and.callFake(function () {
     return true;

//Jasmine 1.3
spyOn(window, 'confirm').andCallFake(function () {
     return true;

Method 2

E2E Testing

Please consult to this project:

Unit Testing

If you create a service for the dialog boxes then you can mock that service in your unit test in order to make your code testable:


function TokenController($scope, modalDialog) {
  $scope.token = 'sampleToken';

  $scope.newToken = function() {
    if (modalDialog.confirm("Are you sure you want to change the token?") == true) {
      $scope.token = 'modifiedToken';

modalDialog service

yourApp.factory('modalDialog', ['$window', function($window) {
    return {
        confirm: function(message) {
            return $window.confirm(message);


function modalDialogMock() {

    this.confirm = function() {
        return this.confirmResult;

    this.confirmTrue = function() {
        this.confirmResult = true;

    this.confirmFalse = function() {
        this.confirmResult = false;


var scope;
var modalDialog;


beforeEach(inject(function($rootScope, $controller) {
    scope = $rootScope.$new();
    modalDialog = new modalDialogMock();
    var ctrl = $controller('TokenController', {$scope: scope, modalDialog: modalDialog});

it('should be able to generate new token', function () {


Method 3

In unit tests you can mock the $window object like this:

Your test:

beforeEach(function() {

    inject(function($rootScope, $injector) {
        $controller = $injector.get('$controller');
        $scope = $rootScope.$new();
        var windowMock = { confirm: function(msg) { return true } }
        $controller('UsersCtrl', { $scope: $scope, $window: windowMock });

Your controller:

myAppName.controller('UsersCtrl', function($scope, $window) {
    $scope.delete = function() {
        var answer = $window.confirm('Delete?');
        if (answer) {
             // doing something

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from or, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply