Browse Category: Selenium WebDriver

Smart click (part 3)

In this part I decided to show some examples of using the SmartClick() method just to make the way it works easier to understand.

Example 1 – the simplest. In 99% of cases you can use it without any parameters just like an IWebElement interface extension method:

public void GoogleSearch()
{
   IWebDriver driver = new FirefoxDriver();
   driver.Navigate().GoToUrl("http://www.google.com");
   IWebElement query, btnSearch;
   WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));

   query = driver.FindElement(By.Name("q"));
   query.Clear();
   query.SendKeys("selenium");

   btnSearch = driver.FindElement(By.Name("btnG"));

   btnSearch.SmartClick();

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

In this case SmartClick works like native method Click() with some additional functionalities, such as logging and exception handling. It verifies that the element is not null, is visible and enabled, ignores the precondition method, uses the first click action from the list of default ones (in our case it is IWebElement.Click(), but you can replace it with any other) and finishes its work (because the postcondition method always returns true and no verification is provided). Therefore, SmartClick() is equal to Click() plus event messages logging plus handling exceptions.

Example 2 – using IWebDriver. You can invoke the method with instance of IWebDriver as a parameter to make click actions more robust

btnSearch.SmartClick(driver);

The method after clicking the btnSearch element verifies that any of the following events has occurred: title or url address or page source of the page has changed, number of opened tabs or windows has changed, or an alert message is displayed. If any of the conditions is met it means that the click action has been performed over btnSearch. If not – you will have an error message in your log file (or you can rewrite this behavior according to your needs).

Example 3. If you pass an additional parameter to the method – number of iterations – it will try clicking the element as many times as the iterations parameter specifies until one of the conditions above is met.

btnSearch.SmartClick(driver: driver, iterations: 3);

Example 4. Or if you pass different click actions, it will try clicking the btnSearch with all these actions until the conditions above are met:

btnSearch.SmartClick(driver: driver, clicks: ClickAction.Click, ClickAction.DoubleClick, ClickAction.JSClick);

Example 5 – using a precondition delegate. One more way to invoke the method is to pass a precondition method to it like this:

public void GoogleSearch()
{
   IWebDriver driver = new FirefoxDriver();
   driver.Navigate().GoToUrl("http://www.google.com");
   IWebElement query, btnSearch;
   WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));

   btnSearch = driver.FindElement(By.Name("btnG"));

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

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

Here the method does all actions inside the passed anonymous method first and then clicks btnSearch. In this example it is not very useful but it might help if btnSearch was disabled until you entered a query into the search field. In such case, you can perform some preconditional actions first and then click the button. It also may be useful if your web element is a part of a dropdown menu and you have to hover or click some parent menu item first to make the element visible.

Example 6. The same thing can be done with post-conditions:

public void GoogleSearch()
{
   IWebDriver driver = new FirefoxDriver();
   driver.Navigate().GoToUrl("http://www.google.com");
   IWebElement query, btnSearch;
   WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));

   query = driver.FindElement(By.Name("q"));
   query.Clear();
   query.SendKeys("selenium");

   btnSearch = driver.FindElement(By.Name("btnG"));

   btnSearch.SmartClick(postcondition: x => { return wait.Until((d) => { return d.Title.StartsWith("selenium"); }); });

   Assert.AreEqual("selenium - Google Search", driver.Title);
}

In the example above, the driver will try clicking btnSearch until the title of the current page starts with the ‘selenium’ word.

Example 7 – custom click actions. Invoking the method in the following manner:

btnSearch.SmartClick(clicks: ClickAction.JSClick);

will make SmartClick working like SmartClcik() without parameters (see details above) but only using JavaScript function for performing click action instead of native IWebElement.Click() action. Of course, you can pass any other action or a set of actions instead of ClickAction.JSClick.

Example 8.1 – passing a parametrized method as a parameter. The next example shows invoking SmartClick with a function as a parameter which has its own parameters. Assume you have some method in your test class (which matches to CustomFunction delegate signature – bool Method(params object[])). Here it is:

public bool EnterSearchCriteria(params object[] obj)
{
   if (!(obj[0] is IWebElement) || obj[0] == null)
      throw new Exception("Wrong parameter input");
   if (!(obj[1] is string) || string.IsNullOrEmpty((string)obj[1]))
      throw new Exception("Wrong parameter input");
   IWebElement query = (IWebElement)obj[0];
   query.Clear();
   query.SendKeys((string)obj[1]);
   return true;
}

And here is the example of its usage:

public void GoogleSearch()
{
   IWebDriver driver = new FirefoxDriver();
   driver.Navigate().GoToUrl("http://www.google.com");
   IWebElement query, btnSearch;
   WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));

   btnSearch = driver.FindElement(By.Name("btnG"));

   btnSearch.SmartClick(precondition: x => EnterSearchCriteria(driver.FindElement(By.Name("q")), "selenium"));

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

Example 8.2. You can do the same thing with post-conditions as well. Assume you have another method with appropriate signature which waits for the page title to change:

public bool WaitForSearchResult(params object[] obj)
{
   if (!(obj[0] is IWebDriver) || obj[0] == null)
      throw new Exception("Wrong parameter input");
   if (!(obj[1] is string) || string.IsNullOrEmpty((string)obj[1]))
      throw new Exception("Wrong parameter input");
   WebDriverWait wait = new WebDriverWait((IWebDriver)obj[0], TimeSpan.FromSeconds(5));
   return wait.Until((d) => { return d.Title.StartsWith((string)obj[1]); });
}

You can invoke it in this way:

btnSearch.SmartClick(postcondition: x => WaitForSearchResult(driver, "selenium"), clicks: new[] { ClickAction.CursorClick, ClickAction.JSClick });

Example 9. In the example above there are multiple click actions are used in addition. You may combine all the method’s parameters as you wish to make the method working the way you need. For example:

btnSearch.SmartClick(driver, x => EnterSearchCriteria(query, "selenium"), x => { return wait.Until((d) => { return d.Title.StartsWith("selenium"); }); }, 2, 3, ClickAction.LeftMBClick, ClickAction.SendKeyEnter);

P.S. It is likely that you will never use all the method’s features, but actually it’s a good to know that you can.

 

Google Chrome and ChromeDriver with Selenium

Google Chrome and ChromeDriver with Selenium

Before going in details about google chrome and ChromeDriver lets learn some terminology.

Wire Protocol: defined as RESTful web services using JSON over HTTP that is being used by webdriver/RemoteWebDriver, to communicate with browser.

ChromeDriver is a standalone server developed by Chromium team(Google) which implements wire protocol.
ChromeDriver consist of three separate pieces,
a. Chrome Browser.
b. Selenium Project code (driver) AND
c.  An Executable that helps code to communicate with chrome browser (lets call it server for ease)

server expects you to have chrome installed in the default location of computer.

Before start, make sure that you add the location of ChromeDriver.exe aka server into the PATH system variable so you do not need to specify during the execution.
WebDriver driver = new ChromeDriver();
WebDriver driver = new ChromeDriver(“PATH To ChromeDriver.exe”);

if you execute your test with ChromeDriver, you will notice that server will start and shut down when driver.quit is being called. server is small and light weighted but this will start and stop every time while executing multiple tests which may add noticeable delay to a larger test suite. To handle this, you can control the life and death of the server by ChromeDriverService.

1. Start ChromeDriverService in [TestFixtureSetup] before any test starts.
service = ChromeDriverService.CreateDefaultService();
service.Start();
option = new ChromeOptions();

2. Stop this service in [TestFixtureTearDown] once all test suite executed.
service.Dispose();

Full Code:

using System;
using System.Linq;
using System.Text;
using NUnit.Framework;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;
using OpenQA.Selenium.Chrome;
namespace NUnitTest1 {
    [TestFixture]
    public class TestBasicSteps {
        OpenQA.Selenium.IWebDriver driver = null;
        ChromeDriverService service = null;
        ChromeOptions option = null;
        [TestFixtureSetUp]
        public void TestFixtureSetup() {
            service = ChromeDriverService.CreateDefaultService();
            service.Start();
            option = new ChromeOptions();
			}
        [SetUp]
        public void setup() {
            driver = new ChromeDriver(service, option);
			}
        [Test]
        public void TestCase1() {
            driver.Navigate().GoToUrl("http: //www.google.com");
            System.Threading.Thread.Sleep(5000);
			}
        [Test]
        public void TestCase2() {
            driver.Navigate().GoToUrl("http: //learnseleniumtesting.com");
            System.Threading.Thread.Sleep(5000);
			}
        [TearDown]
        public void CleanUp() {
            driver.Quit();
            }
        [TestFixtureTearDown]
        public void dispose() {
            service.Dispose();
            }
        }
    }

Known Issue:

Typing does not work with rich-text enabled page.
Cannot specify a custom profile.
HTML 5 API not implemented yet.

Selenium Commands That You must know.

Pay attention to following commands as these are going to play pivotal role in selenium.

1: SelectFrame (locator):

To learn this command we need to understand basics of HTML frame element first. Spend some time to learn HTML Frames, if don’t know much about frame elements. While performing any action to any web element, we first select the frame where it resides then we perform any action to any element inside that frame. To access other elements coded in different frame, again we need to select that frame using this command and then we can access their elements. We use frame name as locator. To select the parent frame, use “relative=parent” as a locator; to select the top frame, use “relative=top”. You can also select a frame by its 0-based index number; select the first frame with “index=0”, or the third frame with “index=2”.

E.g.     selenium.SelectFrame(“relative=up”);

selenium.SelectFrame(“al-iframe”);

selenium.SelectFrame(“fraContent”);

2: WaitForCondition (script, timeout):

This command executes ‘script’ (JavaScript/selenium command) repeatedly until it gets true and exit. The maximum duration of execution is specified as ‘timeout’. Command returns ‘false’ if script timeout without evaluating script as true. We will use this command frequently in our code to verify any expected condition be true within specified time period. For example we can use this command to execute to simple JavaScript to verify if some page element present or not etc. I would recommend you to do practice this command with variety of JavaScript or other selenium command.

Selenium.WaitForCondition (“selenium.IsElementPresent (“id=buttonID”)”, 60000);

Explanation: This command will execute repeatedly until selenium.IsElementPresent () returns true or reach timeout period. Even after 60000 ms, if selenium.IsElementPresent () doesn’t find desired element, WaitForConition command returns false.


3: WaitForPageToLoad (timeout):

This is another very important selenium command that people use in testing. We need to wait for page to load either do some action or to verify if there is new page or frame being load on the browser. It works most of time but on some instances it doesn’t which I will explain later. We will create customized method using WaitForCondition command to perform waitForPageToLoad action.

4: fireEvent (locator, eventName):

This command use to explicitly simulate an event, to trigger the corresponding “onevent” handler. There are some of instances where search box perform search process as soon as we start typing in the field but that only possible if type manually. that doesn’t work if we just send selenium.Type() command to the element. In such cases we need to send fireEvent command with eventName like onChange, onFocus etc., depending upon the associated event to the search box. We will talk about this in more detail on upcoming posts.

5: AddLocationStrategy(StrategyName, Strategy):

This command is very powerful command of selenium. We will use to write a strategy to capture the web element or locator smartly. For example, if you define the strategy of name “foo”, we need to use this “foo” with ‘=’ to define locator. To use this strategy effectively we will use with “foo=blah bblah” in our code. In later section I will show you, how to use jQuery for our location strategy and start doing greedy search for every element without any hassle. Here is basic example of that but we will go in more detail in later sections. Suppose you want to click on <button> element with id=”a”, you will write command selenium.Click(“jquery=button[id=’a’]”); where ‘jquery’ is the name of the strategy. Just make sure that you run addLocationStrategy command in very beginning of you code.

There are few more commands like isElementPresent, isTextPresent, Assert, Verify, which is also an important command for testing but I don’t think we need special explanation here. You can refer them from various from or seleniumhq.org. I would recommend you to do more and more practice on these commands so you will be well acquainted.

Now we will try to finish very first step of framework in term of coding. In this section we will try to empower selenium to do greedy search for locator using AddLocationStrategy command. We will write a strategy using JavaScript and jQuery which is be best way to do search the web element without any hassle. Before going into detail let’s learn jQuery first. I am sure you just frown after reading this but I can assure you, it’s not that daunting as you are expecting.



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