Testing angular directive that remove dom element doesn't work (at least for me...)

angularjs, angularjs-directive

Solution

When you execute `element.remove()`, it only removes the element from its parent, remove bound events, etc.

The shortest solution is to enclose the directive in a parent element:

var element = compileTemplate('<div><span permission-needed="W">Some content goes here</span></div>');

then

expect(element.html()).toBe('')

will pass since `element` doesn't contain the `span` anymore

Problem

I've got a directive that removes a dom element upon some permission checking : ``` angular.module('app').directive('permissionNeeded', function ($location, $route, SecurityService) { return { restrict: 'A', link: function (scope, element, attributes) { var permissionNeeded = attributes.permissionNeeded; if (permissionNeeded) { if (SecurityService.checkAccess($route.current.name) !== permissionNeeded) { element.remove(); } } } }; }); ``` Directive is working fine, however I can't test it. The DOM manipulation (element.remove()) seems to be triggered after my expect assertion : ``` it('should not do anything cos permissions are correct', function () { $route.current = { name: 'import' } var element = compileTemplate('<span permission-needed="W">Some content goes here</span>'); $rootScope.$digest(); expect(element.html()).toBe(''); // FAIL!!! it's still equals to 'Some Content goes here' }); ``` I've seen some answers on SO about using a $timeout function to delay the expect assertion, but whatever I've tried the assertion fails (element.html() is still equals to 'Some content goes here') However, what is funny (is it?) is that if I just alter the dom instead of removing it in my directive, my test is OK : ``` angular.module('app').directive('permissionNeeded', function ($location, $route, SecurityService) { return { restrict: 'A', link: function (scope, element, attributes) { var permissionNeeded = attributes.permissionNeeded; if (permissionNeeded) { if (SecurityService.checkAccess($route.current.name) !== permissionNeeded) { element.html(''); } } } }; }); ``` using the directive above, test is passing. Am I correct when I guess that dom rendering isn't over when I'm making my assertion ? If so, what can I do to delay my assertion after DOM rendering ? Thank you. Mathieu.

Original source