“MY CLICK DOESN’T WORK…”: SOLVING PROBLEMS RELATED TO THE CLICK() METHOD USING WEDDRIVER IO AND APPIUM

Isabel Cristina Moreira de Aguiar
NicaSource
6 min readAug 3, 2022

--

Suppose you’ve just started to learn Selenium/Webdriver IO and Appium, and you are all happy and satisfied with your discoveries. But… all of a sudden, your tests start to fail! You have analyzed your tests and realized that the .click( ) function is not working as expected, but you can’t figure out why…

Well, no need to panic! Here we have some clues about what might be happening.

And we hope they may help.

Many issues can cause the .click() method not to behave as it was supposed to. We are going to talk about what we consider to be the three most frequent ones.

The elements to be clicked are not found

This is by far one of the most common problems beginner automated testers are going to face. Here are two factors that should be considered in this case:

Are you on the right page?

This is the first thing you need to check. Maybe you haven’t adequately waited for the screen containing the clickable element to be loaded.

The use of “wait commands” and the correct control of timeouts and retries might help you assure that your test will not look for the element before the page is fully loaded. But we understand that ensuring you are on the right screen before asking for a component to be clicked is never too much.

Example:

await browser.waitUntil(() => HomePage.isDisplayed(), {

timeout: 6000,

timeoutMsg: ‘Homepage not loaded.’’,

});

await $(‘buttonToBeClicked’’).click();

It can also happen that you haven’t waited for the element to be clickable. In this case, one good option is:

await $(‘buttonToBeClicked’’).waitForClickable({timeout: 2000});

await $(‘buttonToBeClicked’’).click( ):

Have you used the most appropriate selector?

Now that you are 100% certain the test is on the right page…

Are you sure your selector is looking for what it was intended to?

Sometimes a given selector may select more than one element. Or sometimes, the chosen select strategy doesn’t consider that state changes may modify the element’s properties.

For example:

In general, we can define a specific order of preference for the strategies to be used in selectors to webpages:

  • id (if they are unique on the page);
  • input name (if unique on the page);
  • class name;
  • CSS selector;
  • Xpath ( without text or indexing);
  • link text or partial line text;
  • Xpath with text and indexing.

These criteria may vary a little according to individual conceptions and experiences but might be a valuable guide to start. In regards to Appium and mobile apps, Jonathan Lipps suggests the following order:

  • accessibility id;
  • id;
  • Xpath;
  • class name;
  • native locators strategies;
  • image.

While finding out your selectors (especially for android or iOS applications), it is always good to remember:

  • Whenever it is possible, use an accessibility id. It’s even more advisable than using an id or an input name.
  • Be especially careful if you need to use Xpaths.
  • Sometimes, Xpaths are the only possibility to locate a specific element. However, according to the Appium Pro site, despite its frequent use, there are several warnings about its drawbacks as they are well-known for their tendency to be slow and brittle.
  • The commands “.getCSSProperty( )” only applies to webview contexts. It means it might not work if the mobile application under test is not hybrid;
  • Try not to choose selectors that use element text as they tend to be unreliable. Imagine what would happen if your app is accessed in another language!
  • Avoid selectors that use an index; if the order of the elements varies, your test will fail.

An essential tool to give a hand with selectors is Appium Inspector. This tool shows different selector options and displays warnings if it considers one option to be risky. It also helps you analyze the time it takes to find a selector. Additionally, it provides a recording function that generates test code you may take as a reference.

Those resources might give you ideas for choosing the best strategy and defining the most appropriate selector. But, the final decision should always be yours as it should consider your project’s unique characteristics.

The elements to be clicked are covered by other elements (keyboard, pop-ups, alerts, log messages, etc.)

You have done your best. Your selector works perfectly well! The page is completely loaded, and the element you need is clickable. Yet, you still have problems making your tests click work.

Here’s a tip! Check the snapshots, verify if an element prevents you from clicking your target element, and identify the said element. If it is the keyboard, there are some alternatives, depending on the circumstances.

Before the .click( ) function, you can try to use:

  1. an Appium command:

if (await driver.isKeyboardShown ( )) {

await driver.hideKeyboard ( );

};

or,

2. a WebdriverIo command:

await browser.sendKeys([‘/n’]).

One of those two options should do the trick.
If they don’t, you must manually find how to get rid of the keyboard and transform this action into code.

If a dialog box, a pop-up, a notification, or an alert is preventing the element from being accessible, Appium offers three desired capabilities to solve this problem:

  • autoAcceptAlerts
  • autoDismissAlerts
  • autoGrantPermissions.

All you have to do is set up the one that best accomplishes your needs to true, as in the example:

capabilities: [

{

“platformName”: “iOS”,

“platformVersion”: “11.0”,

“deviceName”: “iPhone 7”,

“automationName”: “XCUITest”,

“app”: “/path/to/my.app”,

“autoAcceptAlerts”: “true”,

},

],

However, you may still have your element covered by React Native log messages. Unfortunately, solving this issue is not in your hands. As it is clarified by React Native documentation, warning notifications can be hidden if you use one of these two commands (‘lLogBox.ignoreAllLogs( )” or “LogBox.ignoreLogs( )”) in the application. To be able to use them, you have to import LogBox from “react-native”:

import { LogBox } from ‘react-native’;

LogBox.ignoreLogs([‘Warning: …’]); // Ignore log notification by message

LogBox.ignoreAllLogs(); //Ignore all log notifications

In this case, if possible, the application’s developers would have to be contacted and the problem discussed to find the best solution for the project. Ignoring logs should be used only as a last resource. Whenever it is feasible, fixing bugs is always a better solution.

More than one click is necessary to perform the desired action

Last but not least, there is another issue we would like to mention in this article. Sometimes an action can not be performed by clicking the element only once. Or, the number of times the element should be clicked varies according to the state of the elements.

The wisest suggestion to attempt to solve this issue, and many others, are never to assume how the app will behave. Exploratory manual testing and keen observation are essential keys to the success of your tests. Manual testing is a fundamental tool to understand how the application under test works and, consequently, how the .click( ) method in your scripts should be written.

We hope your test clicks perform much better from now on. But if they don’t, we hope you are better equipped to detect the causes and repair your suites.

--

--