michael salmon michael salmon - 6 months ago 34
AngularJS Question

CSS selector not finding dom elements in Angular unit testing w/karma & chai

I have a directive under test which I want to verify has a few specific elements with class attributes. When testing with karma + chai, I am only able to select with element.find actual dom elements (i.e. div). Using element.find to locate by class or ID fails. Can someone illuminate me what api to use in this case?

Here's the unit test

var expect = chai.expect;
var assert = chai.assert;
beforeEach(module('blah'));
beforeEach(module('mytemplates')); // for ng-html2js

describe('Testing notifications directive', function() {
var scope, elem, directive;

var html = '<notifications></notifications>';
var rendered;
beforeEach(function(){
inject(function($compile, $rootScope) {
elem = angular.element(html);
scope = $rootScope.$new();
scope.notificationList =_notificationsspecmockdata;
rendered = $compile(elem)(scope);
scope.$digest();
});
});

it('should render a notifications element', function() {
console.log(elem);
console.log(elem.find('.close-icon'))
console.log('------------------');
console.log(rendered);
console.log(rendered.find('.close-icon'))
console.log('------------------');
console.log(elem.find('div').length);

expect(elem.find('div').length).to.eql(6); // works
});
});


And the output. As you can see the dom elements do exist there with the class I'm looking for.

Object{0: <li id="notificationdropdown" class="notification-dropdown hidden-xs hidden-sm">
<a href="#" class="trigger">
<i class="icon-warning-sign"></i>
<span class="count ng-binding"></span>
</a>
<div class="pop-dialog">
<div class="pointer right">
<div class="arrow"></div>
<div class="arrow_border"></div>
</div>
<div class="body">
<a href="#" class="close-icon"><i class="icon-remove-sign"></i></a>
<div class="notifications">
<h3 class="ng-binding">You have 0
notifications</h3>
<!-- ngRepeat: table in problemTables -->

</div>
</div>
</div>
</li>, length: 1}
LOG: Object{}
LOG: '------------------'
LOG: Object{0: <li id="notificationdropdown" class="notification-dropdown hidden-xs hidden-sm">
<a href="#" class="trigger">
<i class="icon-warning-sign"></i>
<span class="count ng-binding"></span>
</a>
<div class="pop-dialog">
<div class="pointer right">
<div class="arrow"></div>
<div class="arrow_border"></div>
</div>
<div class="body">
<a href="#" class="close-icon"><i class="icon-remove-sign"></i></a>
<div class="notifications">
<h3 class="ng-binding">You have 0
notifications</h3>
<!-- ngRepeat: table in problemTables -->

</div>
</div>
</div>
</li>, length: 1}
LOG: Object{}
LOG: '------------------'
LOG: 6

Answer

Use document.querySelector().

Returns the first element within the document (using depth-first pre-order traversal of the document's nodes) that matches the specified group of selectors.

To select a class/ID in the test, do ...

element[0].querySelector('.klass');
element[0].querySelector('#ID');

Also, as @Brett Caswell stated in the comment to select all elements of the same class, use document.querySelectorAll()