Inspired by this particular question, I have implemented a method to test the correct display of ng-if tagged divs using Karma instead of Protractor:
var element;
beforeEach(inject(function ($rootScope, $templateCache, $compile) {
scope = $rootScope.new();
fooController.init(scope); //A controller function that sets properties on the scope
//which are tested in the template
scope.$digest();
var template = $templateCache.get('/my/template'); //Fetching the cached template
var compiled = compile(template)(scope); //Compiling it
element = angular.element(compiled); //Wrapping it with jQuery functions
}));
it('should perform some action', function () {
var div = element.find('#someDiv'); //Finding a relevant div affected by ng-if
expect(div.html()).toBeUndefined(); //Expecting the div not to be displayed due to previously set properties
});
This is what my template looks like:
<!-- The value of scope.shown should be set to false by fooController.init -->
<div id="someDiv" ng-if="shown">Foo</div>
By using
expect(div.html()).toBeUndefined();
, I'm noting that ngIf removes the entire div from the DOM if the inner condition evaluates to false, different from ngShow and ngHide which apply classes for visibility.
However, upon running this and examining the compiled object, I observed that regardless of the scope.shown value, the HTML content within the ngIf div gets replaced with a comment.
Could it be that the Angular compilation function used by Karma behaves differently compared to how Angular renders it in a browser? My observation is that in browser testing, everything seems fine but unit testing outputs incorrect information. Maybe this discrepancy relates to utilizing PhantomJS for headless tests as opposed to Google Chrome for manual checks?