Darren Sweeney February 2016

Jasmine - wait for fadeOut() to finish

I have a simple function which fades in an element:

CODE

checkLengthSelect: function(){
    if($(this).val() != ''){ // if not empty
        $('.c--error').fadeOut('fast', function(){
            $('#button').fadeIn();
        })
    } else { // if empty hide button and show error message
        $('#button').fadeOut('fast', function(){
            $('.c--error').html('foo').fadeIn(); // <-- I want to test this on fadeOut callback
        })
    }
},

I'm trying to write a test for it like this:

TEST

it("it should have a value or hide continue button", function(){

    // check cover length on select
    $(document).on('change', '#select', function(){ qqw.validate.checkLengthSelect.call(this) } );

    // force a change event to fire with empty value.
    $('#select').val('').change();

    setTimeout(function(){
        expect($('.c--error').html()).toEqual('foo');   
        done(); // <-- test if done
    }, 800);

});

ERROR

This shows in console

'expect' was used when there was no current spec, this could be because an asynchronous test timed out

QUESTION

How can I test that an event happens when the fadeOut completes?

I'm using Jasmine v2+

Answers


Jake Cobb February 2016

Jasmine 1.3

You can use waitsFor to wait for the condition or fail after a timeout:

waitsFor(function() {
  return $('.c--error').html() == 'foo';
}, "Error was never set to 'foo'", 800);

Jasmine 2.0

For Jasmine 2.0, you can simulate the same behavior:

describe("stackoverflow test", function() {
    var originalTimeout;
    beforeEach(function() {
      originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
      jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
    });

    it("it should have a value or hide continue button", function(done) {

        // check cover length on select
        $(document).on('change', '#select', function(){ checkLengthSelect.call(this) } );

        // force a change event to fire with empty value.
        $('#select').val('').change();

        var POLL_TIME = 10;
        var endTime = new Date().getTime() + 5000;

        var checkCondition = function() {
            if (new Date().getTime() <= endTime && $('.c--error').html() != 'foo') {
                setTimeout(checkCondition, POLL_TIME);
            } else {
                expect($('.c--error').html()).toEqual('foo');  
                done();
            }
        };
        checkCondition();
    });

    afterEach(function() {
      jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
    });
});

You need to increase the async timeout to keep the test from failing. Adjust POLL_TIME or the amount added to the current date to change that behavior. I should also note that your current code will not hit the correct branch of checkLengthSelect so the test will fail, I flipped the condition on that branch in my testing to make sure the Jasmine part of this works as expected.


Dave Bush February 2016

use

jasmine.clock().tick(801);

to advance the timer.

http://jasmine.github.io/2.4/introduction.html

Post Status

Asked in February 2016
Viewed 2,295 times
Voted 6
Answered 2 times

Search




Leave an answer