More tests, more fun

Since the Summits, there has been some interest in the test framework I keep flogging on this blog, and rightfully so, imnsho!

They say that no plan survives first contact with reality, and the same is true for those who have started to use the framework. It is amazing how much abstraction goes on in a human brain when we learn about something, and how much that shapes how we try to approach using it.

Long story short: I have added two tests that should help with more complex scenarios, such as visitor interaction, and SPAs. The two take the idea of the genericJavascript test case and take it a bit further.

This post shall describe this and the two other tests in a bit more detail.


The genericJavascript case can inject any Javascript into a page. The code should return a boolean value, i.e. true or false, and the test will pass on the former and fail on the latter.

The example I use in the documentation on github is extremely simple:

"genericJavascript": "return true;"

Not surprisingly, this test would work every time.

On the test site I made for the labs, I use a slightly more complex test:

"genericJavascript": "document.getElementById('numbooks').value = 3;document.getElementsByClassName('button')[0].click();return digitalData.cart.item[0].productInfo.sku == 'je0001' && digitalData.cart.item[0].quantity == 3 && digitalData.cart.price.cartTotal == 199.97"

This test loads my test page, sets the number of books to buy to 3, clicks the “Add to Cart” button, then checks whether the data layer reflects the action, quantity and price.

When I built this test, I presumed it would mainly be used as a temporary, stop gap kind of test, meaning that if someone used it, they’d eventually create a proper test instead.

In my case the test would have been called something like setQuantityThenAddToCartAndVerifyDataLayerElementValuesDelayed and have 4 parameters.

What do you mean, that’s just silly?

Ok, maybe it is.

Turns out that the genericJavascript test is pretty popular, due to its flexibility. But there is one, big flaw.


If you want to load a page, trigger something in it, wait a moment, then check some result, you will notice that Javascript is not a multi-threaded language. There is no way to write a test like that with the genericJavascript test! You cannot wait in Javascript and have the browser do something at the ame time.

Enter genericJavascriptSetupAndCheckLater.

You can feed this test two snippets of Javascript code. It will inject the first, then wait for a defined time, then inject the second and check the (boolean) result.

As an example:

"genericJavascriptSetupAndCheckLater": { "setupScript": " = true;", "verificationScript": "return;", "delay": 1000 }

The first script sets = true, then the test waits 1 second, then the second script returns the value of (which is true, of course). This test, too, will always succeed.

The trick is that instead of waiting in the Javascript code, the test handles the wait independently, and lets the browser soldier on while it does so.

Cool, right?

I went one step further.


First, I have to apologise for the name of this one, but hey.

The test can take an arbitrary number of scripts, a verification script, plus a delay. Like genericJavascriptSetupAndCheckLater, it’ll inject all the snippets, one by one, waiting between each snippet. At the very end, it’ll inject the verification script and check the (again boolean) result.

Here’s the example:

"genericJavascriptCascade": { "scripts": [ "window.aaa1 = 1;", "window.aaa2 = 2;" ], "verificationsScript": "return (window.aaa1 + window.aaa2 == 3);", 500 }

This test injects two scripts, both setting Javascript variables. The verification then adds them up and checks the value. There’s a 500ms delay between each of these steps.

So, this test allows you to drive some pretty complex scenarios, including a check out funnel, or even testing aspects of an SPA.

I’m sure there are limitations, there always are.

But this framework is alive, it grows, and it hopefully becomes more useful each time something is added.

Next stop: the ability to stop the actual tracking requests. For that I need a built-in proxy, and that beast is still putting up quite a fight. Stay tuned.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s