How do I check if my element has been focussed in a unit test

23,093

Solution 1

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:

  1. I wasn't calling the timeout flush function so timeout wasn't occuring, and
  2. I was trying to look at the focus attribute of the element whereas just looking at the call of the focus() function is much more like unit-testing. The focus attribute is something that really belongs to the e2e testing territory.

Solution 2

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

Share:
23,093

Related videos on Youtube

Maarten
Author by

Maarten

20+ years experience in web development, system administration and application management.

Updated on July 09, 2022

Comments

  • Maarten
    Maarten almost 2 years

    I have the following directive to autofocus a field:

    .directive('ngAutofocus', function ($timeout) {
        return {
            restrict: 'A',
            link: function (scope, elm) {
                    $timeout(function () {
                    elm[0].focus();
                });
            }
        };
    }
    

    How would I unit test this? I tried several things like the following selector but they all return errors or false:

    console.log($(elm[0]).is(':focus'));
    

    My unit test is set up like this:

    elm = angular.element('<input type="text"  name="textfield1" ng-autofocus>');
    $scope.$digest();
    $compile(elm)($scope);
    
    • Lee Goddard
      Lee Goddard over 8 years
      Besides the remarks you make in your answer, readers should note your directive definition should read: .directive('ngAutofocus', '$timeout', function ($timeout) { -- otherwise $timeout is not transcluded by Angular.
    • Maarten
      Maarten over 8 years
      Are you sure? You probably mean with a [ added too, and not because transclusion but because of minification causing injection to break without it with certain minimizers. See github.com/johnpapa/…
    • Lee Goddard
      Lee Goddard over 8 years
      yes to the [ - I should edit outside the comment box.
    • Maarten
      Maarten over 8 years
      then still, the injection helping is only needed in certain cases, and not required for the question
  • Mobigital
    Mobigital about 2 years
    great option, should expand your post on the specifics!