2014-10-17 2 views
3

В модульном тесте Karma.js для директивы Angular.js я столкнулся с странной несовместимостью в поведении между Chrome и Firefox.ng-blur in Karma on Firefox

Директива имеет шаблон, и этот шаблон содержит форму с некоторыми входами. Я хочу, чтобы модуль тестировал, будет ли какой-то метод области вызван после того, как первый вход потеряет фокус.

Итак, у меня есть этот тест:

describe('Firefox weirdness.', function() { 
    var $scope, compiled; 
    var template = '<dir></dir>'; 

    beforeEach(function() { 
    module('templates'); 
    module('App'); 

    inject(function($compile, $rootScope) { 
     $scope = $rootScope.$new(); 
     compiled = $compile(template)($scope); 
     angular.element(compiled).appendTo(document.body); 
     $scope.$apply(); 
    }); 
    }); 

    it('Shows weirdness.', function() { 
    var i1 = compiled.find('input[name="i1"]'), 
     i2 = compiled.find('input[name="i2"]'), 
     executed = false; 

    // This method is never called on Firefox. 
    // On Chrome it works flawlessly. 
    $scope.doStuff = function() { 
     executed = true; 
    }; 

    // Focus first input, then second. 
    // It doesn't help if I delay them via setTimeouts, 
    // or by digesting the scope. 
    angular.element(i1).focus(); 
    angular.element(i2).focus(); 

    // This line fails. 
    expect(executed).to.be.true; 
    }); 
}); 

И директива выглядит следующим образом (это нефрит):

form(name="form") 
    input(name="i1", ng-blur="doStuff()") 
    input(name="i2") 

В то время как мой JS код:

describe('Firefox weirdness.', function() { 
var app = angular.module('App', []); 

app.controller('MainCtrl', function($scope) { 
    $scope.doStuff = function() { 
    console.log('Stuff done!'); 
    }; 
}); 

app.directive('dir', function() { 
    return { 
    restrict: 'E', 
    templateUrl: 'dir.html' 
    }; 
}); 

Что неправильно? Тест пройдет в Chrome, но на Firefox - он терпит неудачу. Я пытался использовать некоторые тайм-ауты и т. Д., Чтобы исключить некоторые проблемы с синхронизацией, но это все равно потерпит неудачу. Может кто-нибудь объяснить, почему и намек на то, как это исправить?

Я использую Angular.js 1.2, Mocha + Chai и karma-ng-jade2js-препроцессор, чтобы поместить шаблоны в отдельный Angular модуль (для тестирования, чтобы избежать Angular, пытающегося загрузить их асинхронно).

Я привел небольшой пример в этом репо: https://github.com/kamituel/firefox-blur-weirdness. Вы можете попробовать его, клонируя, устанавливая зависимости npm и запуская ./karma start karma.conf. В результате вы увидите прохождение теста Chrome, а Firefox один не удастся.

ответ

3

Вы можете фактически вызвать событие размытия вместо

angular.element(i1).focus(); 

Может быть, запуская событие фокуса на другой входе не вызывает событие размытия ранее сосредоточен вход в Firefox

Если вы забыли о Угловом, это также терпит неудачу в Firefox

it('Shows weirdness.', function() { 
    var i1 = compiled.find('input[name="i1"]'), 
     i2 = compiled.find('input[name="i2"]'), 
     executed = false; 

    angular.element(i1).bind('blur', function() { 
     executed = true; 
    }); 

    angular.element(i1).focus(); 
    angular.element(i2).focus(); 

    expect(executed).to.be.true; 
}); 

в то время как это не

it('Shows weirdness.', function() { 
     var i1 = compiled.find('input[name="i1"]'), 
     i2 = compiled.find('input[name="i2"]'), 
     executed = false; 

    angular.element(i1).bind('blur', function() { 
     executed = true; 
    }); 

    angular.element(i1).blur(); 


    expect(executed).to.be.true; 
}); 
+0

Да, это объясняет это поведение. Я поддержал ваш ответ, и если пока не появится другой ответ, я награду за награду. Благодаря! – kamituel