Reputation: 3003
I'm writing tests for a directive that basically expand over it's container to reach the full width of the browser window.
To exemplify this I'll write some sample code.
HTML in the page:
<div style="width: 800px; margin: 0 auto;">
<full-width></full-width>
</div>
The directive then replace the fullWidth
directive with:
<div class="full-width">
<div ng-transclude=""></div>
</div>
And assign margins to the element, like this:
var sideOffset = element[0].offsetLeft*-1;
element.css('margin-left', sideOffset+'px')
element.css('margin-right', sideOffset+'px')
Now, the directive works perfectly fine, but when I try to test the offset with:
describe('Directive: fullWidth', function () {
beforeEach(module('myApp'))
var element,
scope
beforeEach(inject(function ($rootScope) {
scope = $rootScope.$new()
}))
it('should have the same right and left margin', inject(function ($compile) {
element = angular.element('<tt-full-width-section></tt-full-width-section>');
element = $compile(element)(scope)
var leftMargin = element.css('margin-left')
console.log(leftMargin)
console.log(element)
}))
})
I get a nice 0px
. Also inspecting the logged element[0].offsetLeft
results in 0.
Any idea on how can I (if possible) tell Karma (Jasmine?) to render the div so I can check the offset?
Based on daveoncode suggestion, I made some changes to the test, and we're improving.
However, the directive doesn't seems to work in the test.
I still get 0px as margin-left
while having 265px of offsetLeft
it('should have the same right and left margin', inject(function ($compile) {
element = angular.element(
' <div style="width:50%; margin: 0 auto;">' +
' <full-width></full-width>' +
' </div>'
);
element = $compile(element)(scope)
angular.element(document).find('body').append(element);
var el2 = element.find('div')
var leftMargin = el2.css('margin-left')
var rightMargin = el2.css('margin-right')
console.log(leftMargin, el2)
}
Upvotes: 5
Views: 4028
Reputation: 19578
TIP 1:
CSS styles are not applied to elements until they get added to the DOM! and this is not an issue related to karma, angular, jasmine or what else... this is how a browser engine works! A browser parses CSS definitions and it renders elements in the page according, but when in angular test you write:
var element = angular.element('<my-directive></my-directive>');
$compile(element)(scope);
You are dealing with in-memory DOM nodes, which are unknown to all but your JavaScript code! How should the browser engine apply CSS to an in-memory node living in a js variable? It can't obviously... it can only traverse the nodes tree in the page, so... the "fix" is very simple: you have to add the element to the DOM:
angular.element(document).find('body').append(element);
TIP 2:
Ok, I think that now your problem is actually another one, you are using jQlite .css() implementation, which differently from the jQuery one does not retrieve the computed style but only the inline one (hence I fear that is not able to "translate" auto
to the actual number of pixels!)... Try to use this snippet to retrieve the computed margin left:
window.getComputedStyle(element, null).marginLeft
(getComputedStyle should work for each browser except IE, so if you are testing using PhantomJS it's ok)
Upvotes: 10