UI Testing Web Views in a React Native App with Appium

Although there are quite a few UI testing frameworks for cross-platform apps, not all of them have the ability to interact with a web view. When an app contains a web view or runs entirely within a web view, having the capability to do this is very important for end-to-end testing.

Appium provides us with this ability. Below, we’ll walk through how to add Appium to a React Native app and how use it to reach in and test web views.

1. Add Appium to React Native

First, we’ll need to add Appium and a couple of other libraries to our project.

yarn add --dev appium wd appium-doctor 

The library after Appium is the web driver library that will communicate with Appium. Appium doctor is a tool to verify the installation of Appium and its dependencies. In order to check the dependencies after installing Appium, simply run:

yarn run appium-doctor

If any errors show up, fix them by pulling in the correct libraries.

2. Set Up Server in Test

The default port that the server runs on is 4723. When setting up the driver, we can either use this or pass in a separate value.


import wd from 'wd';

const PORT = 4723;
const driver = wd.promiseChainRemote('localhost', PORT);

3. Set Up Test Configurations

The client sends configurations or capabilities to the Appium server. They share information about how the tests should run, such as which simulator to use and where to find the app.

For example, if we wanted to run tests on an iPhone X running iOS 11.4, we would pass the following configuration to the driver:


const config = {
  platformName: 'iOS',
  platformVersion: '11.4',
  deviceName: 'iPhone X',
  app: './path/to/the.app' // relative to the root of the project
};

More information and a list of generally supported capabilities can be found in the Appium documentation.

We can then set the above configuration in our test setup. Our code should now look like this:


import wd from 'wd';

const PORT = 4723;
const driver = wd.promiseChainRemote('localhost', PORT);

const config = {
  platformName: 'iOS',
  platformVersion: '11.4',
  deviceName: 'iPhone X',
  app: './path/to/the.app' // relative to the root of the project
};

beforeAll(async () => {
  await driver.init(config);
})

4. Switch to the Web View Context

In order for the test to interact with the web view, we will need to change the context of the test. To view a list of all available contexts, we can use the following line of code:


let contexts = await driver.contexts();

In our case, contexts should contain both the native app and the web view in an array. The first element will be the native app, and the second should be the web view. With this knowledge, we can pull out the web view context and set it as the current context.


await driver.context(contexts[1]); // set the current context to the webview 

It’s also possible to set the context to the web view immediately upon session start. This can be helpful if the entire app is running in a web view. To do this, simply add the autoWebview property to the configuration passed to the server when it is set up.

5. Interacting with the Web View from a Test

Once we switch contexts, we can start reaching into the web view to do our testing. We can reach directly into the DOM of the web view using calls like getElementByTagName or hasElementByAccessibilityId. If we follow all of these steps, we should end up with a test that looks like this:


test('appium renders', async () => {
  expect(await driver.hasElementByAccessibilityId('webView')).toBe(true);
  let contexts = await driver.contexts();
  await driver.context(contexts[1]); // set the current context to the webview
  const resultText = await driver.elementByAccessibilityId('text').text();
  expect(resultText).toBe('HELLO WORLD');
});

6. Start Appium and Run Tests

Before we can run the tests, we’ll need to get the Appium server up and running. This is as simple as running a single command:

yarn run appium 

Once the server is up, we can begin running tests. Make sure the emulator is started, start the React Native development server, and then run the tests.

xcrun instruments -w "iPhone X (11.4)"
react-native start
yarn test

Other Resources