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.
{ 14 comments… read them below or add one }
I have the same question as above post, Kindly help!
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.
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") NextGoal: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
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.
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.
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?
Danijela,
Does the WinObject have a name property that equals to MacromediaFlashPlayerActiveX? Any example that I can use to test this?
OR would be easier b/c then you don’t have to see a big mess of OR and easy to maintain.
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).
Which ever is easier.
Try this:
SwfWindow(“swfname:=.*Server.*]“).SwfEdit(“swfname:=txtServerIp”).Set IP SwfWindow("swfname:=.*Login Mode.*")ActivateIf its not the
swfnameproperty 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.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
Hi Puneet,
Do you intend to insert the wildcard through DP or OR?