Browse Category: Tips

Firebug, Firepath, and other developer tools.

Firebug, Firepath, and other developer tools.

First thing should come to your mind, what are Firebug and firepath and why do I need to learn this? The answer is pretty simple, you should know that what you want to tell your selenium code to perform some action, and where? As a human, you exactly know that where you want to click on the screen or what kind of items you like to interact with. If you want to click on third menu item out of six on the screen, your mind will tell your hand or finger to move the cursor to that menu item and click but in case of selenium or another test tool, your test code should know that unique location before the click. Firebug and firepath help you to make your life easier by identifying your target element in your Firefox browser.

Installation Steps:

Firefox Users

firebug:

Start firefox browser, open URL https://addons.mozilla.org and search for Firebug add-on. You will see the following screen. You may notice different version of firebug based on your existing firefox version. Add this extension to your Firefox by clicking button ‘Add to Firefox’.
Firepath Addon

This action may ask to restart your firefox. Make sure you do not have any unsaved changes on any firefox instance opened on your computer. Once Firefox restarts, you will see the following icon in the browser’s add-on area. Now you can start using firebug.

 

Firepath:

Firepath is firebug extension and adds a development tool to edit and identify XPath or CSS selector of web element. To install firepath, you need to do the same as firebug in above steps and restart the browser. Once browser started, you can start using it.

Usage:

Now you want to understand about an element like HTML code, XPath, and properties of that target element. Take an example, my application under test is, http://www.donethedeal.com/ and I want to click on ‘Add to Cart’ button on the Nexus phone. Take your cursor to the desired button or element, do right click and choose “Inspect Element with firebug’ as below.

Firepath Addon

As soon as you click on the last option in the above dialog, you will see developer tool open where you can see all HTML code for the web page. There is no need to go into detail with other tabs which I will go in later chapters.

Firepath Addon

you can see Firepath tab on the above screen too. Now you if you want to have your script to click on this button, you have to give the locator of the button. The locator is a unique address of an element on the webpage so that your script can find and act on it. To find the locator either you can right click on the highlighted element on the above screen inside developer tool and select “Copy XPath” or “Copy CSS Path” as given below and save in your script at an appropriate place.

Firepath Addon

Firepath can better help to get CSS or XPath than getting from here. Go to FirePath tab in firebug tool and click inspect element and then point to target element on the webpage. It will highlight target element and give you the option to choose XPath/classpath as per your choice as below.

Firepath Addon

In Chrome Browser

If you are using google chrome, developer tool is already there. You do not have to worry about. Put your mouse cursor to the element where you want to perform the action, and do right click and choose “Inspect”. Developer tool will automatically open. right click on the highlighted and you can choose to copy XPath or CSS Selector as below.

Firepath Addon

There are many chrome extensions are available which can help you to find locator from chrome browser. You can play along with them and see if those are easy enough to use. There is no perfect tool but each developer in the world building something which is making our life easier. You can see various tabs above and we will talk more about that some other time.

 

Thanks for reading and your valuable feedback is important to make this website helpful for others. Do not hesitate to correct if you find any mistake or unclear line. I will try to improve and update periodically.

 

Smart click (part 1)

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, coded-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:

  1. I determine what the button I am going to click.
  2. 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.
  3. Then I click the button.
  4. I verify that click has been successful, that some changes has 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();

 

 

Smart click (part 2)

Here is the explanation how you can implement your own Click() method and what is behind the scenes. I will describe the method using a pure IWebElement instance. To be able to invoke the method out of an IWebElement, it should be declared as an IWebElement interface extension method. The method will have a couple of overridden versions for different sets of input parameters.

Ok, let’s start. First of all let’s define what the method should do:

  • It checks if the clicking action may be done
  • It checks if all the necessary conditions for successful clicking are met (for example, some other elements are displayed in the specified state)
  • It clicks the element
  • It verifies if the clicking action has been performed and checks the result of the click

How it does it:

  1. It verifies the element exists, is visible and is available for clicking
  2. It starts the loop. The number of iterations is presented by one of the parameters
  3. It invokes a method which is passed as an input parameter and verifies preconditions for successful clicking (checks if some necessary elements are in the correct state, clicks some other elements to meet the expected conditions, and performs all the actions required to prepare your web element for successful clicking)
  4. It tries to click the element with one of the approaches passed as a parameters (list of clicking actions)
  5. It invokes a method passed as a parameter which verifies that the clicking action has been performed and the expected result has been achieved.
  6. If the expected result is not met, it proceeds to the next clicking action from the parameter list

This is the end of the theory, now let’s begin with practice.

Create a simple test aka testing Google Search page:

using System;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Support.UI;

namespace SmartClick
{
   [TestFixture]
   public class TestClass
   {
      IWebDriver driver;

      [SetUp]
      public void Setup()
      {
         driver = new FirefoxDriver();
      }

      [TearDown]
      public void Teardown()
      {
         driver.Quit();
      }

      [Test]
      public void GoogleSearch()
      {
         driver.Navigate().GoToUrl("http://www.google.com ");
         IWebElement query = driver.FindElement(By.Name("q"));
         query.SendKeys("selenium");

         IWebElement btnSearch = driver.FindElement(By.Name("btnG"));
         //assume this method is working fine now but does not work with previous version of your browser (or with another browser) and the customer just eager to run your tests with both versions
         btnSearch.Click();

         WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
         wait.Until((d) => { return d.Title.StartsWith("selenium"); });
         Assert.AreEqual("selenium - Google Search", driver.Title);
      }
   }
}

Now let’s start writing our own clicking method. I named it SmartClick(). Add a static class to the namespace and put a static void method SmartClick() into it:

public static class Extensions
{
   public static void SmartClick(this IWebElement element)
   {
      element.Click();
   }
}

Now you can replace btnSearch.Click(); with btnSearch.SmartClick();

Or you can invoke the method this way:

Extensions.SmartClick(btnSearch);

because it is static.

Now let’s check that you did not pass null as a parameter and the element is displayed and enabled for clicking (step 1)

public static class Extensions
{
   public static void SmartClick(this IWebElement element)
   {
      if (element == null) 
      { 
         //add 'Element is null' error message into your log file or throw NoSuchElement or NullReference exception 
      }
      if(!element.Displayed) 
      { 
         //add 'Element is not displayed and cannot be clicked' error message into your log file 
         //you may add a screenshot here
      }
      if(!element.Enabled) 
      {
         //add 'Element is not displayed and cannot be clicked' error message into your log file
         //plus a screenshot
      }
      element.Click();
   }
}

Step 2 – wrap the clicking action into a loop. There is no sense in it right now but in the future it will be used for multiple attempts to click the element if it is necessary. The number of iterations is one of the method parameters with value 1 as default.

public static class Extensions
{
   public static void SmartClick(this IWebElement element, int iterations = 1)
   {
      int i = iterations;
   
      if (element == null) 
      { 
         //add 'Element is null' error message into your log file or throw NoSuchElement or NullReference exception 
      }
      if(!element.Displayed) 
      { 
         //add 'Element is not displayed and cannot be clicked' error message into your log file 
         //you may add a screenshot here
      }
      if(!element.Enabled) 
      {
         //add 'Element is not displayed and cannot be clicked' error message into your log file
         //plus a screenshot
      }
      
      while (i > 0)
      {
         i--;
         element.Click();
      }      
   }
}

Inside the loop, you can do any precondition, clicking actions and post-clicking verification to make successful click.

Step 3 – invoke a method that checks or does some preparation for successful clicking actions. You can put here almost any method which will be doing almost anything you need. To do this, you have to create a delegate for a method and then to initialize it, pass it as a parameter to the method and invoke it inside the loop. Add the following delegate to the namespace:

public delegate bool CustomFunction(params object[] obj);

and pass the delegate as a parameter to the SmartClick method:

public static void SmartClick(this IWebElement element, CustomFunction precondition = nullint iterations = 1)
   {
      int i = iterations;
      string elementName = element.Text;

      if (precondition == null)
         precondition = x => true; //if you did not specify the method let's assume it has passed (return true)
      
      while (i > 0)
      {
         i--;
         if (!precondition.Invoke())
         {
            //add string.Format("Preconditions for clicking '{0}' web element are not met", elementName) error message into your log file
            //screenshot
            continue; //there is no sense to do clicking action if precondition method has failed. Return back to the beginning of the loop and start again from the very beginning
         }
         if (element == null)   
         {   
            //add 'Element is null' error message into your log file or throw NoSuchElement or NullReference exception   
         }
         if(!element.Displayed)   
         {   
            //add 'Element is not displayed and cannot be clicked' error message into your log file   
            //you may add a screenshot here  
         }  
         if(!element.Enabled)   
        {  
           //add 'Element is not displayed and cannot be clicked' error message into your log file      //plus a screenshot  
         }
         element.Click();
      }      
   }

Now you can invoke the SmartClick method in this way:

btnSearch.SmartClick(x =>
{
   try
   {
      IWebElement query = driver.FindElement(By.Name("q"));
      query.SendKeys("selenium");
      return true;
   }
   catch (Exception e)
   {
      //add "SmartClick preconditions error: " + e.Message error message into your log file
      return false;
   }
});

Above I passed an anonymous method as a parameter but actually there are a lot of ways to use this delegate – and this is your choice how to do it. A couple of examples:

btnSearch.SmartClick();//preconditions are always true because precondition parameter is null by default
btnSearch.SmartClick(x => SomeMethod("blah", "blah-blah", "blah-blah-blah"));//invokes precondition method with parameters
CustomFunction myDelegate = SomeMethod;
btnSearch.SmartClick(myDelegate);//using the delegate instance

Step 4 – clicking the element. I mentioned that the method must perform different clicking actions on the web element according to input parameters. Therefore there must be additional parameter which specifies the action. You are free to implement it as you wish but I used an enumerator for it. I pass its value to the method and then handle it inside the switch operator.

Add a new enumerator inside the namespace

public enum ClickAction
{
   Click,
   Submit,
   DoubleClick,
   LeftMBClick,
   RightMBClick,
   JSClick,
   CursorClick,
   SendKeyEnter,
   SendKeyReturn,
   SendKeySpacebar
}

This is the list of clicking actions I sometimes use in relation to specific web elements. You can use some of them or implement your own ones. Keep it in mind that some of the actions used here require an instance of IWebDriver, therefore you have to pass it to the method as a parameter or to make it available for use inside the method.

Now update the method with new input parameters and inner implementation:

public static void SmartClick(this IWebElement element, IWebDriver driver = null, CustomFunction precondition = nullint iterations = 1, params ClickAction[] clicks)
   {
      int i = iterations;

      //if you do not specify what actions to use for clicking the following default actions will be used
      ClickAction[] clickActions = clicks != null ? clicks : new ClickAction[] { ClickAction.Click, ClickAction.LeftMBClick, ClickAction.JSClick };
   
      string elementName = element.Text;

      if (precondition == null)
         precondition = x => true; //if you did not specify the method let's assume it has passed (return true)
      
      while (i > 0)
      {
         i--;
         if (!precondition.Invoke())
         {
            //add string.Format("Preconditions for clicking '{0}' web element are not met", elementName) error message into your log file
            //screenshot
            continue; //there is no sense to do clicking action if precondition method has failed. Return back to the beginning of the loop and start again from the very beginning
         }
         if (element == null)   
        {
           //add 'Element is null' error message into your log file or throw NoSuchElement or NullReference exception   
        }  
        if(!element.Displayed)   
        {    
           //add 'Element is not displayed and cannot be clicked' error message into your log file      
          //you may add a screenshot here  
        }  
        if(!element.Enabled)   
        {  
           //add 'Element is not displayed and cannot be clicked' error message into your log file  
          //plus a screenshot  
        }
         foreach (var action in clickActions)
         {
            //here you may add string.Format("Clicking '{0}' web element with {1} click action", elementName, action) message into your log file
            switch (action)
            {
               case ClickAction.Click:
                  try
                  {
                      element.Click();
                  }
                  catch (Exception e)
                  {
                      //"SmartClick clicking error: " + e.Message error message
                  }
                  break;
               case ClickAction.Submit:
                  try
                  {
                  }
                  catch (Exception e)
                  {
                     //"SmartClick clicking error: " + e.Message error message
                  }
                  break;
               case ClickAction.DoubleClick:
                  try
                  {
                     var builder = new Actions(driver);
                     builder.DoubleClick().Build().Perform();
                  }
                  catch (Exception e)
                  {
                     //"SmartClick clicking error: " + e.Message error message
                  } 
                  break;
              
               case ClickAction.RightMBClick:
                  if (driver == null)
                  {
                     //"SmartClick clicking error: IWebDriver instance must be passed as a parameter and connot be null if you use clicking with right mouse button action" error message
                     break;
                  }
                  try
                  {
                      var builder = new Actions(driver);
                      builder.MoveToElement(element).ContextClick(element).Build().Perform();
                  }
                  catch (Exception e)
                  {
                     //"SmartClick clicking error: " + e.Message error message
                  }
                  break;
               case ClickAction.JSClick: 
                  if (driver == null)
                  {
                     //"SmartClick clicking error: IWebDriver instance must be passed as a parameter and connot be null if you use clicking with JavaScript action" error message
                     break;
                  }
                  try
                  {
                     ((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].click()", element);
                  }
                  catch (Exception e)
                  {
                     //"SmartClick clicking error: " + e.Message error message
                  }
                  break;
               case ClickAction.CursorClick:
                  try
                  {
                     var X = element.Location.X;
                     var Y = element.Location.Y;
                     SetCursorPos(X, Y);
                     mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
                  }
                  catch (Exception e)
                  {
                     //"SmartClick clicking error: " + e.Message error message
                  }
                  break;
               case ClickAction.SendKeyEnter:
                  try
                  {
                     element.SendKeys(Keys.Enter);
                  }
                  catch (Exception e)
                  {
                     //"SmartClick clicking error: " + e.Message error message
                  }
                  break;
               case ClickAction.SendKeyReturn:
                  try
                  {
                     element.SendKeys(Keys.Return);
                  }
                  catch (Exception e)
                  {
                     //"SmartClick clicking error: " + e.Message error message
                  }
                  break;
               case ClickAction.SendKeySpacebar:
                  try
                  {
                     element.SendKeys(Keys.Space);
                  }
                  catch (Exception e)
                  {
                     //"SmartClick clicking error: " + e.Message error message
                  }
                  break;
            }
            //For now this part of code is placed here just to avoid multiple clicking on the same web element. It will be replaced with Step 5 on the next stage
           if(true)
               break;
         }
      }      
   }

The ClickAction.CursorClick action requires the use of some additional variables. Add them to the Extensions class:

[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern void mouse_event(uint dwFlags, int dx, int dy, uint cButtons, uint dwExtraInfo);

[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern long SetCursorPos(int X, int Y);

private const int MOUSEEVENTF_LEFTDOWN = 0x02;
private const int MOUSEEVENTF_LEFTUP = 0x04;

Also you need to add reference to System.Drawing library and use following namespaces:

using System;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.Interactions;
using System.Runtime.InteropServices;

Steps 5 – invoking a method passed as a parameter which verifies that the clicking action has been performed and the expected result matches the actual one.

To be sure that a clicking action has been successfully done and the expected result has occurred, you can pass one more function to the method and invoke it after every attempt to click the web element. This function has the same signature as the method which verifies preconditions. Let’s name it ‘postcondition’.

If you specify your own method which will verify post-click conditions or you can not to specify the method itself but pass IWebDriver instance to the method – in this case the method will use default actions defined in the method. If you specify neither post-click verification conditions method nor IWebDriver instance there no verification will be performed. Here is an example of how I implemented it, but you can change the functionality in your own way.

public static void SmartClick(this IWebElement element, IWebDriver driver = null, CustomFunction precondition = null, CustomFunction postcondition = nullint iterations = 1, params ClickAction[] clicks)
   {
      int i = iterations;

      //if you do not specify what actions to use for clicking the following default actions will be used
      ClickAction[] clickActions = clicks != null ? clicks : new ClickAction[] { ClickAction.Click, ClickAction.LeftMBClick, ClickAction.JSClick };
   
      string elementName = element.Text;

      if (precondition == null)
         precondition = x => true; //if you did not specify the method let's assume it has passed (return true)

      if (postcondition == null)
      {
         if (driver == null)
         {
            //"SmartClick: IWebDriver is null, no postcondition verification provided" message to log file
            postcondition = x => true//assume if you do not pass IWebDriver to the mathod you do not need any post-click conditions verification. Therefore, this method always returns true
         }
         else
         {
            //"SmartClick: No click verification conditions are specified. Default verification wil be used." message to log file
            var numOfWindows = driver.WindowHandles.Count;
            var pageHashCode = PageHashCode(driver);
            var pageTitle = driver.Title;
            var pageUrl = driver.Url;
            //the method returns true if any of the following conditions are met, otherwise it returns false
            postcondition = delegate
            {
               //page title is changed
               if (pageTitle != driver.Title)
               {
                  //log message "SmartClick: Click validation - Title of the page has changed"
                  //screenshot
                  return true;
               }
               //page url address is changed
               if (pageUrl != driver.Url)
               {
                  //log message "SmartClick: Click validation - Url address of the page has changed"
                  //screenshot
                  return true;
               }
               //alert pop-up is displayed
               try
               {
                  driver.SwitchTo().Alert();
                  //log message "SmartClick: "Element_ClickWhile: Click validation - Alert pop-up is displayed"
                  //screenshot
                  return true;
               }
               catch {  }
               //number of opened windows or tabs is changed
               if (numOfWindows != driver.WindowHandles.Count)
               {
                  //log message "SmartClick: "Element_ClickWhile: Click validation - Number of opened windows (tabs) has changed"
                  //screenshot
                  return true;
               }
               //page hash code is changed. It indicates that some changes has occurred on the page
               if (pageHashCode != PageHashCode(driver))
               {
                  //log message "SmartClick: "Element_ClickWhile: Click validation - Hash code of the page has changed"
                  //screenshot
                  return true;
               }
               return false;
            }
         }
      }
      
      while (i > 0)
      {
         i--;
         if (!precondition.Invoke())
         {
            //add string.Format("Preconditions for clicking '{0}' web element are not met", elementName) error message into your log file
            //screenshot
            continue; //there is no sense to do clicking action if precondition method has failed. Return back to the beginning of the loop and start again from the very beginning
         }
         if (element == null)   
         {   
            //add 'Element is null' error message into your log file or throw NoSuchElement or NullReference exception   
         }  
         if(!element.Displayed)   
         {   
            //add 'Element is not displayed and cannot be clicked' error message into your log file   
            //you may add a screenshot here  
         }  
         if(!element.Enabled)   
         {  
            //add 'Element is not displayed and cannot be clicked' error message into your log file  
            //plus a screenshot  
         }
         foreach (var action in clickActions)
         {
            //here you may add string.Format("Clicking '{0}' web element with {1} click action", elementName, action) message into your log file
            switch (action)
            {
               case ClickAction.Click:
                  try
                  {
                      element.Click();
                  }
                  catch (Exception e)
                  {
                      //"SmartClick clicking error: " + e.Message error message
                  }
                  break;
               case ClickAction.Submit:
                  try
                  {
                  }
                  catch (Exception e)
                  {
                     //"SmartClick clicking error: " + e.Message error message
                  }
                  break;
               case ClickAction.DoubleClick:
                  try
                  {
                     var builder = new Actions(driver);
                     builder.DoubleClick().Build().Perform();
                  }
                  catch (Exception e)
                  {
                     //"SmartClick clicking error: " + e.Message error message
                  } 
                  break;
              
               case ClickAction.RightMBClick:
                  if (driver == null)
                  {
                     //"SmartClick clicking error: IWebDriver instance must be passed as a parameter and connot be null if you use clicking with right mouse button action" error message
                     break;
                  }
                  try
                  {
                      var builder = new Actions(driver);
                      builder.MoveToElement(element).ContextClick(element).Build().Perform();
                  }
                  catch (Exception e)
                  {
                     //"SmartClick clicking error: " + e.Message error message
                  }
                  break;
               case ClickAction.JSClick: 
                  if (driver == null)
                  {
                     //"SmartClick clicking error: IWebDriver instance must be passed as a parameter and connot be null if you use clicking with JavaScript action" error message
                     break;
                  }
                  try
                  {
                     ((IJavaScriptExecutor)driver).ExecuteScript("arguments[0].click()", element);
                  }
                  catch (Exception e)
                  {
                     //"SmartClick clicking error: " + e.Message error message
                  }
                  break;
               case ClickAction.CursorClick:
                  try
                  {
                     var X = element.Location.X;
                     var Y = element.Location.Y;
                     SetCursorPos(X, Y);
                     mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
                  }
                  catch (Exception e)
                  {
                     //"SmartClick clicking error: " + e.Message error message
                  }
                  break;
               case ClickAction.SendKeyEnter:
                  try
                  {
                     element.SendKeys(Keys.Enter);
                  }
                  catch (Exception e)
                  {
                     //"SmartClick clicking error: " + e.Message error message
                  }
                  break;
               case ClickAction.SendKeyReturn:
                  try
                  {
                     element.SendKeys(Keys.Return);
                  }
                  catch (Exception e)
                  {
                     //"SmartClick clicking error: " + e.Message error message
                  }
                  break;
               case ClickAction.SendKeySpacebar:
                  try
                  {
                     element.SendKeys(Keys.Space);
                  }
                  catch (Exception e)
                  {
                     //"SmartClick clicking error: " + e.Message error message
                  }
                  break;
            }
            if (postcondition())
               return;
            //add string.Format("Post-conditions for clicking '{0}' web element are not met", elementName) error message into your log file
            //screenshot
         }
      }      
   }

Note: In the code above I invoked a method named PageHashCode(). This is a custom method which gets html-code of the current page (IWebDriver.PageSource property) and computes its hash code. The result is returned as a string. Here is the code of the method. Put it into the Extensions class:

static string PageHashCode(IWebDriver driver)
{
   MD5 md5 = MD5.Create();
   byte[] bytesArray = Encoding.ASCII.GetBytes(driver.PageSource);
   byte[] hashCode = md5.ComputeHash(bytesArray);
   var sb = new StringBuilder();
   foreach (byte t in hashCode)
      sb.Append(t.ToString("X2"));
   return sb.ToString();
}

Step 6 – If the expected result is not met, it tries to clicking the elements with the next clicking action from the list.

You can implement it in many ways according to your objectives. For example, you may just add an error message to log file or your can throw an exception. You should add the code for this right after the switch() operator.

Also, I recommend to add one more input parameter to the method: a delay between the clicking attempts. Obviously, after a click on a web element it takes some time for something to happen. Usually, when you click a button, a request is sent to a server, and then the server sends a response which your browser handles and displays the final result. Sometimes it happens almost immediately and sometimes it may be a time-consuming process. So, you can pass a delay parameter (period of time in seconds during which the method should do nothing, assuming this time is enough for performing all the actions described above) with some default value, for example 1 second.

public static void SmartClick(this IWebElement element, IWebDriver driver = null, CustomFunction precondition = null, CustomFunction postcondition = nullint iterations = 1, int delay = 1, params ClickAction[] clicks)
{
   //method code
}

Put its use right after switch() operator

foreach (var action in clickActions)
{        
   ...
   switch (action)
   {
        ... 
   }
   Thread.Sleep(delay * 1000);
   if(postcondition())
      ...
}

Note: you may use global variables instead of the method parameters. For example, you can store such variables as delay or IWebDriver instance in external classes and have them visible all over the project. In that case, you do not need pass them as a parameter. Anyway, you are free to modify the method as you wish. This is just a common point of view, one of possible implementations.

In the next part, I will show how the method may be used in a test.

 

 



Notice: Undefined variable: font_family in /home/chyqruxavcln/public_html/learnseleniumtesting.com/wp-content/plugins/gdpr-cookie-compliance/moove-modules.php on line 282