Following this question I'm using the following method to try to test whether ng-if tagged divs are displaying correctly using Karma, rather than Protractor:
var element;
beforeEach(inject(function ($rootScope, $templateCache, $compile) {
scope = $rootScope.new();
fooController.init(scope); //Some controller function that sets properties on the scope
//which are tested for in the template
scope.$digest();
var template = $templateCache.get('/my/template'); //Get the cached template
var compiled = compile(template)(scope); //Compile it
element = angular.element(compiled); //Wrap it with jQuery functions
}));
it('should do something', function () {
var div = element.find('#someDiv'); //Get some div that should be affected by ng-if
expect(div.html()).toBeUndefined(); //Expect the div not to be shown due to properties that
//were set by fooController.init
});
My template has something like this:
<!-- scope.shown should be set to false by fooController.init -->
<div id = "someDiv" ng-if = "shown">Foo</div>
Here, I'm using expect(div.html()).toBeUndefined();
because ngIf (unlike ngShow and ngHide) removes the entire div from the DOM if the condition inside evaluates to false (ngShow and ngHide apply classes to the div to cause it not to be shown instead).
However, when I run this and print out the compiled variable, I find that the HTML of the ngIf div is ALWAYS taken away and replaced with a comment, regardless of the value of scope.shown.
Does the Angular compile function used by Karma not work the same way as it does when it's actually rendered by Angular itself in a browser? I ask because when I test it with a browser, it displays correctly, but when I try to unit test it, it outputs the wrong info. Maybe it's also because I'm using PhantomJS for headless testing, but Google Chrome to test it myself?