Search code examples
unit-testingmocha.jskarma-mocha

Mocha / Karma - how to test CSS properties


The angular directive that I am responsible for testing manipulates much of the css with click handlers. Also, it adds the css styles inside of the element.

 angular.element(dropDown).css({display: 'block'});

I have referenced another stack overflow post Testing whether certain elements are visible or not

I changed toBe to .to.be for mocha. I also tried to check for a attribute to be added on the click. Here are my expects listed below.

expect(elem('.dropdown-menu').css('display')).to.be('none');
expect(elem.getAttribute('display')).to.be('block');  

However, I am getting

[[object HTMLUListElement]]' is not a function 
TypeError: elem.getAttribute is not a function

I know it would be easier not have the css in the directive like so, but am wondering if anyone has tested for this or knows how to debug these?


Solution

  • What is elem in the context of your spec? Is that the $compiled directive?

    What does your beforeEach look like?

    What does the internal implementation of dropDown look like?


    This is how I test my directives:

    describe('directive', function () {
      var el, $scope; 
    
      beforeEach(function () {
        module('my.mod');
    
        inject(function ($compile, $rootScope) {
          $scope = $rootScope.$new();
          el     = $compile('<some-custom-dir></some-custom-dir>')($scope);
    
          $scope.$digest();
          // or if isolated $scope: 
          el.isolateScope().$digest();
        });
      });
    
      it('some css property', function () {
        expect(el.css('display')).to.eq('block');
      });
    
      it('some attribute', function () {
        expect(el[0].getAttribute('something')); // You need to unwrap the angular.element(el) with [0] to access the native methods. 
      });
    
      it('some other attribute', function () {
        expect(el.attr('someAttr')).to.eq('...'); // Or just use .attr()
      });
    });
    

    Also, to.be cannot be used that way. You can use to.be in the following ways:

    .to.be.true; 
    .to.be.false;
    .to.be.null;
    .to.be.undefined;
    .to.be.empty;
    .to.be.arguments;
    .to.be.ok;
    .to.be.above();
    .to.be.a(Type);
    .to.be.an(Type);
    .to.be.closeTo(min, max); // delta range
    .to.be.instanceOf(Constructor);
    .to.be.within(min, max);
    .to.be.at.most(max);
    .to.be.below(max);
    .to.be.at.least(min);
    .to.be.above(min);
    

    What you are looking for is the .to.eq or .to.equal method.

    expect('asdf').to.be('asdf'); // Nope!
    expect('qwer').to.eq('qwer'); // Yay!
    
    expect([]).to.eq([]);         // Nope..
    expect([]).to.deep.equal([]); // Yay!
    
    expect({}).to.eq({});  // Nope..
    expect({}).to.eql({}); // Yay!