Karma - incorrect ui div properties when unit testing Angular JS directive

I am writing tests for a directive that basically extend its container to achieve the full width of the browser window.

To illustrate this, I will write some code examples.

HTML on page:

<div style="width: 800px; margin: 0 auto;"> <full-width></full-width> </div> 

Directive then replace the fullWidth directive with:

 <div class="full-width"> <div ng-transclude=""></div> </div> 

And assign the fields to the element, for example:

 var sideOffset = element[0].offsetLeft*-1; element.css('margin-left', sideOffset+'px') element.css('margin-right', sideOffset+'px') 


Now the directive works fine, but when I try to check 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 . In addition, checking the registered element[0].offsetLeft results at 0.

Any idea on how I can (if possible) tell Karma (Jasmine?) To display a div so that I can check the offset?


Based on the daveoncode proposal , I made some changes to the test, and we are improving. However, the directive does not seem to work in the test.
I still get 0px as margin-left , having 265px 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) } 
+5
source share
1 answer

TIP 1:

CSS styles do not apply to elements until they are added to the DOM! and that’s not a problem with karma, angular, jasmine or anything else ... that’s how the browser engine works! The browser parses the CSS definitions and displays the elements on the page according to, but when in the angular test you write:

 var element = angular.element('<my-directive></my-directive>'); $compile(element)(scope); 

You are dealing with DOM nodes in memory that are unknown to everyone except your JavaScript code! How does a browser engine apply CSS to node embedded memory living in js variable? This may not be obvious ... it can only cross the node tree on the page, so ... "Fix" is very simple: you have to add the element to the DOM:

 angular.element(document).find('body').append(element); 

TIP 2:

Well, I think that now your problem is actually different, you are using the jQlite.css () implementation, which, other than jQuery, does not extract the computed style, but only the built-in (therefore, I'm afraid it is not) capable of " translate " auto to the actual number of pixels!) ... Try using this snippet to get the calculated margin on the left:

 window.getComputedStyle(element, null).marginLeft 

(getComputedStyle should work for every browser except IE, so if you are testing using PhantomJS, this is normal)

+10
source

Source: https://habr.com/ru/post/1202238/


All Articles