CSS issue testing AngularJS directives with Karma + Jasmine

All we need is an easy explanation of the problem, so here it is.

I’m using Karma + Jasmine to test my AngularJS directives, I wrote more than 300 tests and I was very happy… until I found an issue that taken me here because I’m stuck: some tests are failing because they need a CSS applied to some elements (a piece of code in my directive does a size computation based on this style), and despite I added the file containing the CSS implementation, this file seems ignored during tests.
In my karma config I added the css file in this way:

files: [
     // ..
     // ..

the settings above generates a link tag in the body rather than head, so I tried to inject the CSS “manually” using js:

        '<style type="text/css">@charset "UTF-8";' +

but neither this approach seems to work (I tested and the style tag gets injected correctly).
I finally tried to add a block of style among the html that I compile using angular $compile:

var element = ng.element('<div>' +
'<style type="text/css">@charset "UTF-8";' +
            '/* THE STYLE I NEED FOR MY TESTS HERE */' +
            '</style>' +
'<my-directive></my-directive>' +
+ '</div>');

…but still no lucky… I also tried to switch the test runner from PhantomJS to Chrome, but the problem is the same: styles are somehow ignored (they are injected but they don’t get applied to elements, in fact using jQuery(targetElement).css('width') it returns 0)…

so, my big question: how should I import and successfully apply stylesheet in karma tests??? ๐Ÿ™

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Ok, the problem is very simple and stupid… I wonder why I lost so much time to realize it ๐Ÿ˜›
So… the CSS are perfectly injected by Karma by specifying them in the config file, like I’ve done as the first approach (there is no need for other plugin or black magic), but… 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 I write:

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

I’m dealing with in-memory DOM nodes, which are unknown to all but my 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: I have to add the element to the DOM:


Method 2

From the sounds of your situation, you’re looking to test if the DOM is in a certain state. I found a plugin that looks like it was designed with this use case in mind: jasmine-jquery. Even though you’re using AngularJs for your DOM manipulation, this extension will still let you test the resultant DOM’s state.

In particular I think you should have a look at the StyleSheet Fixtures which lets you inject CSS in to the test.

Disclaimer: I haven’t tested any of this yet, the answer is just the result of research.

Note: Use and implement method 1 because this method fully tested our system.
Thank you ๐Ÿ™‚

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply