QTP – Testing Multiple Windows Applications

by Anshoo Arora on November 26, 2009 | QTP/UFT, QTP/Windows | 14 Comments

After writing the article Working with Multiple Browser Applications with QTP, I thought, there are several instances where automation developers have to work with applications containing multiple windows, in a Standard Windows Environment. This technique uses a similar methodology as demonstrated in the article for Web-based apps, but the crux of this technique differs. It can be used by automation developers testing most types of windows applications, and it contains concepts that are showcased in my generic automation framework RelevantCodes[1]One, which will be released in the coming few weeks.

With the help of this technique, regardless of how many windows applications are opened through QTP, we would never have to keep track of the Window’s title or any of its recognition properties (unless we want to). In other words, regardless of a window’s dynamic nature, this concept will enable you to give the window a name of your choice, and use that name to identify the window, instead of keeping track of changes in its properties.

What this concept contains:

  • LaunchAdd: Launch a new window and retain its reference throughout the test cycle
  • AddNew: Automatically add a new open window to the collection without you having to specify its properties (see list of dependencies)
  • AddCustom: Adds a custom window by specifying its properties as an array
  • All identifiers stay intact until the test finishes.

View clsWindow.txt | Download clsWindow.zip | Download Demo v9.2 | Download Demo v9.5

This concept contains 3 main methods, as described above. You can download the Class clsWindow for complete documentation, but for a quick overview, please continue reading.

First, and the one that may be used the most often is a method called AddCustom. It enables users to add a window of their choice to the collection, with the name they want to specify. From that point onwards, regardless of the number of changes that particular window goes through, it will not be required to update its properties. The name you give the window can be used throughout the test cycle. Below is the code snippet for AddCustom:

Public Sub AddCustom(arrPropertyValue, sName)
    Dim lngHwnd
 
    Me.sName = sName
    Me.arrPropertyValue = arrPropertyValue
 
    'Retrieve the handle of the specified window
    lngHwnd = GetCustomWindowHwnd()
 
    'If the handle is valid, then add it to the global collection
    If lngHwnd <> -1 Then
        colObject.Add sName, Window("hwnd:=" & lngHwnd)
        If Not oDict.Exists(lngHwnd) Then
            oDict.Add lngHwnd, lngHwnd
        End If
    End If
End Sub

Next is a method called LaunchAdd, which is dependent upon GetRecentlyOpenWindowHwnd. This will enable you to automatically add a newly launched window to the collection, with the name you specify:

Public Sub LaunchAdd(sFilePath, sName)
    Dim lngHwnd
 
    Me.sFilePath = sFilePath
    Me.sName = sName
 
    'Retrieve the window handle of the recently launched window
    lngHwnd = GetRecentlyOpenWindowHwnd()
 
    'If the handle is valid, then add it to the global collection object
    If lngHwnd <> -1 Then
        colObject.Add sName, Window("hwnd:=" & lngHwnd)
        If Not oDict.Exists(lngHwnd) Then
            oDict.Add lngHwnd, lngHwnd
        End If
    End If
End Sub
 
Private Function GetRecentlyOpenWindowHwnd() 'As Integer
    Dim sFilePath, sName, oDesc, oParent, mHwndDict, x, iTimeElapsed
 
    sFilePath = Me.sFilePath
    sName = Me.sName
 
    GetRecentlyOpenWindowHwnd = -1
 
    On Error Resume Next
 
        'Create a description object
        Set oDesc = Description.Create
 
        'oParent holds references to all the open windows
        Set oParent = Desktop.ChildObjects(oDesc)
 
        'Scripting.Dictionary: holds all open windows' handles
        Set mHwndDict = CreateObject("Scripting.Dictionary")
 
        'Loop until all the handles are successfully added to the collection
        For x = 0 to oParent.Count - 1
            mHwndDict.Add oParent(x).GetROProperty("hwnd"), x
            If Not oDict.Exists(oParent(x).GetROProperty("hwnd")) Then
                oDict.Add oParent(x).GetROProperty("hwnd"), oParent(x).GetROProperty("hwnd")
            End If
        Next
 
        'Launch the target application
        SystemUtil.Run sFilePath
 
        'Loop max 10 seconds for the window to open
        Do
            Set oParent = Desktop.ChildObjects(oDesc)
            For x = 0 to oParent.Count - 1
                Select Case oParent(x).GetTOProperty("micclass")
	       Case "Window", "Dialog"
                        If Not mHwndDict.Exists(oParent(x).GetROProperty("hwnd")) Then
                            GetRecentlyOpenWindowHwnd = oParent(x).GetROProperty("hwnd")
                            Exit Do
                        End If
                End Select
            Next
            Wait(1)
            iTimeElapsed = iTimeElapsed + 1
        Loop Until iTimeElapsed = 10 
 
        Set oDesc = Nothing
        Set oParent = Nothing
        Set mHwndDict = Nothing
 
    On Error Goto 0
End Function

Lastly, and a tricky one is AddNew. This will automatically add any new open window after LaunchAdd has been executed. Like the other 2 methods, this method will also enable preservation of a window’s property until the end of the test.

Public Sub AddNew(sName, iTimeOutBeforeWindowOpens)
    Dim oDesc, oParent, x, iTimeElapsed, lngHwnd
 
    'Set default application timeout
    If iTimeOutBeforeWindowOpens = "" Then
        iTimeOutBeforeWindowOpens = 1
    End If
 
    'Create a Description Object
    Set oDesc = Description.Create
 
    'oParent holds all open windows
    Set oParent = Desktop.ChildObjects(oDesc)
 
    'Wait iTimeOutBeforeWindowOpens number of seconds
    'Default iTimeOutBeforeWindow Opens = 1
    Wait(iTimeOutBeforeWindowOpens)
 
    'Loop for 5 seconds
    'If within 5 seconds, a new unadded window is found, the window will
    ' be added to the collection and this procedure will end.
    Do 
        'Create a new collection
        Set oParent = Desktop.ChildObjects(oDesc)
 
        'Loop for all objects in the collection and find a one that does
        'not exist in the global dictionary: colWindows
        For x = 0 to oParent.Count - 1
            If Not oDict.Exists(oParent(x).GetROProperty("hwnd")) Then
                lngHwnd = oParent(x).GetROProperty("hwnd")
                oDict.Add lngHwnd, lngHwnd
                colObject.Add sName, Window("hwnd:=" & lngHwnd)
                Exit Do
            End If
        Next
        Wait(1)
        iTimeElapsed = iTimeElapsed + 1
    Loop Until iTimeElapsed = 5 'This timeout can be minized to 1, if desired
End Sub

View clsWindow.txt | Download clsWindow.zip | Download Demo v9.2 | Download Demo v9.5

Technically, the concepts in this article can be easily transferred to any technology, just like the concepts were transferred from Web to Windows, which is quite a huge transition. Once this concept is implemented properly, it should help eliminate the need to constantly identify the windows we need to work with.

Subscribe to Relevant Codes (by Anshoo Arora)
Hello! We're always posting interesting articles on Relevant Codes.
Why not subscribe so you don't miss out?

Leave a Comment

{ 14 comments… read them below or add one }

Sophia March 7, 2012 at 2:34 am

I have the same question as above post, Kindly help!

Reply

chandan January 2, 2012 at 1:56 am

I want to verify a window title with all the opened windows in desktop screen.In Qtp what will be the code , which will return me the list of windows title that are opened/minimised.Please help me out in this.

Reply

Anshoo Arora March 15, 2012 at 9:03 am

Chandan/Sophia, there you go:

Set oDesc = Description.Create
Set oBase = Desktop.ChildObjects(oDesc)

For ix = 0 to oBase.Count - 1
    Print oBase(ix).GetROProperty("text")
Next

Reply

prachi May 18, 2011 at 3:27 am

Goal:In my windows application,there is a print operation.When the print command is given ,it goes to MS One note.Now what I need to do is find a way to verify the printed content .For this I need to create AOM for one Note ,read the information and then verify it from MS One Note.
I have tried AOM MS word menthods and properties,but those doesn’t work with One Note.

Below is the description of what I have tried upto now:

I have tried this code:(tried with one note folder open/closed both )

Set obj= CreateObject(“Onenote.application”)
Dim strid
obj.OpenHierarchy “C:\Documents and Settings\pandeypr\Desktop\OneNoteTesting”,”",”strid”
msgbox strid
obj.GetHierarchy “”, hsPages, “strid”
msgbox strid

obj.GetHierarchy “”, hsSections , “strid”
msgbox strid

strid returns nothing in all the cases.
It isn’t working out.pls suggest how to get this done.

msdn link i followed is:http://msdn.microsoft.com/en-us/library/ms788684.aspx#Y4834

Thanks,
Prachi

Reply

Danijela September 19, 2010 at 5:25 pm

I have solved my problem with only using descriptive programming.

Thank you! You helped me a lot with your class. It is working for multiple windows.

Now I need to perform more test one after another. To destroy WindowObject after one test is finished is not enough.
I get Error with message:

Object required: ‘colObject’

Function file: C:\Program Files\HP\QuickTest Professional\Tests\Test7\clsWindow.qfl
Line (131): ” colObject.Add sName, Window(“hwnd:=” & lngHwnd)”.

I need to create new WindowObject for secound test. How can I do that? I am not an expert with VBScript.

Reply

Anshoo Arora September 29, 2010 at 3:01 pm

Danijela,

All variables of one test will be lost as soon as the next test is open. One way to counter this is to store values in an external source (text file, Excel, xml etc.) and read values from the source in each new session.

Reply

Danijela August 17, 2010 at 12:19 pm

I use low-level recording for IE to record flash element.
I use something like this:
WindowObject.LaunchAdd “iexplore.exe”, “Windows Internet Explorer”

and instead of
Window(“Windows Internet Explorer”).WinObject(“MacromediaFlashPlayerActiveX”)
in my code I write
WindowObject.Name(“Windows Internet Explorer”).WinObject(“Name:=MacromediaFlashPlayerActiveX”)
but WinObject is not recognized.
What am I doing wrong?

Reply

Anshoo Arora August 22, 2010 at 4:40 pm

Danijela,

Does the WinObject have a name property that equals to MacromediaFlashPlayerActiveX? Any example that I can use to test this?

Reply

Puneet February 4, 2010 at 2:01 pm

OR would be easier b/c then you don’t have to see a big mess of OR and easy to maintain.

Reply

Anshoo Arora February 4, 2010 at 2:15 pm

Puneet,

In the object’s properties window, you can check the box “regular expression” and add the correct regular expression there (see the post above).

Reply

Puneet February 4, 2010 at 1:57 pm

Which ever is easier.

Reply

Anshoo Arora February 4, 2010 at 2:01 pm

Try this:

SwfWindow(“swfname:=.*Server.*]“).SwfEdit(“swfname:=txtServerIp”).Set IP
SwfWindow("swfname:=.*Login Mode.*")Activate

If its not the swfname property in the object spy for these object, please change it to the correct property. But, the wilcard rule is quite simple here. .* matches any character 0 or more number of times.

Reply

Puneet Varma February 4, 2010 at 1:51 pm

Hi Anshoo,

If you can help me with this problem, how i can get the wildcard on the window name below or the object repository.

SwfWindow(“HA – [Server IP]“).SwfEdit(“txtServerIp”).Set IP
SwfWindow(“HA – [Login Mode]“).Activate
SwfWindow(“HA – [Login Mode]_2″).Activate

Reply

Anshoo Arora February 4, 2010 at 1:55 pm

Hi Puneet,

Do you intend to insert the wildcard through DP or OR?

Reply

Previous post:

Next post: