When using the Selenium Webdriver tool for testing web-based applications, I faced a problem: sometimes the common Click() method does not work for specific elements. Or, for example, it may work fine in the FF browser and fails to click in Internet Explorer. After a little investigation, I noticed that instead of the Click() method I can use methods from the Actions class, or I can click elements with JavaScript. But I also discovered that I have to use one action for FF and another for IE – often an action worked with one browser but failed with the other. I had to add extra logic for specific elements and it began spreading some mess in my code.
Then a couple of months later “funny” things started to happen regularly. Guys from Mozilla Corp. or Microsoft delivered a new version of their browser. The old version of Selenium Webdriver didn’t support this new browser, so I had to upgrade it to the latest one. But oops… most of my specific clicks turned out to work conversely. Or did not work at all, and I had to return to the common Click() method. Chaos in my code was about to come.
That’s why I started looking for a method that would work consistently with any browser, webdriver, or elements and would also give me some additional helpful features like events logging with screenshots, handling exceptions, code-behind verification, etc. Finally, I realized I had to invent it myself.
I asked myself what I do when I click a web element (assume a button) in a browser manually and came up with the following list:
- I determine what the button I am going to click.
- I am sure if I can click the button. I check if it is present on the page, is displayed, is enabled for a click, etc. In other words, I verify conditions for a successful click.
- Then I click the button.
- I verify that click has been successful, that some changes have occurred – expected or not – even if I’ve got an error, it means that the click itself has happened. So, I verify conditions after the click.
I do all the thing from the list above unconsciously. So does everyone else.
So I decided to write my own version of the Click() method reproducing all my manual actions for clicking a button in real life. Here is the recipe:
If you have separate classes for different types of web elements in your testing framework, such as buttons or links, you can add the method Click() to this class(es) and use a private IWebElement instance defined inside the class for interactions. For example:
public class WebButton { private IWebElement element; public WebButton(/*constructor parameters*/) { element = //instance of IWebElement according to constructor parameters //bla-bla } public void Click(/*possible parameters*/) { //logic for clicking the element in a smart way } }
If you use an ordinary IWebElement interface for describing web elements, you can create an extension method for the interface. Like this:
public static class Extensions { public static void Click(this IWebElement buttonToClick, /*possible parameters*/) { //logic for smart click on buttonToClick } }
You will be able to invoke the methods in your tests in this way:
//1st case WebButton button = new WebButton(/*constructor parameters*/); button.Click(); //2nd case IWebElement button = driver.FindElement(By.Id("buttonID")); button.Click();