Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test for visible in QUnit test of JQueryUI widget

This may be obvious to everyone else but I didn't find it by searching, so posting both the question and one possible answer here.

Background:

  1. Custom JQuery UI widget using widget factory
  2. In the widget, some elements get hidden or shown based on other data/options.
  3. Creating unit tests to verify they are being shown/hidden correctly.
  4. I thought that my unit tests could each create their own element in memory, similar to this old answer.

Stripped out the actual widget part from this example:

test( 'show/hide', 1, function() {
    var somecondition = true;

    var div = $( '<div/>' ).hide();
    if (somecondition) div.show();

    equal( somecondition, div.is( ":visible" ) );
});

The test fails because jQuery always reports div.is( ":visible" ) as false. I thought that using div.css('display') == 'none' would be a workaround. Unfortunately, this worked in Chrome but not Firefox.

like image 747
explunit Avatar asked Apr 16 '13 21:04

explunit


1 Answers

The problem was that jQuery is smart enough to know that even if a particular element has said it's visible, it might not actually be visible if (for example):

  1. It was never added to the DOM
  2. The DOM element (or parent/grandparent/etc) it was appended to is not actually visible

So in order for the unit tests to work, I need to have a real div in the test harness html, attach the widget to it, and then call a destroy at the end.

test( 'show/hide', 1, function() {
    var somecondition = true;

    var div = $( '#someid' ).hide();
    if (somecondition) div.show();

    equal( somecondition, div.is( ":visible" ) );
});

I was hoping for a different approach (and maybe someone will come along and provide another answer), but I'm not very hopeful, seeing as this is the approach that JQueryUI uses in their own QUnit tests:

test( "search, close", function() {
    //SNIP
    // Note the use of a real element here:
    element = $( "#autocomplete" ).autocomplete({
        source: data,
        minLength: 0
    }),
    menu = element.autocomplete( "widget" );
    //SNIP
    ok( menu.is( ":visible" ), "menu is visible after search" );
    //SNIP
});
like image 127
explunit Avatar answered Oct 18 '22 09:10

explunit