Search code examples
javascriptinternleadfoot

Leadfoot's pollUntil() Not Triggering on Variable Value Change?


I currently am writing functional tests in Intern and have run across a small issue.

During the before portion of my test suite, I make an ajax call to an API to retrieve a variable's value. This variable being set is critical to the next step in the functional test, and therefore I want to halt the test until the variable is returned from the ajax call.

I read about Leadfoot's pollUntil() function and it sounded like it did what I needed to do. I wrote the following code:

var valueThatChanges = 0;

// ... (some functional test setup stuff)

//Ajax call that sets value of valueThatChanges
.then(function() {
    return ajaxCall(valueThatChanges);
})

//valueThatChanges is initially 0 before/during ajax call
//Is set to a randomly generated value that is non-zero after response recieved
.then(pollUntil(function(valueThatChanges) {
        return valueThatChanges !== 0 ? true : null;
    },[valueThatChanges], 30000, 100))

    .then(function() { //On success
        console.log('Value is no longer zero.')
    }, function(error) { //On failure/timeout
        console.log(error)
    })
});

However this does not work as the function enters the success callback instantly despite the value of valueThatChanges still being 0.

I understand that pollUntil() may not designed to handle situations like this (since I am not directly dealing with DOM elements in the pollUntil), but I am not sure why it does not work for this specific scenario.

It seems as though pollUntil() is not passing the updated variable on each call of it's polling function.

Can pollUntil() handle triggering an event on a change of variable value?


Solution

  • The general use case for pollUntil is a situation where you need to wait for something to happen in the remote browser. For example, pollUntil is often used to wait for a functional test page to fully initialize:

    // ---------------------
    // functional test (in Node.js)
    this.remote.get('testpage.html')
        .then(pollUntil('return window.pageIsReady ? true : null'))
        // rest of test
    
    // ---------------------
    // remote test page (in the browser)
    <script>
        var pageIsReady = false;
        require( ..., function ( ... ) {
            // do setup stuff
            pageIsReady = true;
        });
    </script>
    

    If you're doing some bit of async stuff in your test setup that doesn't involve the browser, return a Promise from the before function in your test suite that will resolve when the async action is complete.

    var valueThatChanges;
    
    registerSuite({
        before: function () {
            return new Promise(function (resolve) {
                // Assuming ajaxCall calls a callback when it's finished:
                ajaxCall(function (newValue) {
                    valueThatChanges = newValue;
                    resolve();
                });
            });
        },
    
        test1: function () {
            return this.remote
                // rest of test
        },
    
        // ...
    });