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.
genericJavascript
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.
genericJavascriptSetupAndCheckLater
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": "window.aaa = true;", "verificationScript": "return window.aaa;", "delay": 1000 }
The first script sets window.aaa = true
, then the test waits 1 second, then the second script returns the value of window.aaa
(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.
genericJavascriptCascade
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.
2 thoughts on “More tests, more fun”