Sunday, 26 January 2014

Advanced User Interactions in Selenium !!

The Advanced User Interactions API is a new, more comprehensive API for describing 
actions a user can perform on a web page. Normally we need to find elements and then 
send actions through them. If we need to perform complex tasks like hold down Control and click, then this may not work.The Advanced User Interactions allows us to build these complex interactions with elements in a really nice API. The API relies on two key interfaces for this to work.
Keyboard
The keyboard interface allows keys to be pressed, held down, and released. 
It also allows for normal typing.

Methods available are:
‹1)void sendKeys(CharSequence... keysToSend): Similar to the existing
sendKeys(...) method.
‹2)void pressKey(Keys keyToPress): Sends a key press only, without releasing it.
Should only be implemented for modifier keys (Control, Alt, and Shift).
‹3)void releaseKey(Keys keyToRelease): Releases a modifier key.

Mouse
The mouse interface allows for mouse clicks, double clicks, context clicks, 
as well as moving the mouse to a specific point or to a specific element on the page.

Methods available are:
‹1)void click(WebElement onElement): Similar to the existing click() method
‹2)void doubleClick(WebElement onElement): Double-clicks an element
‹3)void mouseDown(WebElement onElement): Holds down the left mouse button
on an element
‹4)void mouseUp(WebElement onElement): Releases the mouse button
on an element
‹5)void mouseMove(WebElement toElement): Move (from the current location)
to another element
‹6)void mouseMove(WebElement toElement, long xOffset, long yOffset):
Move (from the current location) to new coordinates 
(X coordinates of toElement+ xOffset, Y coordinates of toElement + yOffset)
‹7) void contextClick(WebElement onElement): Performs a context-click (rightclick)

on an element These methods are useful to know but when working and creating a sequence of it, it is better to use the Actions chain generator and then call perform on that class.

Actions
The Actions class allows us to build a chain of actions that we would like to perform.
This means that we can build up a nice sequence, for example "Press Shift and type and
then release", or if we wanted to work with a select that allows multiple selects, we could
press Shift and then do the necessary clicks.

Time for action – selecting multiple items on a select item
  
1 Open up inteliij and create a new Selenium WebDriver project.

2.             WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
driver.get("http://book.theautomatedtester.co.uk/multi-select.html");
Actions builder = new Actions(driver);
//WebElement select = driver.findElement(By.tagName("select"));

WebElement select = driver.findElement(By.id("selectWithMultipleEqualsMultiple"));
System.out.println(select.getText());
List<WebElement> options = select.findElements(By.tagName("option"));
System.out.println(options.size());
Action multipleSelect = builder.keyDown(Keys.SHIFT)
.click(options.get(1))
.click(options.get(2))
.build();
multipleSelect.perform();


Friday, 24 January 2014

How to use Classes in QTP !!!!!!!!!!!!

Here i am giving an useful information about how to use classes in QTP.
Before going to that we will discuss about using functions in QTP.
If there is a function in our script like this


'*********** ********* ********* ********* ********* ********* **
Function Demo(a,b)
demo=a+b
End Function
'*********** ********* ********* ********* ********* ********* **

This is a function to add two numbers.
To call this function we write
'*********** ********* *****


'*********** ********* *****
val=demo(2,3)
msgbox val
'*********** ********* *****
We can store the functions in library files (.vbs) and to use this function, Library should be associated to the QTP Test or library file should be executed by QTP Test using ExecuteFile statement.
This means we can use the functions which are written in QTP Script or in Library files by associating it or by executing it.

But this is not possible when using classes in our QTP Test. If we want to use a class which is there in the libraryfile its mandotory that the library should be executed using Executefile statement.
Classes will not work which are there in associated libraries. Here is an example...

'*********** ********* ********* ********* ********* **
Class Maths
Function Add1(a,b)
add1=a+b
End Function

Function sub1(a,b)
sub1=a-b
End Function

End Class
'*********** ********* ********* ********* ********* **
If the above code is there with in the test script then the usage of this class will be like this
'*********** ********* ********* ********* ********* **
Set mat=New Maths
val=mat.add1( 2,3)
msgbox val
'*********** ********* ********* ********* ********* **
If the class code is there with in the library file then the usage of this class will be like this
'*********** ********* ********* ********* ********* **
ExecuteFile (Library Path)
Set mat=New Maths
val=mat.add1( 2,3)
msgbox val
'*********** ********* ********* ********* ********* **
This class will not work If you just associate the library with in the
File--> Settings --> Resources
But there is a way of using the classes even though if it is in associated library.

First Method:
Where ever the class is declared in the library it self create the class instance and use it in your qtp script.
'*********** ********* ********* ********* ********* **
Set mat=New Maths

Class Maths
Function Add1(a,b)
add1=a+b
End Function

Function sub1(a,b)
sub1=a-b
End Function

End Class
'*********** ********* ********* ********* ********* **
To Use this class
'*********** ********* *
val=mat.add1( 2,3)
msgbox val
'*********** ********* *

Second Method:
Create a function which is returning class object by creating instance of the class.
'*********** ********* ********* ********* ********* **
Function mat()
Set mat=New Maths
End Function

Class Maths
Function Add1(a,b)
add1=a+b
End Function

Function sub1(a,b)
sub1=a-b
End Function

End Class
'*********** ********* ********* ********* ********* **
To Use this class
'*********** ********* *
Set mth=mat ' mat is a function which will return the class instance
val=mth.add1( 2,3)
msgbox val
'*********** ********* *

Thursday, 23 January 2014

Classes, Objects, and QuickTest !!!!!!!!!

VBScript is considered to be "object-based", meaning you can use classes, and those classes can have methods and members, but you can't get nearly the kind of re-use and extensibility you could out of a real OOP language. You don't get inheritance, you don't get polymorphism. In short, you get encapsulation, and that's about it. To me that's pretty important, the abilty to wrap up a bunch of common functions and attributes into a single entity called "an object" and throw it around kinda like you would in Java or Ruby. It allows me to create (instantiate) an object in line 10, then count on it being persisted three levels deep and 200 lines later, and never need to look inside the box to find out how it works.
I'll give some code first.
I'm using VBScript classes right now to model our AUT and make the code prettier. For example, if I want to create a user, it looks like this:
View as plain text
Visual Basic:
LoginProfile "ADMIN"
Set user = NewUser()
user.create(“marcus”, “password”)
user.addRole(“Administrator”)

This snippet opens a browser, logs in as an administrator, creates a new User object (basically a variable that holds attributes about a user), then uses that data (if I had supplied any) to actually create user from within the GUI. After the user is created and declared "valid", I call the "addRole()" method off of the same user. The User object knows how to fill out all the form fields. It knows how to add a role through the security interface. How? That's the beauty: I don't have to know. Someone else can develop the library of objects and maintain it, and all I have to know how to do is invoke it.
I know, I know, it's the same with functions. Yes, it is. But here they're all wrapped up together. Consider this:
View as plain text
Visual Basic:
Set userGuest = NewUser()
userGuest.create(“guest”, “password”)
userGuest.addRole("Guest")
Later, if I want to know the name of that user, I can just ask the object:
View as plain text
Visual Basic:
sName = userGuest.FirstName

Rather than have to code up a function to go and look it up somewhere. It's the persistance of data between states that I'm most interested in. The lack of inheritance and polymorphism is bad, but the most important problems are solved.
Here's the problem: in QTP, you don't just have the limitations of VBScript, you also have some severe limitations built in to (or rather "excluded from") QTP.
The class declaration (in a file called User.vbs) looks like this:
View as plain text
Visual Basic:
Class User
Private sUserID
Public Function Init ( aOptions )
'do some proprietary stuff
End Function
Public Function create ( sUserName, sPassword )
'do some proprietary stuff
End Function
End Class

Public Function NewTigerUser ( aOptions )
Set NewTigerUser = new User
NewTigerUser.Init ( aOptions )
End Function

The first limitation:
That last function is there because QTP doesn't have the ability to use classes from external vbs files within the function libraries. You must give the test script access to the above function, which has access to the class, in order for your test script to be able to "see" the class.
The second limitation:
There's a bug in QTP where you can't, no matter what you do, use the debugger to step through class functions. That was almost a showstopper for me when doing this, before I learned just how few of me teammates use the debugger. When I found out I was the only one I decided that for the greater good, OO was a good direction to go in, if for no other reason than to make the code seem more familiar to us non-VBScript types.
So, in short, it's possible for us to get what we need to when we confront OO concepts, but we're severely limited by VBScript as well as Mercury. I'll submit defects on both of these issues, but I'm not sure whether I'd be optimistic about my chances. We seem to be the only ones trying to do this. Let me know if you know different!


Multiple QTP instances with sandboxie!!

I just learned a new trick.

Sandboxie is a freeware application that you can use to run two instances of QuickTest Pro simultaneously. Sandboxie will create a virtual sandbox separated from the rest of the applications on your machine. What happens in the sandbox stays in the sandbox, and what happens outside the sandbox stays outside.
Once you have sandboxie installed, run an instance of QTP in the sandbox and then run another instance outside the sandbox. They won’t see each other. Better yet, they won’t see each other’s browsers, so you can run two tests at the same time without them interfering with each other.
Of course sandboxie wasn’t written with QTP in mind. This is just one of many applications for it. Most of you are software testers, and I am sure that software testers can figure out the benefits of segregating a test app from the rest of your machine.

--Sudhakar.Mangi

Wednesday, 22 January 2014

Google Search Automation!!!!!!

Through the years I have been asked many times by novices to automation and QTP about Google/Gmail automation. This short post provides an example of Google search automation using a class (see Below). The class encapsulates opening the Browser (invoking Internet Explorer), navigating to the Google.com page, searching and retrieving the results. The Main Procedure takes care of the analysis and final reporting of the test’s status.
Prerequisites:
· Environment(“OPEN_URL”) – OPEN_URL must be defined as either an internal or external variable
· DataTable(“Query”, dtLocalSheet) – Query must be defined as a DataTable parameter in the local sheet.

01Dim oGoogleSearch
02Dim iNumResults
03Dim sMaxResults
04Dim iMaxResults
05Dim oListResults
06Dim oDicSearches
07
08'A .Net ArrayList is used to store the results and sort them with ease
09If Not lcase(typename(oListResults)) = "arraylist" Then
10    Set oListResults = createobject("System.Collections.ArrayList")
11End If
12
13'A Dictionary is used to store the search results (key) linked to the search terms (value)
14If Not lcase(typename(oDicSearches)) = "dictionary" Then
15    Set oDicSearches = createobject("scripting.dictionary")
16End If
17
18Set oGoogleSearch = getGoogleSearch()
19
20sToSearch = DataTable("Query", dtLocalSheet)
21iNumResults = oGoogleSearch.doSearch(sToSearch)
22
23oListResults.Add iNumResults
24
25'If more than one search term share the same number of results, the item associated with the key will concatenate them as a comma separated string.
26If Not oDicSearches.Exists(iNumResults) then
27    'Unique entry
28    oDicSearches.Add iNumResults, sToSearch
29Else
30    'Same number of results of a previous search
31    oDicSearches(iNumResults) = oDicSearches(iNumResults) & ", " & sToSearch
32End If
33
34'Last iteration (assuming we always run on all rows)
35If cint(Environment("ActionIteration")) = DataTable.LocalSheet.GetRowCount Then
36    oListResults.sort
37
38    iMaxResults = oListResults.item(oListResults.Count-1)
39    sMaxResults = oDicSearches(iMaxResults)
40
41    Reporter.ReportEvent micDone, "Max search",  sMaxResults & " got " & iMaxResults
42
43    Set oListResults = nothing
44    Set oDicSearches = nothing
45    Set oGoogleSearch = nothing
46End If


Here below you can see the GoogleSearch class. Some highlights:
·  Upon instantiation, the class_initialize subroutine checks if the browser is open on the Google page. If not, it opens a browser and navigates to the Google page.
·   Upon termination, the class_terminate subroutine closes the browser.
·   All relevant test objects are identified using inline descriptions (aka DP).

01Class GoogleSearch
02    public oBrowser
03    Public oPage
04    Public oResults
05
06    Public Function doSearch(ByVal sQuery)
07        oPage.WebEdit("name:=q").set sQuery
08        oPage.WebButton("html id:=gbqfba").click
09        oBrowser.Sync
10        Set oResults = oPage.WebElement("html id:=resultStats")
11        If oResults.WaitProperty("visible", 1, 10000) Then
12            doSearch = getNumResults()
13        Else
14            doSearch = 0
15            Reporter.ReportEvent micFail, Typename(Me), "Search did not retrieve results until timeout"
16        End If
17    End Function
18
19    Public Function getNumResults()
20        Dim tmpStr
21
22        tmpStr = oResults.GetROProperty("innertext")
23        tmpStr = split(tmpStr, " ")
24        getNumResults = Cdbl(tmpStr(1)) 'Assumes the number is always in the second entry
25    End Function
26
27    Private Sub Class_Initialize
28        Set oBrowser = Browser("title:=.*Google.*")
29        If Not oBrowser.Exist(0) Then
30            SystemUtil.Run "iexplore.exe", Environment("OPEN_URL")
31            Reporter.Filter = rfEnableErrorsOnly
32            While not oBrowser.Exist(0)
33                wait 0, 50
34            WEnd
35            Reporter.Filter = rfEnableAll
36            Reporter.ReportEvent micDone, TypeName(me), "Opened browser"
37        Else
38            Reporter.ReportEvent micDone, TypeName(Me), "Browser was already open"
39        End If
40
41        Set oPage = oBrowser.Page("title:=.*Google.*")
42    End Sub
43
44    Private Sub Class_Terminate
45        If oBrowser.Exist(0) Then
46            oBrowser.Close
47            Reporter.Filter = rfEnableErrorsOnly
48            While oBrowser.Exist(0)
49                wait 0, 50
50            WEnd
51            Reporter.Filter = rfEnableAll
52            Reporter.ReportEvent micDone, TypeName(Me), "Closed browser"
53        End If
54    End Sub
55End Class

The following function serves as a “constructor” for our GoogleSearch class (keep in mind that QTP/UFT does not support using the new operator for custom classes inside the test code; one must use it in a function library).

1Function getGoogleSearch()
2    Set getGoogleSearch = New GoogleSearch
3End Function


---Sudhakar.Mangi