Streamlining Mobile App Testing with WebdriverIO and Appium

Wavda Aniva
5 min readApr 15


To ensure a high-quality application, testing is an essential phase in software development. Yet, testing mobile applications can be challenging for testers, especially when the application needs to be tested to see if it is working correctly across multiple platforms, operating systems, and devices.

Powerful tools like WebdriverIO and Appium can greatly improve mobile app testing and build effective test automation frameworks. In this article, we’ll look at how to use WebdriverIO with Appium to speed up mobile app testing.

Benefits of Using WebdriverIO and Appium for Mobile App Testing

WebdriverIO and Appium are powerful tools that can help streamline mobile app testing by creating efficient and effective test automation frameworks. The advantages of using WebdriverIO and Appium for mobile app testing include the following:

  1. Efficient testing: WebdriverIO and Appium enable mobile app testing across various devices, platforms, and operating systems. This lowers testing time and effort, resulting in faster feedback on issues.
  2. Cross-platform testing: it is supported by WebdriverIO and Appium, allowing testers to test mobile applications on different platforms such as Android and iOS with a single test script.
  3. WebdriverIO and Appium support several programming languages, including JavaScript, Python, and Ruby, which makes it simpler for developers and testers to develop test scripts.


Before setting up WebdriverIO and Appium for mobile app testing, ensure that the following prerequisites are met:

  1. A local machine with Node.js installed.
  2. Appium server installed.
  3. Android or iOS device connected to the local machine.
  4. An emulator or simulator is installed.

You can also find a step-by-step guide for setting up the above pre-requisites in this article:

Setting up WebdriverIO and Appium for Mobile App Testing

We’ll proceed with setting up WebdriverIO and Appium for mobile app testing with the following steps:

Step 1: Initiate Project

Run the following command to start a node.js project within your test project directory. In this example, we’ll create the project within a folder called wdio-appium-test.

npm init -y

Step 2: Install Dependencies

Install Appium, WebdriverIO CLI, and Allure CLI dependencies with the following command:

npm install @wdio/cli allure-commandline --save-dev

Step 3: Configure Test Setup

Run the following command to configure your test:

npx wdio config

With the command above, a wizard will be executed, which will require you to answer a couple of questions. In this example, we’ll configure the test setup so that it’ll

  • be launched locally
  • have automation backend located locally
  • run using the mocha framework
  • run without compiler
  • use autogenerated page objects and test files
  • use test reporter spec and allure
  • use wait-for plugin
  • use chromedriver service

Step 4: Setup Service and Capabilities for Appium

Add capabilities configuration to your wdio.conf.js file, for example:

// ...

services: [
['appium', {
command: 'appium',
logPath: './logs/'

capabilities: [{
platformName: 'Android',
platformVersion: '13.0',
deviceName: 'Pixel_4',
udid: 'emulator-5554',
autoGrantPermissions: true,
app: 'apk/NativeDemoApp.apk',
automationName: 'UiAutomator2',
appPackage: 'com.wdiodemoapp',
appActivity: 'com.wdiodemoapp.MainActivity'

// ...

This capabilities configuration will allow you to test a WebdriverIO demo app file located within the folder C:\demo\wdio-appium\apk using the Android emulator we created earlier in this article:

Step 5: Configure Test Report

Add the following configuration to your wdio.conf.js file, which will allow you to get logs for each step of the test as well as screenshots of failing tests:

reporters: ['spec', ['allure', {
outputDir: './allure-results',
disableWebdriverStepsReporting: true,
disableWebdriverScreenshotsReporting: false,

Step 6: Setup Test Execution Script

Add the following script to your package.json file:

"scripts": {
"test": "npx wdio wdio.conf.js",
"report": "npx allure generate allure-results --clean && npx allure open"

Write Test Script

Once we have set up WebdriverIO with Appium, we can start writing our page objects and test cases. Let’s start with a simple test case that signs up a new account on the demo app and verifies that a successful message is displayed.

WebdriverIO Demo Application

Step 1: Creating Page Objects

Page objects are classes that represent the different pages of our mobile website. They encapsulate the page elements and the actions that can be performed on those elements.

Let’s create a page object in test/pageobjects/page.js for the navigation menu that is shared across the demo application.

module.exports = class Page {
get loginWidget() {
return $('//*[@content-desc="Login"]');

Now, let’s create a page object for the login page within test/pageobjects/

const Page = require('./page');

class LoginPage extends Page {
get btnSignUpContainer () {
return $('//*[@content-desc="button-sign-up-container"]');

get inputEmail () {
return $('~input-email');

get inputPassword () {
return $('~input-password');

get inputRepeatPassword () {
return $('~input-repeat-password');

get btnSignUp () {
return $('//*[@content-desc="button-SIGN UP"]');

get popupSignupSuccessMessage() {
return $('//*[@resource-id="android:id/message"]');

async signUp (email, password) {
await this.inputEmail.setValue(email);
await this.inputPassword.setValue(password);
await this.inputRepeatPassword.setValue(password);

module.exports = new LoginPage();

In the above code, we have defined a LoginPage class along with the element locators on the login page related to the sign-up process.

We have also defined a signUp() method that performs the sign-up process, starting with clicking the button to open the sign-up form, inputting values into the required fields (email, password, password confirmation), and clicking the sign-up button.

Step 2: Writing Test Cases

Now we can start writing our test cases with our page object in place.

Let’s write our test case to use the LoginPage page object.

const LoginPage = require('../pageobjects/')

describe('Login/Sign Up Form', () => {
it('should signup with valid credentials', async () => {
await LoginPage.signUp('', 'SuperSecretPassword!')
await expect(LoginPage.popupSignupSuccessMessage).toBeExisting()
await expect(LoginPage.popupSignupSuccessMessage).toHaveTextContaining('You successfully signed up!')

In the above code, we have created an instance of the LoginPage class and used its signUp() method to perform the sign-up process using the email and password as the parameter.

We have also added the expect assertion, which will check if the popupSignupSuccessMessage element defined in LoginPage exists and contains the text “You successfully signed up!”.

Running the Test Cases

To run the test cases, we need to execute the following command, which we have defined in the script within the package.json file:

npm test
Running test command

Once the test execution is complete, proceed with generating the HTML report using Allure with the following command:

npm run report
Running generate report command
Allure HTML Report



Wavda Aniva

A curious potato exploring new things on software quality