This blog post was originally posted by Seth Urban on Prototest’s blog here. ProtoTest is a mobile app test lab that blends UX and QA in a holistic way. Based in Denver, the company tests apps and sites for clients that range from startups to the Fortune 500.
As I’ve discussed in my previous blog posts, Appium from Sauce Labs is a great open source tool. Allowing test engineers to quickly set up automated tests for mobile device applications without having to do any modifications to the tested app’s source code is one of the most compelling reasons to use Appium.
However, Appium can be difficult to use when testing iOS applications because Appium runs a file on the iOS device called bootstrap.js. This is a file that takes the application that is running and locates elements on the screen for your test to interact with. The tests created with Appium work well using bootstrap.js to find elements. That is, until a new version of the application is delivered. Then everything needs to be updated.
Difficulty with Locators
The problem arises when using Appium xpath locators to find elements on the screen. When something changes in the application being tested, for example a new button is added or removed, all the xpath locators will change also. The best solution is to recommend to the development team to use names or IDs for all the elements in the application. Application elements that use specific names or ID are consistent across builds and can be found easily by Appium in subsequent versions. That won’t solve the problem of finding every element since specific application elements such as tree views and lists are better suited for xpaths, and what happens if the developers simply say no?
In a perfect world, there would be some other way to identify elements; one that is just as stable and easy as locator IDs. Fortunately, we have something almost as good: locations.
The location of the element we want to interact with can be used to create the element in Appium. Locations for elements rarely change, and should change less frequently as the application gets closer to completion. Appium doesn’t provide support for finding elements by location but does allow us to extract this information from the application frame.
Engineers can get the ‘page’ source by using the following code:
source = (String) js.executeScript("wd_frame.getPageSource()");
Now we can get the screen source exactly how Appium sees it. Examining the output from that function you will notice that the xpath locators are built from this. Now all we need to do is parse that string and build the proper xpath locator dynamically for the element we want to interact with.
We’ve got the Solution
Fortunately, we have a java class built already that does that for you:
appiumXpathBuilder - /jazzhands
This class, which you can download from the ProtoTest Github repository, will get the page source from whatever screen you want to test, and build xpath locators for any element with a valid location.
Once the class is instantiated on your test script, use the FindByLocation function to return the xpath locator for that element.
Your tests are now easier to maintain and don’t have to rely on developers providing an ID or a name for all the elements in their application — although that really is the best way to find elements.
Keep in mind also that the location locators may change depending on screen size of the device you’re testing on. As long as you’re testing on the same device this shouldn’t be a problem.
appiumXpathBuilder on gitHub: https://github.com/ProtoTest/appiumXpathBuilder