Showing posts with label csharp. Show all posts
Showing posts with label csharp. Show all posts

Friday, October 28, 2011

Selenium WebDriver tips 2

1. "Xpath expression cannot be evaluated or does notresult in a WebElement" error

During our recent automation project we've been encountering really irritating error using WebDriver
"The xpath expression '//given xpath' cannot be evaluated or does notresult in a WebElement"

This error was appearing randomly, for example script was working for 10 times but failed on the 11th. Eventually after several experiments we were able to narrow the problem to following factors:

- this problem appears on the IE only(IE8 in our case)
- this problems appears when WebElement is identified using XPath selector
- this problems appears often shortly after webpage is loaded

Possible Solutions:

Get rid of the XPath selectors
This is great idea and Alister Scott presents sound arguments for this here. This approach however is not always applicable in our context. We know that sophisticated XPath selectors can be brittle but having to automate application based on Microsott SharePoint there is not much choice

Add pause before first FindElement (with XPath selector) method
This solution worked out however you need to remember about adding this pause every time new page is opened. Because in general we don't like pauses in our automation scripts for many reasons we were looking for something else.

Update current FindElement method
We found this solution indirectly thanks to Alister Scott and his SpecDriver example on github. Because this problem appears usually at the first attempt to find element using XPath it's easy to update FindElement method and create your own where you can catch the exception for given number of times. An example in C#:

for (int i = 1; i <= 10; i++)
{
try
{
return driver.FindElement(selector);
}
catch (OpenQA.Selenium.WebDriverException e)
{
Console.WriteLine("Error " + i + " raised: " + e.Message);
}

It really works and often above loop doesn't need more than two iteration to return correct WebElement.

2. WebDriver loses focus on IE8

Another issue which appears randomly. Fortunately we were able to identify one of the reason of this issue - Microsoft Office Communicator. In order to run tests using WebDriver on IE (Windows 7, IE8 in our case) Microsoft's IM needs to be switched off if not then WebDriver randomly switches from IE to IM window during script execution.

Alek

Tuesday, October 25, 2011

Selenium WebDriver tips

Since the beginning of my current automation project we've been encountering issues that seemed to be real showstoppers. These issues were not only time-consuming but could also stop the whole idea of automated checks. Fortunately thanks to the Selenium WebDriver community we were able to handle every problem challenge. Here are some tips that were useful in our context:

1. HTTP Basic Authentication with Selenium WebDriver
Our automated checks needed to be run against web server with HTTP Basic Authentication.

Firefox Authentication Window


IE Authentication Window


Basically the authentication prompt is not available from the Selenium WebDriver. One of the way to handle this limitation is to pass user and password in the url like like below:
http://user:password@example.com

Before we can pass username and password in the url we need to make sure that given web browser let us use this feature.

Firefox
You need to change the following flag:
browser.safebrowsing.malware.enabled

You can change the state of this flag in the default Firefox profile using about:config service page (double click on the flag to change it's state) From now on the Firefox should let you go through http authentication using name and password in the url. (Note that if you are using Selenium WebDriver 2.6 or higher this flag should be disabled by default)

Internet Explorer
Because of the security reason IE by default has this feature disabled. To overcome this limitation you need to update a windows registry as described in this article : http://support.microsoft.com/kb/834489
You need to go to regedit and look for the key

HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_HTTP_USERNAME_PASSWORD_DISABLE

Then you need to add a DWORD 'iexplorer.exe' with '0' value in this key:


This functionality should be available immediately after restarting IE browser

In case your authentication server requires username with domain like "domain\user" you need to remember about adding double slash “\\” (or "%5C" symbol in case of IE) to the url you use in Navigate().GoToUrl() function

http://localdomain\\user:password@example.com
http://domain%5Cuser:password@example.com



2. Same Protected Mode across all zones on IE 8
To be able to run WebDriver on IE you need to equalize the Protected Mode settings for all zones in IE8. It's easy when you are in charge of your computer security policy, however it might be difficult when your machine works under global company policy. In that case you may be not able to change this settings even with local administrator rights.



One of the way we found useful is to update these settings through the windows register in following register keys:
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Internet Settings\Zones

and equalize values for 0x2500 position in all zones.


Value: 3 (Protected Mode off)
Value: 0 (Protected Mode on)


[UPDATE 1]
It seems there is another way to overcome this IE limitation, however we haven't tried it yet - http://www.qaautomation.net/?p=373

[UPDATE 2]
Above tips were tested on : WebDriver 2.6, Windows 7, Firefox 7, IE8

[UPDATE 3]
Thanks to Damian Galek:

Another way of bypassing Selenium limitation, regarding not being able to reach Windows Authentication prompt, that actually worked for us, could be using SendKeys class (one of the class in System.Windows.Forms.dll library – link). It can be used to type whatever we need into any Windows-based application. So in our solution something similar to thefollowing code was used to enter any desired users credentials and accept authentication prompt:

Driver.SwitchTo().Alert(); #Web driver function
System.Windows.Forms.SendKeys.SendWait("Down}");System.Windows.Forms.SendKeys.SendWait("Down}");System.Windows.Forms.SendKeys.SendWait(username);System.Windows.Forms.SendKeys.SendWait("TAB}");System.Windows.Forms.SendKeys.SendWait(password);System.Windows.Forms.SendKeys.SendWait("{Enter}");Driver.SwitchTo().DefaultContent(); #Web driver function

This may not be the cleanest solution out there but it works.


Alek