Search code examples
javascriptjqueryunit-testingdomangularjs-directive

How can I check text content with respect to display:none style


I would like to get text content of a DOM node, but without elements that are effectively hidden (have style display:none).

I know about DOM textContent property and jQuery's text() method (I think it uses textContent anyway), but it doesn't respect display:none:

var div = $("<div><span style='display:none'>not </span>good</div>");
var text = div.text(); // "not good"
var textContent = div[0].textContent; // "not good"

How can I get just "good" content from that div?

I need this unit test my AngularJS directive. I am writing tests using Jasmine and my test is something similar to that:

    it('should check text ignoring hidden content', function() {
      $rootScope.hidden = true;
      var template = '<div><span ng-hide="hidden">not </span>good<div>';
      var element = $compile(template)($rootScope);
      $rootScope.$digest();

      console.debug(element.html());    // prints: '<span class="ng-hide" ng-hide="hidden">not </span>good<div></div>'
      console.debug(element.text());    // prints: 'not good'
      expect(element.text()).toEqual('good');   // oops, that fails :(
});

In my real test I want to test my custom directive instead of ng-hide, but the actual directive is irrelvant for that question.

I am completely new to Jasmine and Javascript unit testing, so please also let me know if this is just not the way to go.


Solution

  • A few considerations to keep in mind: you can use clone() to avoid modifying the original object, however to use :visible, the elements have to actually be in the DOM.

    var sample = $("<div><span style='display:none'>not </span>good <div>content</div></div>");
    var t = sample.clone();
    $('body').append(t);
    t.find('*:not(:visible)').remove();
    t.remove();
    alert(t.text());
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>