My own Excel Automation Framework (GUI FUNCTIONS)—–Part 4 Automating the Calculator application:

Windows default Calculator Test Automation

  • I have chosen the default Calculator application for Automation as it will help demonstrate       automation of a variety of UI elements and operations.
  • In this post, I will continue to work further on MyOwnExcelFramework.xlsm workbook,       as we did in the part 1 ,2 and 3 of the tutorial, Here I will just put in a note of caution that going forward it is mandatory that you read part 1 ,2 and 3 of the tutorial, as in this tutorial, I will be using the same base and extending its functionality to handle UI elements /control.
  • We will continue in the same excel workbook (MyOwnExcelframework.xlsm), in the VBA module.
  • In the project window ,click at VBAProject (MyOwnExcelframework.xlsm)       highlighting the same, right click VBAProject (MyOwnExcelframework.xlsm),click Insert Module, It will insert a module with default name Module2.
  • Change the name of the module from Module2       to”GUIFUNCTIONS”, from now on we will have 3 .bas files in the module folder,( i.e BrowserFunctions, GUIFUNCTIONS,Module1).

project vba

 

  • All our Gui elements handling code will reside in the module ” GUIFUNCTIONS” which has an extension .bas and is a text file. This will help us address the version control challenges.
  • The project references remain same as mentioned in part 2.
  • In the code window ,In the declarations section make the below declarations.

Private dblProcesID As Double

Private Declare Function FindWindow Lib “User32” Alias “FindWindowA” (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Declare Function FindWindowEx Lib “User32” Alias “FindWindowExA” (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long

Private Declare Function SendMessage Lib “User32” Alias “SendMessageA” (ByVal hwnd As Long, ByVal wMsg As Long, ByVal wParam As Integer, ByVal lParam As Any) As Long

Public Declare Function GetWindowText Lib “User32” Alias “GetWindowTextA” (ByVal hwnd As Long, ByVal lpString As String, ByVal cchar As Long) As Long

Public Declare Function GetWindowTextLength Lib “User32” Alias “GetWindowTextLengthA” (ByVal hwnd As Long) As Long

Public Declare Function GetClassName Lib “User32” Alias “GetClassNameA” (ByVal hwnd As Long, ByVal lpString As String, ByVal cchar As Long) As Long

Private Const WM_SETTEXT = &HC

Private Const BM_CLICK = &HF5

DECLARATION

  • Copy our first procedure for starting an application as below. Note       this is a parameterized function and can be used to start any app whose path is given in the 5th column of the appropriate row in the Run Manager. Also we are capturing the       Process id and declaring it in the declaration section making it available to all procedures and functions in the module. The Process id is subsequently used in the CloseApp & ActivateApp procedures.

Public Sub RunApp()

Dim strAppPath As String

10   On Error GoTo Error_Handler

20   strAppPath = Worksheets(“RunManager”).Cells(m, 5)

30   dblProcesID = Shell(strAppPath, vbNormalFocus)

40   Exit Sub

Error_Handler:

50   Handle_Error “RunApp”, Erl

End Sub
RUN APP

  • The procedure for Activate App which is called by other procedures as below.

Public Sub ActivateApp()

10   On Error GoTo Error_Handler

20   AppActivate CLng(dblProcesID)

30   Exit Sub

Error_Handler:

40   Handle_Error “ActivateApp”, Erl

End Sub

  • The function (Return_Window) loops thru 3 levels of child window , Each child window handle along with expected button caption and button class is in turn passed to Match_Attribute function which retrieves the actual class and text of the window handle and matches it with the expected values, it returns true if match is in order and a false if there is no match.

Private Function Return_Window(strMainWindowTitle As String, strButtonClass As String, strButtonName As String) As Long

Dim lngParenthandle As Long

Dim lngChildhandle As Long

Dim lngWindHndlArray3(15, 15, 75) As Long

Dim lngWindHndlArray1(15) As Long

Dim lngWindHndlArray2(15, 15) As Long

Dim intx As Integer

Dim inty As Integer

Dim intz As Integer

10   On Error GoTo Error_Handler

20   intx = 1

30   inty = 1

40   intz = 1

50   lngParenthandle = FindWindow(vbNullString, strMainWindowTitle)

60   If lngParenthandle <> 0 Then ‘ Parent found

70   lngChildhandle = FindWindowEx(lngParenthandle, 0, vbNullString, vbNullString)

80   Else

90   Log_Test “Parent Handle Not Found”

100   Exit Function

110   End If

120       Do While lngChildhandle <> 0   ‘1st Level Child Found

130     If Match_Attribute(lngChildhandle, strButtonClass, strButtonName) = True Then

140         Return_Window = lngChildhandle

150           Exit Function

160     End If

 

170     lngWindHndlArray1(intx) = lngChildhandle

180     lngChildhandle = FindWindowEx(lngParenthandle, lngChildhandle, vbNullString, vbNullString)

190         If lngChildhandle = 0 Then ‘ 1st dimension over

200         Exit Do

210         End If

220         intx = intx + 1

230       Loop

‘ procedure for second level child

 

240             For n = 1 To intx

250             lngParenthandle = lngWindHndlArray1(n)

260             lngChildhandle = FindWindowEx(lngParenthandle, 0, vbNullString, vbNullString)

270             inty = 1

280                 Do While lngChildhandle <> 0

290                     If Match_Attribute(lngChildhandle, strButtonClass, strButtonName) = True Then

300                     Return_Window = lngChildhandle

310                     Exit Function

320                     End If

330                     lngWindHndlArray2(n, inty) = lngChildhandle

340                     lngChildhandle = FindWindowEx(lngParenthandle, lngChildhandle, vbNullString, vbNullString)

350                         If lngChildhandle = 0 Then ‘ 1st dimension over

360                         Exit Do

370                         End If

380                     inty = inty + 1

390                 Loop

400             Next n

‘procedure for third level child

410         For n = 1 To intx

420         For o = 1 To UBound(lngWindHndlArray2, n)

430         lngParenthandle = lngWindHndlArray2(n, o)

440         If lngParenthandle = 0 Then

450             Exit For

460         End If

470             lngChildhandle = FindWindowEx(lngParenthandle, 0, vbNullString, vbNullString)

480             intz = 1

490                 Do While lngChildhandle <> 0

500                     If Match_Attribute(lngChildhandle, strButtonClass, strButtonName) = True Then

510                     Return_Window = lngChildhandle

520                     Exit Function

530                     End If

540                     lngWindHndlArray3(n, o, intz) = lngChildhandle

550                     lngChildhandle = FindWindowEx(lngParenthandle, lngChildhandle, vbNullString, vbNullString)

560                         If lngChildhandle = 0 Then ‘ 1st dimension over

570                         Exit Do

580                         End If

590                     intz = intz + 1

600                 Loop

610             Next o

620             Next n

630   Exit Function

Error_Handler:

640   Handle_Error “Return_Window”, Erl

 

End Function

  • The function (Match_Attribute) as under.

Private Function Match_Attribute(lngWindowHandleM As Long, strButtonClassM As String, strButtonNameM As String) As Boolean

Dim strClassname As String

Dim strWindowtext As String

10   On Error GoTo Error_Handler

20           strWindowtext = Space(GetWindowTextLength(lngWindowHandleM) + 1)

30           strClassname = Space(256)

40           GetWindowText lngWindowHandleM, strWindowtext, Len(strWindowtext)

50           GetClassName lngWindowHandleM, strClassname, Len(strClassname)

60               If Left(strWindowtext$, Len(strWindowtext$) – 1) = vbNullString Then

70               Match_Attribute = False

80               Exit Function

90               End If

100           If Left(strWindowtext$, Len(strWindowtext$) – 1) = strButtonNameM$ Then

110               If Left(strClassname, Len(strButtonClassM)) = strButtonClassM Then

120               Match_Attribute = True

130               Else

140               Match_Attribute = False

150               Log_Test “Control Name Mismatch”

160               End If

170           Else

180           Match_Attribute = False

‘Log_Test “Class Name Mismatch”

190           End If

200           Exit Function

Error_Handler:

210   Handle_Error “Match_Attribute”, Erl

End Function

  • The procedure to read text from display window is       (Get_Text) , as text is a window where your window text is dynamic , hence we can’t use the Return_Window function, As explained earlier there are 2 approaches in such scenarios. i.e use of Control Id, Windows Position/Hierarchy Order. I have used Windows Position/Hierarchy Order to identify my textbox. As evident from object map row no 8, the textbox hierarchy order is 1,2,3. refer illustration below.

OBJECT  MAP

We pass this hierarchy order as “01,02,03” in 6th column of respective row in the RunManager as illustrated below.
GET  TEXT

  •  Get_Text in turn calls procedure Return_Hwndarray , A 3 dimension array is passed byref to Return_Hwndarray alongwith title of parent window. Details of Get_Text &       Return_Hwndarray procedure is as under.

Public Sub Get_Text()

Dim strWindowtext As String

Dim lngWindhwndarray(15, 15, 75) As Long

Dim lngTexthwnd As Long

Dim strWindoworder As String

Dim intl As Integer

Dim intm As Integer

Dim intn As Integer

Dim lngWindowtext As Integer

10   On Error GoTo Error_Handler

20   strWindowtext = Worksheets(“RunManager”).Cells(m, 5)

30   strWindoworder = Worksheets(“RunManager”).Cells(m, 6)

40   intl = Mid(strWindoworder, 1, 2)

50   intm = Mid(strWindoworder, 4, 2)

60   intn = Mid(strWindoworder, 7, 2)

70   Return_Hwndarray strWindowtext, lngWindhwndarray()

80   lngTexthwnd = lngWindhwndarray(intl, intm, intn)

90   strWindowtext = Space(GetWindowTextLength(lngTexthwnd) + 1)

100   GetWindowText lngTexthwnd, strWindowtext, Len(strWindowtext)

110   strWindowtext = Left(strWindowtext, Len(strWindowtext) – 1)

‘lngWindowtext = CLng(strWindowtext)

‘Worksheets(“RunManager”).Cells(m, 7) = lngWindowtext

120   Worksheets(“RunManager”).Cells(m, 7) = strWindowtext

130   Worksheets(“RunManager”).Cells(m, 7).Font.Italic = True

140   Exit Sub

Error_Handler:

150   Handle_Error “Get_Text”, Erl

End Sub

 

Private Sub Return_Hwndarray(strMainWindowTitle As String, ByRef lngWindhwndarray() As Long)

Dim lngParenthandle As Long

Dim lngChildhandle As Long

‘Dim lngWindHndlArray3(15, 15, 75) As Long

Dim lngWindHndlArray1(15) As Long

Dim lngWindHndlArray2(15, 15) As Long

Dim intx As Integer

Dim inty As Integer

Dim intz As Integer

10   On Error GoTo Error_Handler

20   intx = 1

30   inty = 1

40   intz = 1

50   lngParenthandle = FindWindow(vbNullString, strMainWindowTitle)

60   If lngParenthandle <> 0 Then ‘ Parent found

70   lngChildhandle = FindWindowEx(lngParenthandle, 0, vbNullString, vbNullString)

80   Else

90   Log_Test “Parent Handle Not Found”

100   Exit Sub

110   End If

120       Do While lngChildhandle <> 0   ‘1st Level Child Found

130     lngWindHndlArray1(intx) = lngChildhandle

140     lngChildhandle = FindWindowEx(lngParenthandle, lngChildhandle, vbNullString, vbNullString)

150         If lngChildhandle = 0 Then ‘ 1st dimension over

160         Exit Do

170         End If

180         intx = intx + 1

190       Loop

‘ procedure for second level child

200             For n = 1 To intx

210             lngParenthandle = lngWindHndlArray1(n)

220             lngChildhandle = FindWindowEx(lngParenthandle, 0, vbNullString, vbNullString)

230             inty = 1

240                 Do While lngChildhandle <> 0

250                     lngWindHndlArray2(n, inty) = lngChildhandle

260                     lngChildhandle = FindWindowEx(lngParenthandle, lngChildhandle, vbNullString, vbNullString)

270                         If lngChildhandle = 0 Then ‘ 1st dimension over

280                         Exit Do

290                         End If

300                     inty = inty + 1

310                 Loop

320             Next n

‘procedure for third level child

330         For n = 1 To intx

340         For o = 1 To UBound(lngWindHndlArray2, n)

350         lngParenthandle = lngWindHndlArray2(n, o)

360         If lngParenthandle = 0 Then

370             Exit For

380         End If

390             lngChildhandle = FindWindowEx(lngParenthandle, 0, vbNullString, vbNullString)

400             intz = 1

410                 Do While lngChildhandle <> 0

420                     lngWindhwndarray(n, o, intz) = lngChildhandle

430                     lngChildhandle = FindWindowEx(lngParenthandle, lngChildhandle, vbNullString, vbNullString)

440                         If lngChildhandle = 0 Then ‘ 1st dimension over

450                         Exit Do

460                         End If

470                     intz = intz + 1

480                 Loop

490             Next o

500             Next n

510   Exit Sub

Error_Handler:

520   Handle_Error “Return_Hwndarray”, Erl

End Sub

  • We close the application with our procedure Close App. Note that no parameters are passed to CloseApp procedure, yet CloseApp needs the process id of the application it wants to close, This process id is generated while       launching the application RunApp.

Public Sub CloseApp()

Dim strKillcmd As String

10   On Error GoTo Error_Handler

20   strKillcmd = “C:\Windows\System32\taskkill.exe /PID ” & CStr(dblProcesID) & ” /T”

‘strKillcmd = “” & strKillcmd & “”

30   Shell strKillcmd

40   Exit Sub

Error_Handler:

50   Handle_Error “CloseApp”, Erl

End Sub

 

  • I have created a procedure for Wait, we use this in the Run_Manager procedure on sheet1.here the wait time is parameterized in seconds.

Public Sub Wait(sngWaitTime As Single)

10   On Error GoTo Error_Handler

20   newHour = Hour(Now())

30   newMinute = Minute(Now())

40   newSecond = Second(Now()) + sngWaitTime

50   waitTime = TimeSerial(newHour, newMinute, newSecond)

60   Application.Wait waitTime

70   Exit Sub

Error_Handler:

80   Handle_Error “Wait”, Erl

End Sub

  • I believe we have good nos. of procedures for POC on the GUI Automation , architecture and flexibility aspect of the framework.
  • Its time to write our first test case.
  • Go back to the excel worksheet, In Worksheet “Run Manager” create       the   Header as under in Bold.
    • Row  9 Column   C   Header label as   “Procedure/Test Step Name”
    • Row  9 Column   D   Header label as “Exe”
    • Row  9 Column   E   Header label as “Control Identifier”
    • Row  9 Column   F   Header label as “Data to be Passed”
  • Your Test case starts from Row nos 10. Test Step       1 as under..
    • Row  10 Column   C  as         “RunApp”
    • Row  10 Column   D  as        “Y”
    • Row  10 Column   E  as       “C:\Windows\System32\calc.exe”
  • Test Step 2 to 11 as under. (Row 11 to Row 22)
    • Row 11 to 22 Column   C         as   “ClickButton”
    • Row 11 to 22 Column   D        as   “Y”
    • Row 11 to 22 Column   E         as   “Calculator”
    • Row 11 to 22 Column   F         as   “Button”
  • Test Step 2 to 11 as under. (Row 11 to Row 22)
    • Row 11       Column   G as         “9”
    • Row 12       Column   G as         “8”
    • Row 13       Column   G as         “7”
    • Row 14       Column   G as         “6”
    • Row 15       Column   G as         “5”
    • Row 16       Column   G as         “*”
    • Row 17       Column   G as         “4”
    • Row 18       Column   G as         “3”
    • Row 19       Column   G as         “2”
    • Row 20       Column   G as         “1”
    • Row 21       Column   G as         “0”
    • Row 22       Column   G as         “=”
  • Test Step 12 as under.
    • Row 23 Column   C        as   “Get_Text”
    • Row 23 Column   D        as   “Y”
    • Row 23 Column   E        as   “Calculator”
    • Row 23 Column   F        as   “01,02,03”
  • Test Step 13 as under.
    • Row 23 Column   C       as   “ClickButton”
    • Row 23 Column   D       as   “Y”
    • Row 23 Column   E       as   “Calculator”
    • Row 23 Column   F       as   “Button”
    • Row 23 Column   G      as   “CE”
  • Test Step 14 as under.
    • Row 24 Column   C       as   “CloseApp”
    • Row 24 Column   D       as “Y”

RUN Manager

  • We have Our first test case ready to execute.
  • Just click at RunManager
  • To download the framework with functions discussed so far . visit the link..MyOwnExcelframeworkpart4

download framework

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s