I have the following directive to autofocus a field:
.directive(\'ngAutofocus\', function ($timeout) {
return {
restrict: \'A\',
link: fu
A more verbose solution below, which allows testing (spying on) the focus that runs immediately (i.e. no $timeout or other event). The key is to first render a DOM element before $compile runs:
'use strict';
describe('Testing the focus call from the link function', function () {
var $compile;
var $rootScope;
beforeEach(angular.mock.module('auto-focus-module'));
beforeEach(inject(function (_$compile_, _$rootScope_) {
$compile = _$compile_;
$rootScope = _$rootScope_;
}));
it('should automatically focus when calling the link function', function () {
var $scope = $rootScope.$new();
// create an uncompiled DOM element so we can bind the focus spy
var rawEl = angular.element('<input auto-focus-directive>');
// set the spy
spyOn(rawEl[0], 'focus');
// compile the rawEl so that compile and link functions run
$compile(rawEl)($scope);
expect(rawEl[0].focus).toHaveBeenCalled();
});
});
With a directive and link function that could look like:
(function () {
'use strict';
angular.module('auto-focus-module')
.directive('autoFocusDirective', autoFocusDirective);
function autoFocusDirective () {
return {
link: link
};
function link (scope, elem) {
elem[0].focus();
}
}
})();
You can use document.activeElement to check focus. The only downside being that the HTML needs to be added to the document body for this to work.
https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement
You should use the angular.element api - jQuery lite - and use the method triggerHandler().
it('should have focus', function() {
elm.triggerHandler('focus');
expect(elm).toBeInFocus() //PSEUDO CODE - you will need to see how this can be tested
}
http://docs.angularjs.org/api/ng/function/angular.element
http://api.jquery.com/triggerhandler/
Potential Area for some testing focus knowledge:
https://shanetomlinson.com/2014/test-element-focus-javascript
Also you concerning your unit test - you don't need to append the element to the body, it's possible to test without that.
I figured it out, and it was pretty obvious actually;
it('should set the focus on timeout', function () {
spyOn(elm[0],'focus');
$timeout.flush();
expect(elm[0].focus).toHaveBeenCalled();
})
My problem was two-fold: