What is the JavaScript event loop?

I remember the first time I saw a setTimeout( fn, 0 ) call in some React. Luckily there was a comment with the code, so I kind of had an idea of why that code was there. Even with the comment though, it was still confusing. 😉

Since then, I've read several articles about the event loop and got to a point where I was fairly comfortable with my understanding. But, after watching this JSConf talk by Philip Roberts, I feel like I've got a much better understanding.

In the talk, Philip uses a slowed down demonstration of the event loop to explain what's going on to his audience. Philip also demonstrates a tool that he built which allows users to type in code and visualize all of the parts that make JavaScript asynchronous actions work.

You can check out the tool at http://latentflip.com/loupe, but I'd recommend doing it after watching the video.

How to retry Selenium Webdriver tests in Mocha

While working on some functional tests for a hosting provider, I kept running into an issue where the login test was failing due to a 500 error. It appeared as if the site hadn’t been fully provisioned by the time my test was trying to login.

Initially, I attempted adding timeouts to give the installation process more time, but that seemed prone to error as well since the delay was variable. Also, with a timeout, I would’ve had to make the timeout be the longest expected time, and waiting a minute or so in a test suite didn’t seem like a good idea.

Getting it done

You think it’d be a quick fix, right? If this errors, do it again.

Within minutes, I had found a setting in Mocha that allowed retrying a test. So, I happily plugged that in, ran the test suite again, and it failed…

The issue? The JS bindings for Selenium Webdriver work off of promises, so they don’t quite mesh with the built-in test retry logic. And not having dug in to promises much yet, it definitely took me a bit to wrap my head around a solution.

That being said, there are plenty of articles out there that talk about retries with JavaScript promises, which helped bring me up to speed. But, I didn’t find any that were for specifically retrying promises with Selenium Webdriver in a Mocha test suite.

So, I learned from a couple of examples, and came up with a solution that’d work in my Selenium Webdriver Mocha tests.

The Code

You can find a repo with the code and dependencies here, but for convenience, I’m also copying the relevant snippets below:

The retry logic

This function below recursively calls itself, fetching a promise with the test assertions, and decrementing the number of tries each time.

Each time the function is called, a new promise is created. In that promise, we use catch so that we can hook into the errors and decide whether to retry the test or throw the error.

Note: The syntax looks a bit cleaner in ES6 syntax, but I didn’t want to set that up. 😄

var handleRetries = function ( browser, fetchPromise, numRetries ) {
    numRetries = 'undefined' === typeof numRetries
        ? 1
        : numRetries;
    return fetchPromise().catch( function( err ) {
        if ( numRetries > 0 ) {
            return handleRetries( browser, fetchPromise, numRetries - 1 );
        }
        throw err;
    } );
};
The test

The original test, without retries, looked something like this:

test.describe( 'Can fetch URL', function() {
    test.it( 'page contains something', function() {
        var selector = webdriver.By.name( 'ebinnion' ),
            i = 1;
        browser.get( 'https://google.com' );
        return browser.findElement( selector );
    } );
} );

After integrating with the retry logic, it now looks like this:

test.describe( 'Can fetch URL', function() {
    test.it( 'page contains something', function() {
        var selector = webdriver.By.name( 'ebinnion' ),
            i = 1;
        return handleRetries( browser, function() {
            console.log( 'Trying: ' + i++ );
            browser.get( 'https://google.com' );
            return browser.findElement( selector );
        }, 3 );
    } );
} );

Note that the only thing we did different in the test was put the Selenium Webdriver calls (which return a promise) inside a callback that gets called from handleRetries. Putting the calls inside this callback allows us to get a new promise each time we retry.

Comments?

Feel free to leave a comment if you have input or questions. Admittedly, I may not be too much help if it’s a very technical testing question, but I can try.

I’m also glad to accept critical feedback if there’s a better approach. Particular an approach that doesn’t require an external module, although I’m glad to hear of those as well.

Set default node version with NVM

I was recently figuring out how to use nvm, and one thing that stood out to me is that I needed to set the default version of node that I wanted to use when opening a new tab.

Because I was new to using nvm it took me a while to find the commands. So, if you happen to find this article while configuring nvm, hopefully you find this useful.

# Install the version that you would like 
nvm install 6.1.0

# Set 6.1.0 (or another version) as default
nvm alias default 6.1.0

Then you can open a new tab and if you run node -v, you should see v6.1.0 (or whichever version you set as the default.

Easy peasy, right? Hopefully this helps you if you’re having some issues!

Blank Web Page with PhantomJS and CasperJS

Today, I was attempting to debug an issue where some of our functional tests were not running with the new React powered parts of WordPress.com.

As part of the debugging process, I decided to see if the tests would pass when run from my local machine instead of our test server. But, any time I ran a test, the test would fail.

madComputer

An Example Test

Here is part of the test that we use to test the log-in/log-out functionality on WordPress.com

casper.test.begin( 'Can log in to WordPress', function suite( test ) {
    casper.start( 'https://wordpress.com/', function() {
        test.assertExists( '.click-wpcom-login', 'Login link exists on front page when logged out' );
    } );

    casper.run ( function() {
        test.done();
    } );
} );

But, when I run this test, this is the output that I get:

# Can log in to WordPress
FAIL Login link exists on front page when logged out
#    type: assertExists
#    file: logging-in-out.js:3
#    code: test.assertExists( '.click-wpcom-login', 'Login link exists on front page when logged out' );
#    subject: false
#    selector: ".click-wpcom-login"

To debug this test, I dumped the HTML to my terminal and got this: <html><head></head><body></body></html>

The Fix?

After searching a bit, I found this answer.

It seems that there was a mismatch between the version of TLS that WordPress.com uses and the version that PhantomJS uses.

I was able to get my test to work by changing the command to: casperjs test --ssl-protocol=any logging-in-out.js

Perceived Speed and Optimization

I was lucky enough to speak at WordCamp Orlando last December.

My presentation, titled Perceived Speed and Optimization, discussed some examples of improving user experience through optimistic interfaces.

Looking back, I probably should’ve waited a few more months so that I could have come up with more examples and I could’ve talked more in-depth about the subject.

You’ll notice that my talk ends at about 12:30 and the video is over 27 minutes long. My presentation ended up being much quicker than I expected. I was so nervous during this presentation due to the size of the theater as well as the caliber of the audience.

I consider this presentation a learning experience and a push to prepare better next time.

For a better explanation of optimistic interfaces see The Need for Speed: Optimistic Web Interfaces.

JavaScript Masterclass | JSConfUS 2013

This past Friday night, a coworker on Mercury, Enej Bajgoric, shared this video of Angelina Fabbro speaking at JSConfUS 2013.

Based on the title of the video, I was certain that I would come away with a more advanced understanding of closures or some other JavaScript topic.

But, I was pleasantly surprised that the video was non-technical. Instead, Angelina talked about topics such as:

  • What makes a good programmer?
  • What level programmer am I?
  • Are there natural programmers?
  • How to get from intermediate programmer to expert programmer.

The video is just over 22 minutes and, in my opinion, well worth the time it takes to watch.