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)
}
Karma handles the process of creating HTML files, opening browsers and running tests and returning the results of those tests to the command line. If you use the Angular CLI to manage projects it automatically creates stub Jasmine spec files for you when generating code.
Jasmine is a behavior-driven development framework for testing JavaScript code. It does not depend on any other JavaScript frameworks. It does not require a DOM. And it has a clean, obvious syntax so that you can easily write tests. Karma is a test runner that fits all our needs in the angular framework.
Testing in AngularJS is achieved by using the karma framework, a framework which has been developed by Google itself. The karma framework is installed using the node package manager. The key modules which are required to be installed for basic testing are karma, karma-chrome-launcher ,karma-jasmine, and karma-cli.
Jasmine is a JavaScript testing framework and Karma is a node-based testing tool for JavaScript codes across multiple real browsers.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With