Synchronizing web driver and Ignoring Exceptions in C# Selenium API

In general the website response times may cause issues while doing the UI automation testing. Most of the times test scripts will fail due to synchronizations issues from web-driver and the application web elements.

Following are the common reasons and if we see very frequent issues in synchronization it is suggested to do performance testing and tuning.

  • Location from where we are accessing the application (Latency)
  • Network bandwidth
  • Too much firewall checks
  • Website architecture and technology on which website built on.

Most of these cases are taken care while doing performance tuning and performance engineering, but yet we see page load issues, element enabling issues and visibility issues while doing UI automation.

In selenium we have several methods that we can use to make sure that these things are taken care. Following is the just enough explanation about waits in Selenium driver.

Implicit waits will wait until the defined action (example page loading ) is complete.

Example of it is managed time outs, and they are defined at driver level.

Driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(30);
Driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(30);

When we want to wait explicitly at certain number of seconds we will use explicit waits. As the name suggests the test execution will be halted during this time. Example of it is sleep

 Thread.Sleep(2000);

here the parameter indicates the number of milliseconds to wait for.

The other case of waiting for dynamic web elements is using wait until or web driver waits. These are most common implicit waits that are used. There are two ways we can use these.

We can declare the web driver wait and and it will wait for max wait in this case it is 30 seconds, and repeatedly we can check for the expected conditions i this case we are looking for visibility of the element google search text box.

IWebElement textbox;
WebDriverWait waits = new WebDriverWait(Driver, TimeSpan.FromSeconds(30));
textbox = waits.Until(SeleniumExtras
.WaitHelpers
.ExpectedConditions
.ElementIsVisible((By.Name(SEARCH_TEXT_BOX_NAME))));

There is another way we can use this as function delegate, following is how it is used.

//there is another way using function delegate
//delegate parameters and return value = new delegate parameters return value of passed parameters
//delegate is on the fly function generator
Func<IWebDriver,IWebElement>checkForvisibilityOfWebElement = new Func<IWebDriver, IWebElement>((IWebDriver Driver) =>
  {
     IWebElement textBoxDelegate = Driver.FindElement(By.Name(SEARCH_TEXT_BOX_NAME));
       if (textBoxDelegate.Displayed)
           return textBoxDelegate;
       else
          return null;
   }); 
 
 textbox = waits.Until(checkForvisibilityOfWebElement);

When you look at above code, its function delegate takes one argument as IWebDriver and returns the IWebElement. The last argument of function delegate is always a return type.

The wait until function will take this and checks for the condition mentioned in the delegate periodically.

If you look at the until you can clearly see this text.

WaitUntill

But if we look closely, the description says it will throw exception if it is not listed in the Ignore Exception list.

For that purpose. We have to configure our waits object what exceptions that we want to ignore while we periodically check for our condition. We can achieve this by following.

IWebElement textbox;
WebDriverWait waits = new WebDriverWait(Driver, TimeSpan.FromSeconds(30));

waits.IgnoreExceptionTypes(typeof(NoSuchElementException));
waits.IgnoreExceptionTypes(typeof(ElementNotSelectableException));

There are list of exceptions that we may want to ignore, following is the snap shot.

ExceptionList

And finally following is the list of element states we can wait for.

ListOfwaitsfor

Please comment if you see anything is incorrect or you want to add something you know. Thank you.

 

Advertisement

Synchronization in Automation Testing with selenium.

When you ask selenium tester what is the most common issues he is facing during his automation testing experience, the first thing he would say is Sync problem.

Let’s take a bird eye view on this and will take deep dive on the synchronization issues and how to address them.

Selenium framework has several methods to address the synchronization issues. Mainly they are segregated into two different varieties.

  • Implicit waits
  • Explicit waits

Implicit wait:

This is the most common wait type we use; it is also called as default wait. The page load time out, and the timeouts.implicitwait is the two types of implicit wait. The implicit wait meaning that the driver has to wait until the web element is existed on the dom. It will come out of the waiting loop if element exists beforehand. Example you have given 10 seconds on element x, and it has loaded in 2 seconds web driver knows it and goes to next step without waiting for 10 seconds. It is called as implicit wait.

driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);

Explicit wait:

Explicit waits are defined on the particular web element to wait until the property value becomes true.

It will pole every 500 milliseconds to get the property value and verifies it with defined value.

Examples:

//webdriver wait class
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.elementToBeClickable(driver.findElement(By.xpath(menu))));

//for multiple elements
WebDriverWait wait = new WebDriverWait(driver, 30);
List options = driver.findElements(By.xpath(option_to_select));
wait.until(ExpectedConditions.visibilityOfAllElements(options));

//Another example
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(ExpectedConditions.invisibilityOfElementWithText(By.className("jqx-fill-state-normal"), "Loading..."));

Fluent wait:

Fluent waits also called as explicit waits, but only difference being we can define interval to pole and can tell to ignore any exceptions. It will be useful to save resources not to check every 500 milliseconds if element load takes long time.

Wait<WebDriver> fluentwait = new FluentWait<WebDriver>(driver)
                        .withTimeout(20, TimeUnit.SECONDS)
                        .pollingEvery(1, TimeUnit.SECONDS)
                        .ignoring(java.util.NoSuchElementException.class);
fluentwait.until(ExpectedConditions.invisibilityOfElementWithText(By.className("jqx-fill-state-normal"), "Loading..."));

The another type of wait is normally not recommended is static wait or pause the program.

Thread.sleep(500);

So, the gist is the know when to use what. Fluent wait is used when application slower and running in a slow paced machine where we don’t want driver to hit every 500 milliseconds, and you know it will not come till 2 sec or 3 seconds, we can define the polling interval. I am guessing this as it is synonymous to implicit wait where the default polling is 500 ms.

We can use web driver wait almost in all cases where we know element loading is taking place, but the properties are not loaded until some other action is completed, example, state dropdown is enabled only when country drop down is selected, in that case we can use expected conditions on the enabled of the state dropdown after country select.

Default waits or implicit waits are used when we know dom loading is taking some time and not to give wait on existence of each element. Normally this would serve the purpose, but angular applications waits plays key role in test execution failures.

If we use waits wisely and where ever we need depending the application behavior with limited use of static waits will improve the script quality drastically.

Thank you.

Page Object Model – Approach

In selenium, most frequently we hear page object model.

I have asked people why did they call it as page object model ? Is there any specific reason behind this ?

I got general answer saying “we store all locators in a page as static final strings in a page class”

Is this correct explanation ? are we doing page object model as is ? below is another view point.

In general we call page object model because every method in a page returns the page object instead of string/float/int or any standard return types.  This will provide flexibility in writing test cases easily.

Step 1 : Define Page class

package test.pom;
public class page1 extends pageRep
{  
public page1() 
{
super(); 
} 
public page1 testM1() 
{ 
System.out.println("Method 1 Page 1");  
return this; 
} 
public page1 testM2() 
{ 
System.out.println("Method 2 Page 1");  
return this; 
} 

}

Create another page to illustrate navigation between pages.

package test.pom;
public class page2 extends pageRep 
{
 public page2() 
{ 
super(); 
} 
public page2 test_M1() 
{ 
System.out.println("Method 1 Page 2");  
return this; 
} 
public page2 test_M2() 
{ 
System.out.println("Method 2 Page 2");  
return this; 
} 
}

If you observe clearly, the above classes are returning the page class as object and extending the class page repository. The class page repository is the class where we use to navigate between the pages.

Step 2: Create page repository for navigation between pages

package test.pom;
public class pageRep { 
public pageRep() 
{
 System.out.println("Calling the super class"); 
}
public page1 navigateToPage1() 
{ 
return new page1();
} 
public page2 navigateTopage2() 
{ 
return new page2(); 
} 
}

Step 4 : While creating the test case you can see it will be simple as we can keep “.” to see the methods in the class as each method returns the class object again, you will have visibility of all methods.

Page repository helps us to navigate between pages.

This is the best illustration of the Java extends concept which we can use to write our tests in selenium.

package test.testcases;
import test.pom.pageRep;
public class tests {
public static void main(String[] args) 
{ 
 pageRep start = new pageRep();
 start     
.navigateToPage1().testM1().testM2()
.navigateTopage2().test_M1().test_M2()     
.navigateToPage1().testM1(); 
 }
}

output:

Calling the super class
Calling the super class
Method 1 Page 1
Method 2 Page 1
Calling the super class
Method 1 Page 2
Method 2 Page 2
Calling the super class
Method 1 Page 1