3

I hope this is a simple question.

I have a select-box directive that should close when anything is clicked outside of the directive. So the window has a an event listener to hide the box once a click event is heard-

$window.addEventListener('click', function() {
  $scope.expanded = false;
  $scope.$apply();
});

Which works fine, no complaints. But I'm trying to write a unit test for this and can't figure out how to trigger the click even on the window itself.

it('should close the dropdown if the window is clicked', function() {
  toggleButton.trigger('click');

  expect(eleSimpleOptionBox.hasClass('ng-hide')).toBe(false);

  $window.trigger('click');

  expect(eleSimpleOptionBox.hasClass('ng-hide')).toBe(true);
});

I've tried the following-

$window.trigger('click'); // as well as .click()
$window.triggerHandler('click');
angular.element('body').trigger('click'); // as well as .click()
someWrappingElement.trigger('click'); // as well as .click()
2
  • do you call $digest on your scope or $rootScope after triggering the event? Commented Nov 15, 2015 at 8:25
  • Neither. But in the test the first click trigger works without a $digest so I assume the second would. It's using the DOMs event listeners and not angulars event listeners. Commented Nov 16, 2015 at 15:28

2 Answers 2

0

Ran into a similar situation trying to test a click event on the $window object. I tried all of the above to try and trigger the event but I couldn't get the event to fire. My workaround was to-do something like the code snippet below in the test so that I could test the listener function.. Still not happy with it, but it's better that no test I guess...

describe('test $window events', ()=> {
   var callbackFn; //variable to capture the callback

    beforeEach(()=> {
        //spy on the addEventListener method and capture the function reference
        spyOn($window, 'addEventListener').and.callFake((event: string, callback: any) => { 
            callbackFn = callback; 
        });
    });

    //trigger the callbackFn in your test
    it('should call the event listener', ()=> {
       callback(); //this will trigger the event.. 
       expect(true).toBe(true);
    );
});
Sign up to request clarification or add additional context in comments.

Comments

0

Try this:

function triggerMouseEvent(node, eventType, x, y) {
    var event = document.createEvent('MouseEvents');
    event.initMouseEvent(
        eventType,                  // type
        true,                       // canBubble
        eventType != 'mousemove',   // cancelable
        window,                     // view
        0,                          // detail
        x,                          // screenX
        y,                          // screenY
        x,                          // clientX
        y);                         // clientY
    node.dispatchEvent(event);
}
triggerMouseEvent($window, 'click');

The initMouseEvent function is deprecated now and MouseEvent should be used, but looks like IE doesn't support MouseEvent yet.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.