I have tried and tested - with success - the phantomjs example waitFor. However, I am having difficulty implementing it via the phantomjs-node module primarily because page.evaluate gets evaluated in a callback.
PhantomJS Implementation
page.open("http://twitter.com/#!/sencha", function () {
    waitFor(function() {
        // This here is easy to do as the evaluate method returns immediately
        return page.evaluate(function() {
            return $("#signin-dropdown").is(":visible");
        });
    }, function() {
       console.log("The sign-in dialog should be visible now.");
       phantom.exit();
    });
  }
});
However, with phantomjs-node the evaluate function gets returned data in a callback:
page.evaluate(
    function(){ /* return thing */ },
    function callback(thing) {  /* write code for thing */ }
)
Using phantomjs-node, how can I run a function on the page only after an element is visible?
Just in case the link above is dead, here is the implementation of the waitFor function
/**
* Wait until the test condition is true or a timeout occurs. Useful for waiting
* on a server response or for a ui change (fadeIn, etc.) to occur.
*
* @param testFx javascript condition that evaluates to a boolean,
* it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
* as a callback function.
* @param onReady what to do when testFx condition is fulfilled,
* it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or
* as a callback function.
* @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used.
*/
function waitFor(testFx, onReady, timeOutMillis) {
var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000, //< Default Max Timout is 3s
    start = new Date().getTime(),
    condition = false,
    interval = setInterval(function() {
        if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) {
            // If not time-out yet and condition not yet fulfilled
            condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //<    defensive code
        } else {
            if(!condition) {
                // If condition still not fulfilled (timeout but condition is 'false')
                console.log("'waitFor()' timeout");
                phantom.exit(1);
            } else {
                // Condition fulfilled (timeout and/or condition is 'true')
                console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms.");
                typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled
                clearInterval(interval); //< Stop this interval
            }
        }
    }, 250); //< repeat check every 250ms
};
Thanks in advance.