GA-WDIO: Automating Mobile App Testing
A tool that creates and runs tests automatically and accurately.
What is GA-WDIO?
GA-WDIO is an automation CLI tool that creates tests for Web Apps, APIs & Mobile (iOS & Android) Apps/Browsers. Behind the curtains, it runs numerous tools like GeckoDriver, ChromeDriver & Appium internally for various stacks, browsers & modes for efficient testing.
GA-WDIO was conceptualized internally at GeekyAnts to automate the generic testing scenarios that every app, be it web or mobile, would have to go through to pass the first few levels of testing (apart from very specific test cases that need to be made manually). This tool managed to automate a lot of redundant testing work and cut down on the total development time for projects.
Why should you use GA-WDIO?
This tool comes with quite a lot of features that are inbuilt, like creating a boilerplate, checking Appium's necessary requirements & optional dependencies on the system, but that's not all.
Have a look at this comprehensive list of all the features provided by GA-WDIO here .
Setup For GA-WDIO & Appium For Mobile App Testing
To setup GA-WDIO & Appium, just run this simple npm
command:
npm install -g ga-wdio appium
ga-wdio create
It will create a project using the boilerplate provided by GA-WDIO.
That's It !
GA-WDIO is ready to use now.
Setting Up Android & iOS Automation Testing
Setting up an environment for Android and iOS is quite easy to do. You will need to follow the steps from the official documentation which can be found at this link.
Using GA-WDIO is pretty simple, but you might find yourself stuck with a few things if you're new to this tool. The following are some issues that you might face while writing tests for a mobile application and what you can do to solve them.
A Background On Performing tests
To perform automation tests, we need to find specific elements on which we can perform test actions.
For this tutorial, we will be using xpath
to find elements. Also, we have to pass testId and accessibilitylabel to react-native
components to make them be able to locate these elements.
Adding testID
& getting xpath
In A React Native App
Let's first add testId
and accessibilityLabel
to our React Native project.
To add testId
, we just need to pass accessibilityLabel
and testID
parameters as props to the component.
<Component accessibilityLabel={ 'FOO' } testID={ 'FOO' } />
Also in much cleaner way we can create a function in utils and pass an Id
export function testProps (id) {
return {testID: id, accessibilityLabel: id};
}
<Component ...testProps('FOO') />
Finding & Interacting With Elements Using xpath
.
We have used xpath
to select and interact with elements using GA-WDIO.
For finding xpath
or accessibilityLabel.id
, I have used Appium Desktop
With Appium Desktop, you can find any element and its locators by either clicking the element on the screenshot or locating it in the source tree.
Checkout this link for more information about finding the element.
Using Gestures & Web View On GA-WDIO
Working With Gestures
Most applications use touch gestures for interactivity, navigation and scrolling content, which needs to be tested as well.
Appium provides the touchPerform
function to automate and handle gestures.
/* This is a swipe up
const from = { x: 100, y: 250 }
const to = { x: 100, y:50 }
*/
swipe (from, to) {
driver.touchPerform([{
action: 'press',
options: from,
}, {
action: 'wait',
options: { ms: 1000 },
}, {
action: 'moveTo',
options: to,
}, {
action: 'release',
}]);
driver.pause(1000);
}
In many applications, the content on the screen is longer than the height of the physical screen on which it is displayed, especially in the case of forms.
If the element we need to test is below the visible area on the device, testing tools will not be able to find that element. In such a situation, we have to scroll until we find the element and then perform the necessary tests.
checkIfDisplayedWithScrollDown (element, maxScrolls, amount = 0) {
if ((!element.isExisting() || !element.isDisplayed()) && amount <= maxScrolls) {
this.swipe(from, to);
this.checkIfDisplayedWithScrollDown(element, maxScrolls, amount + 1);
} else if (amount > maxScrolls) {
throw new Error(`The element '${element}' could not be found or is not visible.`);
}
}
Working with webview
When we are working Hybrid apps (i.e. Native + webview), by default, we will have NATIVE_APP
as the current context. If a webview is loaded, then we will have two contexts, much like the following:
["NATIVE_APP","WEBVIEW_28158.2"]
We can get a list of available contexts by using the
driver.getContexts();
method.
We cannot look for a particular element in webview
if webview
is not rendered or not fully loaded.
We can use following methods to confirm these conditions:
export const CONTEXT_REF = {
NATIVE: 'native',
WEBVIEW: 'webview',
};
const DOCUMENT_READY_STATE = {
COMPLETE: 'complete',
INTERACTIVE: 'interactive',
LOADING: 'loading',
};
// Wait for the webview context to be loaded
waitForWebViewContextLoaded () {
driver.waitUntil(
() => {
const currentContexts = this.getCurrentContexts();
return currentContexts.length > 1 &&
currentContexts.find(context => context.toLowerCase().includes(CONTEXT_REF.WEBVIEW));
}, {
timeout: 10000,
timeoutMsg: 'Webview context not loaded',
interval: 100,
},
);
}
// Wait for the document to be full loaded
waitForDocumentFullyLoaded () {
driver.waitUntil(
() => driver.execute(() => document.readyState) === DOCUMENT_READY_STATE.COMPLETE,
{
timeout: 15000,
timeoutMsg: 'Website not loaded',
interval: 100,
},
);
}
Working with Hooks
GA-WDIO allows you to implement hooks, that are supported by webdriver.io. We can use these in the Android config
(android.conf.js
/ios.conf.js
) files.
You can also create a custom log report and send it over mail after successful completion of the tests.
For implementing the same , you can use after
, afterTest
and onComplete
hooks in the config
files in the following manner:
onComplete: async (result) => {
await sendReport(process.env.GA_SESSION_ID);
}
Check out all the hooks that are available for use here.
Writing Test Case Scenarios
Usually, when we are writing test cases in JS, we use tools like Chai or Mocha.
The following is a sample code snippet for testing the 'Login' feature:
import TabPage from "../common/TabPage";
import Login from "../common/Login";
describe("Test login elements", () => {
it("It should go to login page", () => {
TabPage.login.click();
Login.email.click();
Login.email.setValue("test@webdriver.io");
Login.password.setValue("Test1234!");
if (driver.isKeyboardShown()) {
driver.hideKeyboard();
}
Login.loginButton.click();
Login.loginAlert.click();
});
})
const xpath = require("../xpath");
const tabXpath = xpath("tabPath.json");
class TabPage {
get home() {
return $(tabXpath.HOME);
}
get webView() {
return $(tabXpath.WEB_VIEW);
}
get login() {
return $(tabXpath.LOGIN);
}
get forms() {
return $(tabXpath.FORMS);
}
get swipe() {
return $(tabXpath.SWIPE);
}
}
export default new TabPage;
Some Useful Links
- GA-WDIO’s Wiki & Documentation
- Appium
- webdriver
- Another good tutorial
Thank you for reading. I hope that you will give GA-WDIO a shot and make testing much easier and faster for your projects. Do leave some ❤️ if you like the article.
Cheers !