
Creating A/B tests is a lot of fun, and the excitement is compounded by the value your company can get out of a successful testing program. Our team gets to work on a lot of A/B tests across multiple tools and multiple web stacks. Which means that we’ve seen a few cases where things can go sideways…
One of the tools that we use is VWO. We use it to build everything from simple A/B tests to multivariate tests. They have great resources available for beginners and advanced users, but if you have any questions feel free to leave us a note in the comments :).
Building tests for static sites is fairly simple using their platform. If you’re trying to run tests behind authentication, we use a few tricks – like applying classes on the body element and conditionally hiding elements based on the authentication state.
Most recently we were working on some tests in VWO for Forks Over Knives, the organization behind the award winning Forks Over Knives documentary launched in 2011, and ran into some interesting issues. One of their products, the ForksMealsPlanner.com uses Angular. AngularJS is a framework backed by Google and used by thousands of developers. It’s known for it’s dependency injection and follows the MVW methodology.
Here’s what we learned about VWO and Angular JS
VWO has one article on using VWO with single page apps. The key takeaway from that article is the executeTrackingCode function that accepts a hidden element as a parameter.
1. Use the executeTrackingCode function
Depending on whether or not your application changes the URL will determine which snippet you use. The application we were working with did not actually change the URL – only routes within the application. For example, http://www.example.com/#!/home and http://www.example.com/#!/pricing
https://gist.github.com/irkanu/803e85f78d67624bf43bfa3990665dc8
This means we had to set a new virtual page URL for each route and execute the function in that route’s controller. (Do you have an application like this and are having trouble implementing VWO? Let us know. If you’re determined to fix it yourself, then keep reading!)
2. setInterval({ /* VWO Code */ }, 100)
VWO’s support team was very helpful when it came to understanding how to work around Angular’s DOM injection replacing our VWO test code. Basically, VWO fires it’s code, then AngularJS was injecting it’s DOM causing us to see conflicting results on different routes. See this code snippet as an example:
https://gist.github.com/irkanu/6ab0d0f09a87889ba4c9717941615a8d
If you are wondering where you should be adding this code, then check out this screenshot below:

How to add custom code to VWO test.
3. ng-if vs. ng-show
The last tip isn’t focused specifically on VWO, but instead highlights a potential issue with using ng-if on an element you are testing. For example, imagine you have a pricing table that shows a price monthly or annually based on another element – think a switch.

An example of an AngularJS switch where the state is changed from the controller.
Depending on the code in your controller, you might display the monthly price or annual price. This works great in practice, but it will immediately overwrite any changes you make in VWO on those elements.
A better alternative is to use ng-show, so VWO can replace the elements in the DOM without AngularJS overwriting any of that. By default, ng-show will toggle the display of the element rather than injecting the value; this is a much better fit for our needs.
Check out this example from a live application:

An example of the same switch using ng-if instead of ng-show.
Notice how we are binding the state of the input to the vm.plan_type model. This state is modified from the controller using ng-change=”vm.changePlan()”. Now using ngIf, the state of the switch is synced with the DOM instead of having it injected dynamically via ngShow which causes issues when building the tests.
If none of these tips helped fix your AngularJS testing issues, then please don’t hesitate to contact us. We’d love to help.
Leave a Reply