How do you set up an Optimizely test for a single-page app? - ab-testing

I have a single-page web app that presents a multi-step photo management "wizard", split up across several discrete steps (photo upload, styling, annotation, publishing) via a tab strip. On switching steps I set the URL hash to #publishing-step (or whichever step was activated).
How do I set up Optimizely tests to run on the various discrete steps of the wizard?
The browser never leaves the page, so it only gets a single window.load event. Its DOM isn't getting scrapped or regenerated, but just switches what page elements are visible at any one time via display: none or block, so the part I am trying to figure out is really mostly about in what way I go about the Optimizely test setup itself - it's fine (and likely necessary) if all edits get applied at once.
This thing unfortunately has to work in IE9, so I can't use history.pushState to get pretty discrete urls for each step.

There's actually several ways you could go about doing this, and which option you choose will largely depend on what's easiest for you AND how you plan to analyze the data.
If you want to use Optimizely's analytics dashboard:
I would recommend creating one experiment which will activate a bunch of other experiments at different times. The activation experiment will be targeted to everyone and run immediately when they get to your wizard. The other experiments will be set up with manual activation and triggered by this experiment.
The activation experiment would have code like:
window.optimizely = window.optimizely || [];
function hashChanged() {
if(location.hash === 'publishing-step') {
window.optimizely.push(['activate', 0000000000]);
}
if(location.hash === 'checkout-step') {
window.optimizely.push(['activate', 1111111111]);
}
}
window.addEventListener('hashchange', hashChanged, false);
Or you could call window.optimizely.push(['activate', xxxxxxxxx]); directly from your site's code instead of creating an activation experiment and listening for hashchange.
If you want to use a 3rd party analytics tool like Google Analytics:
You could do this all in one experiment with code similar to above, but in each "if" section instead of activating an experiment, you could run your variation code that makes changes to the wizard and sends special tracking information to your analytics sweet for later reporting. You'll have to do your own statistical significance calculation for this method (as Optimizely's data won't be "clean"), but this method actually works out better usually if properly configured.
Alternatively you could use the method outlined above but still try to use the Optimizely analytics dashboard by creating custom events on your experiment and sending data to them using calls like window.optimizely.push(["trackEvent", "eventName"]);
This article may also be helpful to you.

You'll probably need to do this yourself, using Optimizely's JS API to trigger actions on their end and tell it what your users did: https://www.optimizely.com/docs/api

Related

Maneuver issues in Turn By Turn Navigation with HERE maps in Flutter

Thanks in advance.
We have to use HERE map's Turn by turn navigation feature in one of our Flutter application, we have added billing in the developer account and have created the necessary keys.
When we try HERE map examples they have provided, we get everything except maneuver instructions that shows the user when to turn right/left/go straight for some distance etc.
I'm new to this and I have no idea how to get this, we never get events on the listener and it only shows updating there, am I missing something ?
this is how it looks right now, Updating...
I think we should be getting the progress here, but we are not getting it here...
_visualNavigator.routeProgressListener = Navigation.RouteProgressListener((routeProgress) { }
Please look into the provided example app. It shows here how to get the maneuver actions.
Your screenshot shows a different app, so make sure everything works with the example app, at first. The app offers to run a simulation mode. This should work. If you run the example app with real GPS updates, you may need to go outside and move to get location updates. This should also work.
If this still does not work, it could either mean that your device has an issue with getting GPS locations. Some iPads, for example, lack support. Or that you have disabled getting location updates. You can cross-check this when trying the positioning_app example from the same repository that shows how to get location updates.
A last point may be to clarify what events you get and what you miss: There are multiple event listeners providing real-time information during guidance - if you have only an issue with maneuvers, then most likely you can solve your issue by following strictly the code of the example app.
Note that previous HERE SDK versions, prior to HERE SDK 4.13.0, only provided empty maneuver instruction texts during guidance when they have been taken from the route instance. Make sure to take this information from the VisualNavigator instead.

Setting a value in Frappe application isn't reflected in ERPNext GUI

I have added a 'number_of_members' value to the Customer DocType via customization.
In my application I have tried several ways to update the value. However the value never updates in the webpage. I feel like I'm missing some sort of save or update or commit step.
For example I have tried:
frappe.client.set_value('Customer', '00042', 'number_of_members', 8887)
frappe.set_value('Customer', '00042', 'number_of_members', 8887)
frappe.db.set_value('Customer', '00042', 'number_of_members', 8887)
and also
customer = frappe.get_doc('Customer', '00042')
customer.number_of_members = 8887
customer.save()
In each case I can do something like frappe.get_value, or frappe.get_doc and it shows the value is set to 8887. However it never updates in the web side. This is what makes me think I'm updating some sort of cache or database transaction and I need some way to save it, but have not had any luck.
I am mostly testing this via bench console if that has any bearing on it, but I've tried a couple of the methods in my application code as well.
Relevant documentation:
Frappe Developer API - Document
Frappe Developer API - Database
Turns out the answer is to call frappe.db.commit() after making changes. If someone can point this out in the documentation so I can better understand how I'm missing stuff, I would appreciate it.
I also noticed if you try to Save something in the UI before you send frappe.db.commit() the UI will hang.

Stopping Ember.js Controller

My question is very basic on one hand but on the other hand the general situation is more complex, plus I cannot really get any working sample.
I'm developing/maintaing a web-application which is currently in transition from GWT code base into Ember.js.
Most of the newer code already relies on Ember.js and I think it's really awesome.
The problem is we cannot use Ember Router as all the request are being handled by the GWT.
In order to enabled the application run in this unusual configuration we have special JavaScript files that create our Ember main objects (Controllers & Models) for us.
As you can imagine navigation between tabs is cumbersome and is handled by GWT who creates Ember objects when needed. We are in transit toward a brave new world Ember Router and all.
But in the meantime, this is the problem I'm facing right now.
The user clicks a link which opens a page that contains some Ember based table.
The data is retrieved form the server using some Ajax code. Upon success it spawns a forEach loop which tries to pushObject all the received date into our Ember based components.
My problem happens when the user quickly switches between tabs. In this case the first list of object has not finished rendering yet and suddenly there's a new set of objects to handle. This causes Ember to throw errors like:
"Uncaught Error: Cannot perform operations on a Metamorph that is not in the DOM. "
and
"Uncaught NotFoundError: An attempt was made to reference a Node in a context where it does not exist."
Is it possible to prevent the loop from trying to render?
I've tried checking if the controller in question is already inDOM and it is, is there a way to notify Ember this object is no longer valid?
Sorry for a lengthy question and lack of running sample.
I'd probably modify the switch tab code to only execute afterRender has completed, that way you aren't mucking with ember objects while they are being used.
Ember.run.scheduleOnce('afterRender', this, function(){
// call GWT switch tab routine
});
Thank you Daniel and Márcio Rodrigues Correa Júnior. eventually what I did is to add a patch that would check the current context of the application (in my case the currently selected tab). If upon receiving the AJAX response the application is in the correct context (meaning the user haven't change the tab) go on. Otherwise just ignore the response and do not try to render it.
Now it seems to be working

Testing with dual UI's

I have a browser based test program for testing a browser based application. This means that I need to record sequences that alternately manipulate the test program and then the application to check that it reacts correctly, so that I can perform automated testing.
How should I do this with SAHI?
I cannot see a way of recording two separate URL's concurrently. I have tried combining the two UI's using frames, and iframes, but I couldn't get SAHI to record in the frame/iframe.
I could modify the test program so that I can call it from scripts called by SAHI, but that rather defeats the object of having an automation tool...
Any suggestions?
1) Record the actions on the first web page using Sahi (script1)
2) Record the actions on the second web page (script2)
3) In script1, do this
// do steps for UI 1 as recorded in script1
_call(window.open("second url", "newWindow")); // open the second window
_selectWindow("newWindow"); // target the following steps on newWindow
// copy steps from script2 here
_selectWindow(); // return to base window
// perform further base window steps
// Use _selectWindow("newWindow") and _selectWindow() to switch between windows.
Hope this helps.
Regards,

how can I improve iPhone UI Automation?

I was googling a lot in order to find a solution for my problems with UI Automation. I found a post that nice summarizes the issues:
There's no way to run tests from the command line.(...)
There's no way to set up or reset state. (...)
Part of the previous problem is that UI Automation has no concept of discrete tests. (...)
There's no way to programmatically retrieve the results of the test run. (...)
source: https://content.pivotal.io/blog/iphone-ui-automation-tests-a-decent-start
Problem no. 3 can be solved with jasmine (https://github.com/pivotal/jasmine-iphone)
How about other problems? Have there been any improvements introduced since that post (July 20, 2010)?
And one more problem: is it true that the only existing method for selecting a particular UI element is adding an accessibility label in the application source code?
While UI Automation has improved since that post was made, the improvements that I've seen have all been related to reliability rather than new functionality.
He brings up good points about some of the issues with using UI Automation for more serious testing. If you read the comments later on, there's a significant amount of discussion about ways to address these issues.
The topic of running tests from the command line is discussed in this question, where a potential solution is hinted at in the Apple Developer Forums. I've not tried this myself.
You can export the results of a test after it is run, which you could parse offline.
Finally, in regards to your last question, you can address UI elements without assigning them an accessibility label. Many common UIKit controls are accessible by default, so you can already target them by name. Otherwise, you can pick out views from their location in the display hierarchy, like in the following example:
var tableView = mainWindow.tableViews()[0];
As always, if there's something missing from the UI Automation tool that is important to you, file an enhancement request so that it might find its way into the next version of the SDK.
Have you tried IMAT? https://code.intuit.com/sf/sfmain/do/viewProject/projects.ginsu . It uses the native javascript sdk that Apple provides and can be triggered via command line or Instruments.
In response to each of your questions:
There's no way to run tests from the command line.(...)
Apple now provides this. With IMAT, you can kick off tests via command line or via Instruments. Before Apple provided the command line interface, we were using AppleScript to bring up Instruments and then kick off the tests - nasty.
There's no way to set up or reset state. (...)
Check out this state diagram: https://code.intuit.com/sf/wiki/do/viewPage/projects.ginsu/wiki/RecoveringFromTestFailures
Part of the previous problem is that UI Automation has no concept of discrete tests. (...)
Agreed. Both IMAT and tuneup.js (https://github.com/alexvollmer/tuneup_js#readme) allow for this.
There's no way to programmatically retrieve the results of the test run. (...)
Reading the trailing plist file is not trivial. IMAT provides a jUnit like report after a test run by reading the plist file and this is picked up by my CI Tool (Teamcity, Jenkins, CruiseControl)
Check out http://lemonjar.com/blog/?p=69
It talks about how to run UIA from the command line
Try to check the element hierarchy, the table can be placed over a UIScrollView.
var tableV = mainWindowTarget.scrollViews()[0].tableViews()[0].scrollToElementWithName("Name of element inside the cell");
the above script will work even the element is in 12th cell(but the name should be exactly the same as mentioned inside the cell)