Thursday, July 9, 2009

Selenium - Handle Dialogs

According to me Selenium is one of the best open source, free tool for testing web applications. It's quite powerful and gives you the facility to write down your test case in your favorite language ( from the plenty of languages it supports ). But it sucks when it comes to handle the dialogs. Dialog boxes are like ghosts to selenium, It can't even see them.
That's because dialogs are native to the operating system you are running and selenium are designed to identify only web component.

After searching too much on the Internet and other forums, I finally got the solution to all my problems. The solution is too simple. As you can't handle the dialog box through selenium, use the other software to do this. And AutoIT is best at this.

Download Execuable (exe) to Handle Save Dialog of Firefox
Download Execuable (exe) to Handle Save Dialog of Internet Explorer
Download Execuable (exe) to Handle Authentication Dialog


AutoIt
Autoit is a free scripting language designed to automate the windows component. It's just like an extensive VB Script and it allows you to convert the script in executable (exe). So what you can do is, write down the script to handle dialog box using AutoIt, convert it into executable and then call the executable when required. So let's see guys how to do it. But before we begin you need to download and install the Autoit. Download it from the following link
Download AutoIt


Handing Modal Dialogs
Modal Dialog box mean once it has appeared all the focus of that application will be on that dialog box only. You will not able to access any of the other component of parent window until you close the dialog box.

Some of the modal dialog boxes that we face frequently during web application testing are

Save Dialog Box
Save dialog box is bit different in IE and in Firefox. So I have write down two separate script for that.

AutoIt script to handle Firefox Save Dialog box
In Firefox when you click on the button/link to download a file. First it will ask you for you permission once you select yes, If you have selected to ask you for the path then only a dialog box will display.

If you will click on download link following dialogbox will appear in Firfox.
Save Dialog box in Firefox

If you click "Save File" on above dialogbox this dialog box will apppears, Yeah if you have choose to ask where to save file from Option.
If you click save on above dialogbox this will appear.
The executable and the script below will handle both of these dialogboxes. You just need to call it in proper way. Your need to pass arguments while calling the script or executable as following.
Save_Dialog_FF Operation FilePath
Operaion: Operation you want to perform when dialog box appears. Can be any of the following
cancel: Press Cancel on the dialog box
Save: Press the Save as Dialog box
FilePath: It's an option argument. It's a full path where you want to save the file.
i.e. C:\myfile.txt
;---------------------------------------------------------
;~ Save_Dialog_FF.au3
;~ Purpose: To handle the Dowload/save Dialogbox in Firefox
;~ Usage: Save_Dialog_FF.exe "Dialog Title" "Opetaion" "Path"
;~ Create By: Gaurang Shah
;~ Email: gaurangnshah@gmail.com
;----------------------------------------------------------

; set the select mode to select using substring
AutoItSetOption("WinTitleMatchMode","2")
 
if $CmdLine[0] < 2 then
 ; Arguments are not enough
 msgbox(0,"Error","Supply all the Arguments, Dialog title,Save/Cancel and Path to save(optional)")
 Exit
EndIf

; wait until dialog box appears
WinWait($CmdLine[1]) ; match the window with substring
$title = WinGetTitle($CmdLine[1]) ; retrives whole window title
WinActive($title);

; if user choose to save file
If (StringCompare($CmdLine[2],"Save",0) = 0) Then

 WinActivate($title)
 WinWaitActive($title)
 Sleep(1)

 ; If firefox is set the save the file on some specific location without asking user.
 ;Save the File
 send("{TAB}")
 Send("{ENTER}")
 if ( StringCompare(WinGetTitle("[active]"),$title,0) = 0 ) Then
  WinActivate($title)
  send("{TAB}")
  Send("{ENTER}")
 EndIf

 ;if firefox is set to prompt user for save path.
 if WinExists("Enter name") Then
  $title = WinGetTitle("Enter name")
  if($CmdLine[0] = 2) Then
  ; If user hasn't provided path to save
  ;save to default path.
  WinActivate($title)
  ControlClick($title,"","Button2")

  Else
  ; If user has provided path 
  ;Set path and save file
  WinActivate($title)
  WinWaitActive($title)
  ControlSetText($title,"","Edit1",$CmdLine[3])
  ControlClick($title,"","Button2")
  EndIf

 Else
  ;Firefox is configured to save file at specific location
  Exit
 EndIf

EndIf
; do not save the file
If (StringCompare($CmdLine[2],"Cancel",0) = 0) Then
 WinWaitActive($title)
 Send("{ESCAPE}")
EndIf

Download above script

AutoIt script to handle Internet Explorer Save Dialog box
Unlike Firefox dialog box internet explorers dialog box is bit different. First dialog box prompts with three choices Run, Save and cancel. The second dialog box is same as Firefox. If you click on the download link in the internet explorer following dialog box will display. Selenium-Handle Save Dialog box of Internet ExplorereIf you will click on "Save" button on the above dialog box Following dialog box will appear which will ask for the path to save the file. Selenium-Handle Save Dialog box of Internet Explorere The executable and the script below will handle both of these dialog boxes. You just need to call it in proper way. Your need to pass arguments while calling the script or executable as following. Save_Dialog_IE Operation FilePath Operaion: Operation you want to perform when dialog box appears. Can be any of the following Run: Clicks on the Run button. cancel: Press Cancel on the dialog box Save: Press the Save as Dialog box FilePath: It's an option argument. It's a full path where you want to save the file. i.e. C:\myfile.txt
;--------------------------------------------------------------------
;~ Save_Dialog_IE.au3
;~ Purpose: To handle the Dowload/save Dialogbox in Internet Explorer
;~ Usage: Save_Dialog_IE.exe "Dialog Title" "Opetaion" "Path"
;~ Create By: Gaurang Shah
;~ Email: gaurangnshah@gmail.com
;--------------------------------------------------------------------

AutoItSetOption("WinTitleMatchMode","2") ; set the select mode to select using substring

if $CmdLine[0] < 2 then
; Arguments are not enough
msgbox(0,"Error","Supply all the arguments, Dialog title,Run/Save/Cancel and Path to save(optional)")
Exit
EndIf

; wait Until dialog box appears
WinWait($CmdLine[1]) ; match the window with substring
$title = WinGetTitle($CmdLine[1]) ; retrives whole window title
WinActivate($title)

If (StringCompare($CmdLine[2],"Run",0) = 0) Then
WinActivate($title)
ControlClick($title,"","Button1")
EndIf

If (StringCompare($CmdLine[2],"Save",0) = 0) Then

WinWaitActive($title)
ControlClick($title,"","Button2")
; Wait for the new dialogbox to open
Sleep(2)
WinWait("Save")
$title = WinGetTitle("Save")
;$title = WinGetTitle("[active]")
if($CmdLine[0] = 2) Then
;click on the save button
WinWaitActive($title)
ControlClick($title,"","Button2")
Else
;Set path and save file
WinWaitActive($title)
ControlSetText($title,"","Edit1",$CmdLine[3])
ControlClick($title,"","Button2")
EndIf

EndIf

If (StringCompare($CmdLine[2],"Cancel",0) = 0) Then
WinWaitActive($title)
ControlClick($title,"","Button3")
EndIf
Download above script

Now you just need to copy and paste above scripts in Autoit IDE, convert those into executables, Save those to the project folder. And then just make a call to the executables with proper arguments, just before you execute the step which invokes the dialog box as shows here.
/**
 * @author Gaurang Shah
 * Purpose: Shows how to invoke Executable to handle dialog box
 * Email: gaurangnshah@gmail.com
 */

import org.testng.annotations.*;
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;

public class Handle_Dialogs {
private Selenium selenium;

 @BeforeClass
 public void startSelenium() {
  selenium = new DefaultSelenium("localhost", 4444, "*chrome", "http://www.autoitscript.com/");
  selenium.start();
 }
 
 @AfterClass(alwaysRun=true)
 public void stopSelenium() {
  this.selenium.stop();
 }
 
 
 @Test
 public void handleSaveDialog() throws Exception {
  String[] dialog;
  
  selenium.open("/site/autoit/downloads/");
  selenium.waitForPageToLoad("3000");
  selenium.click("//img[@alt='Download AutoIt']");
    
  Thread.sleep(2000);
  String browser = selenium.getEval("navigator.userAgent");
  if(browser.contains("IE")){
   System.out.print("Browser= IE "+browser);
   dialog =  new String[]{ "Save_Dialog_IE.exe","Download","Save" };
   Runtime.getRuntime().exec(dialog);
  }
  if(browser.contains("Firefox")){
   System.out.print("Browser= Firefox "+browser);
   dialog = new String[] { "Save_Dialog_FF.exe","Opening","save" };
   Runtime.getRuntime().exec(dialog);
  }
 }

}

Download above File

User Name and Password Dialog Box.

following is the AutoIt script to handle to User name and password dialog box.
;~ ------------------------------------------------------------
;~ Save_Dialog_IE.au3
;~ To handle the Authentication Dialogbox
;~ Create By: Gaurang Shah
;~ Usage: Login_dialog.au3 "Dialog Title" "User Name" "Password"
;~ ------------------------------------------------------------
AutoItSetOption("WinTitleMatchMode","2")

if $CmdLine[0] < 3 then
msgbox(0,"Error","Supply all the Arguments, Dialog title User Name, Password")
Exit
EndIf

WinWait($CmdLine[1]) ; match the window with substring
$title = WinGetTitle($CmdLine[1]) ; retrives whole window title
ControlSend($title,"","Edit2",$CmdLine[2]);Sets User Name
ControlSend($title,"","Edit3",$CmdLine[3]);Sets Password
ControlClick($title,"","OK");
Download above script

Tuesday, July 7, 2009

Selenium - Handling Windows

If your application has a link or a button which opens a new window, and you want to perform some action on the newly opened window though selenium, it's not that hard to handle if you have title, name or the variable associated with that window.

However this is not the case always, sometime you don’t have name of the window or any variable associated with it, and you are not even able able to identify window using title, at the time selenium sucks to identify the window. However there are some alternative ways to resolve this (which might work, not sure). But before we see that let’s see how to select the windows that can be identified easily.

Select window using SelectWindow API

When SelectWindow API fails to Identify Window

Select window using SelectWindow API
Selenium provides the selectWindow API which takes any of the following argument to identify the window.
Title: Use whatever appears on title bar of the window you want to select as argument to selct window API.
However be careful while using title to select the window. Because it may happen that multiple windows have same titles.And in this case Selenium just says that it will choose one, but doesn't mention which one. If this is the case where both have same title I would suggest not to use the title for selecting window. And sometimes the titles of windows are dynamic, and that may create some extra noise.

Name: You can use windows name to identify the window.
For example if the code to open a new window is like as below.

window.open("http://google.co.in","Google Window");

(The second parameter here is windows name. Developer uses this to identify the window in order to use that in further part of the coding.)

You can use "Google Window" as the argument to selectWindow, to select the window as shown below if the code to open the window is as shown above.

selenium.selectWindow("Google Window"); // select new window
//Do whatever you want to do on new window
Selenium.close(); //Close the newly opened window
selenium.selectWindow(null); //To choose the original window back.

Variable name: If opened window is assigned to some variable you can use that variable to identify and select that window.

For example if the code to open a new window is like as below.

GoogleWindow = window.open("http://google.co.in");

You can use "GoogleWindow" as argument to SelectWindow API, to select the window as shown in the code.

selenium.waitForPopUp("GoogleWindow", "30000");
selenium.selectWindow("GoogleWindow");
//Execute steps on new window
selenium.close(); //close the new window
selenium.selectWindow("null"); // select original window.

Using inbuilt API to retrieve Windows Names, Titles and IDs
Selenium provides some APIs to find out the names, Titles and IDs of the all opened windows. So you can use this APIs with SelectWindow API to select the window.

getAllWindowNames() – this will return you the array of all the opened windows names.
getAllWindowTitles() - this will return you the array of all the opened windows names.
getAllWindowIDs() - this will return you the array of all the opened windows names.

So if you have opened only single window you can use something like this to select the newly opened window.

selenium.selectWindow(getAllWindowNames()[1]);
OR
selenium.selectWindow(getAllWindowTitles()[1]);
OR
selenium.selectWindow(getAllWindowIDs ()[1]);

When SelectWindow API fails to Identify Window
Sometimes it happens that you use all the things to select the window but it fails to identify the windows. At the time you can use one of the following ways

Check the selenium logs.
The document of the selectWindow API says that if selenium is not able to identify the window after using all the things mention above you should check out for the window name in selenium log. To do that just start your selenium server with –log argument, something like following:

Java – jar path of selenium-server.jar –log log.txt

Write down the test case to open the window and execute it. Now shutdown the selenium server and checkout the logs for something like this.

Debug: window.open call intercepted; window ID
If you find this you can use this window ID to identify and select the window as the argument to selectWindow API.


Selecting the Window Using openWindow API
Sometimes selenium is not able to identify the window, one of the case is when the window is opened through onload event. Something likes this

<body onload='window.open("http://google.co.in");'>

In this case you can force selenium to identify the window using openwindow command, with URL as blank and name as you like.

Selenium.openWindow("","MyWindow");
selenium.selectWindow("MyWindow");

But if your window is not opening through onload event, and though selenium is not able to select the window after doing all the above things. The only thing left is to open the window using openwindow API with URL same as it would be if would have been opend through button or link click and name as you like. Something like as below.

Selenium.openWindow("http://google.co.in","MyWindow");
Selenium.selectWindow("MyWindow");

Thursday, July 2, 2009

My Firefox add-on.

Download
How to Create Firefox add-on

I just created my own Firefox add-on and submitted to the Firefox. I was free couple of weeks ago and was getting bored, so thought of doing something. And finally I came up with idea of creating my own Firefox add-on. But there was a problem, I wasn't aware of how to make Firefox add-on. So I did some googling on it and came up with some great links(Thanks to the larry and Sergey). It didn't took more than couple of hours to understand how to make the Firefox add-on. Firefox has made it damn easy ( and if you have any doubt about that, just try to make one for IE).

I was thinking that hard part will be to the add-on, but it revealed to be easy. However I found my self stuck with other question, what to make that is useful, easy to implement (as it's my first add-on) and not already been implemented ? Because everything you think of is almost implemented.

But after doing some brainstorming I finally got the idea, I decided to make Spell Checker (Firefox add-on), which checks the spelling mistakes on the page, and not in edit box. The idea came up from my own experience ( and of other friends) of testing websites. Usually we require to test the website for spelling mistakes too. If the site is live I prefer to use some sites (online services) which provides the facility to find the spelling mistakes from page you have submitted. But most of the time the site we require to test are not live, so we can't use other web service for that. And for that we need to use MS Word (or similar software) . It requires to navigate to each page, copy whole text, paste it in the MS Word and then separates the spelling mistakes. And that's a tedious and time consuming task to do. And so I think a add-on, for such thing will be helpful to me ( and yeah others too.. ).

So I quickly learn some JavaScript, put couple of question regarding the JavaScript and add-on on the forum and finally I made my first running version of Firefox add-on, and submitted to the Firefox. Even though it was having plenty of errors and as tester I wouldn't have release it, But somehow my inner developer, woke up and told me to submit just to see other users reacting.

okay so I made it, I submitted it, and other people will be able to download it, use it, but hang on that's not all. Firefox has a system that when you first submits a add-on, Firefox keeps it in the sandbox (a area where people can download add-on, but with warning).

So next step was to make it public. (so that creepy warning disappears) . But you require to have at least three reviews to make it. That seemed to be easy, but it's not because only people who has account can do that.

After few days I nominated it for the public nomination. But after a long delay of 60 (approximately) days I got the email from Firefox which told me that they can't make it public as I haven't handle the global variable in the add-on and it may create problems to other add-on. It didn't fell good, It can't. But the good thing was that they have suggested me some links to resolve the problem.

So I navigate to the link and do some Googleing on global variables and namespace in JavaScript. And I did find out that global variables are really evil thing.

So after a while I resolved the problem of global variable and submitted the new version of my Firefox add-on with fingers crossed that this time it will become the public.


Download Spell Checker

You can download my add-on form the following page.
https://addons.mozilla.org/en-US/firefox/addon/11259

How to Create Firefox add-on
If you want to learn how to create a Firefox add-on following are couple of resource that might help you.

http://www.rietta.com/firefox/Tutorial/prefs.html
https://developer.mozilla.org/en/Building_an_Extension
https://developer.mozilla.org/en/XUL_Overlays
https://developer.mozilla.org/en/XUL_Reference