Forum Discussion

PeterMitcham's avatar
PeterMitcham
Occasional Contributor
10 years ago

GUI Walker test

Hi

 

I was wondering if anyone has created a GUI walker test which they would be willing to share?

 

Ideally i am looking for a test that iterates through all the child objects on a window testing certain properties like enabled, visible, class and default value.

 

Many thanks

 

  •  

    The function GetCollectOfObjects below will return a collection of objects in an array.

    You can pass either the string of the process or the object. I typically pass the object of the main form.

    You can pass either strings or arrays for the arguments PropNames and PropValues

    The Subroutine Main below shows how to iterate throught the array of objects logging their full names.

     

    This is useful if you want to return all the edit boxes (or any other class of objects) that are Visible on the form. 

    The code below automatically adds the Visible property as true.

    The code is basically a wrapper around the FindAllChildren method.

     

    Sub Main

          Dim arrayOfObjects, x
          arrayOfObjects = GetCollectOfObjects(Sys.Process("YourProcess").Window("YourClassname", "YourCaption"), "WndClass", "TjwwDBEdit")
          For x = 0 To UBound(arrayOfObjects)
                If arrayOfObjects(x).Exists = True Then
                      Log.Message arrayOfObjects(x).FullName
                End If
          Next

    End Sub

     

     

    Function GetCollectOfObjects(ProcessNameOrObject, PropNames, PropValues)
          Dim NamesArray, ValuesArray, nvLoopCounter
          If VarType(PropNames) = vbString Then
                NamesArray = Array(PropNames, "Visible")
                ValuesArray = Array(PropValues, True)
          ElseIf VarType(PropNames) => vbArray Then
                NamesArray = PropNames
                ReDim Preserve NamesArray(UBound(NamesArray) + 1)
                NamesArray(UBound(NamesArray)) = "Visible"
                ValuesArray = PropValues
                ReDim Preserve ValuesArray(UBound(ValuesArray) + 1)
                ValuesArray(UBound(ValuesArray)) = True
          Else
                Log.Warning "An unusable data type '" & TypeName(PropNames) & "' was passed for the PropNames argument."
          End If

     

          If VarType(ProcessNameOrObject) = vbString Then
                GetCollectOfObjects = Sys.Process(ProcessNameOrObject).FindAllChildren(NamesArray, ValuesArray, 1000, True)
                nvLoopCounter = 0
                Do While UBound(GetCollectOfObjects) < 0
                      If nvLoopCounter >= 4 Then
                       'Log.Error "Could not locate the object after " & nvLoopCounter & " attempts.", Sys.Process(ProcessNameOrObject).Name

                Exit Do
          End If
                      Sys.Refresh
                      GetCollectOfObjects = Sys.Process(ProcessNameOrObject).FindAllChildren(NamesArray, ValuesArray, 1000, True)
                      nvLoopCounter = nvLoopCounter + 1
                Loop
          ElseIf VarType(ProcessNameOrObject) = vbObject Then
                GetCollectOfObjects = ProcessNameOrObject.FindAllChildren(NamesArray, ValuesArray, 1000, True)
                nvLoopCounter = 0
                Do While UBound(GetCollectOfObjects) < 0
                      If nvLoopCounter >= 4 Then
                            'Log.Error "Could not locate the object after " & nvLoopCounter & " attempts.", ProcessNameOrObject.Name 
                            Exit Do
                      End If
                      Sys.Refresh
                      GetCollectOfObjects = ProcessNameOrObject.FindAllChildren(NamesArray, ValuesArray, 1000, True)
                      nvLoopCounter = nvLoopCounter + 1
                Loop
          Else
                GetCollectOfObjects = Array() ' Return an empty array
                If VarType(PropNames) = vbString Then
                      Log.Warning "An unusable data type '" & TypeName(ProcessNameOrObject) & "' was passed for the control - " & PropNames & " - " & PropValues
                Else
                      Log.Warning "An unusable data type '" & TypeName(ProcessNameOrObject) & "' was passed for the control - " & PropNames(0) & " - " & PropValues(0)
                End If
         End If
    End Function

     

  •  

    The function GetCollectOfObjects below will return a collection of objects in an array.

    You can pass either the string of the process or the object. I typically pass the object of the main form.

    You can pass either strings or arrays for the arguments PropNames and PropValues

    The Subroutine Main below shows how to iterate throught the array of objects logging their full names.

     

    This is useful if you want to return all the edit boxes (or any other class of objects) that are Visible on the form. 

    The code below automatically adds the Visible property as true.

    The code is basically a wrapper around the FindAllChildren method.

     

    Sub Main

          Dim arrayOfObjects, x
          arrayOfObjects = GetCollectOfObjects(Sys.Process("YourProcess").Window("YourClassname", "YourCaption"), "WndClass", "TjwwDBEdit")
          For x = 0 To UBound(arrayOfObjects)
                If arrayOfObjects(x).Exists = True Then
                      Log.Message arrayOfObjects(x).FullName
                End If
          Next

    End Sub

     

     

    Function GetCollectOfObjects(ProcessNameOrObject, PropNames, PropValues)
          Dim NamesArray, ValuesArray, nvLoopCounter
          If VarType(PropNames) = vbString Then
                NamesArray = Array(PropNames, "Visible")
                ValuesArray = Array(PropValues, True)
          ElseIf VarType(PropNames) => vbArray Then
                NamesArray = PropNames
                ReDim Preserve NamesArray(UBound(NamesArray) + 1)
                NamesArray(UBound(NamesArray)) = "Visible"
                ValuesArray = PropValues
                ReDim Preserve ValuesArray(UBound(ValuesArray) + 1)
                ValuesArray(UBound(ValuesArray)) = True
          Else
                Log.Warning "An unusable data type '" & TypeName(PropNames) & "' was passed for the PropNames argument."
          End If

     

          If VarType(ProcessNameOrObject) = vbString Then
                GetCollectOfObjects = Sys.Process(ProcessNameOrObject).FindAllChildren(NamesArray, ValuesArray, 1000, True)
                nvLoopCounter = 0
                Do While UBound(GetCollectOfObjects) < 0
                      If nvLoopCounter >= 4 Then
                       'Log.Error "Could not locate the object after " & nvLoopCounter & " attempts.", Sys.Process(ProcessNameOrObject).Name

                Exit Do
          End If
                      Sys.Refresh
                      GetCollectOfObjects = Sys.Process(ProcessNameOrObject).FindAllChildren(NamesArray, ValuesArray, 1000, True)
                      nvLoopCounter = nvLoopCounter + 1
                Loop
          ElseIf VarType(ProcessNameOrObject) = vbObject Then
                GetCollectOfObjects = ProcessNameOrObject.FindAllChildren(NamesArray, ValuesArray, 1000, True)
                nvLoopCounter = 0
                Do While UBound(GetCollectOfObjects) < 0
                      If nvLoopCounter >= 4 Then
                            'Log.Error "Could not locate the object after " & nvLoopCounter & " attempts.", ProcessNameOrObject.Name 
                            Exit Do
                      End If
                      Sys.Refresh
                      GetCollectOfObjects = ProcessNameOrObject.FindAllChildren(NamesArray, ValuesArray, 1000, True)
                      nvLoopCounter = nvLoopCounter + 1
                Loop
          Else
                GetCollectOfObjects = Array() ' Return an empty array
                If VarType(PropNames) = vbString Then
                      Log.Warning "An unusable data type '" & TypeName(ProcessNameOrObject) & "' was passed for the control - " & PropNames & " - " & PropValues
                Else
                      Log.Warning "An unusable data type '" & TypeName(ProcessNameOrObject) & "' was passed for the control - " & PropNames(0) & " - " & PropValues(0)
                End If
         End If
    End Function

     

    • PeterMitcham's avatar
      PeterMitcham
      Occasional Contributor

      Sorry for the delay in responding.

       

      Thanks very much for the example, I have got it working but I have also come across a rather confusing issue with how objects are passed to functions\routines. I have a solution but I can't quite grasp why this would be the case...

       

      The code below performs the same task in 2 different ways.

       

      Option1. The object is set and used for the FindAllChildren method and is part of the main routine (works as intended)

      Option2. The object is set and passed to a function (ByVal) as the oParent parameter. The function then calls the FindAllChildren method using identical values except they are passed parameters. ( This generates an error when the FindAllChildren method is called that is only really visible in locals or watch list...The GetCollectOfObjects returns the correct number of entries (3) however the value field shows the following error:

      Wrong number of arguments or invalid property assignment: 'GetCollectOfObjects')

       

      I solved the problem by passing the oParent parameter as ByRef, however I am curious as to why this is happening at all.

       

      Sub Main

       

        Dim arrayOfObjects, x, w

       

        Set w = Sys.Process("symphony").WinFormsObject("fLogin2")

       

        NamesArray = Array("ClrClassName", "VisibleOnScreen")
        ValuesArray = Array("Button", True)

       

        arrayOfObjects = w.FindAllChildren(NamesArray, ValuesArray, 100)

       

        For x = 0 To UBound(arrayOfObjects)
          If arrayOfObjects(x).Exists = True Then
            Log.Message arrayOfObjects(x).FullName
          End If
        Next

       

        Log.Message "Start 2nd iteration"
        Erase arrayOfObjects
       
        arrayOfObjects = GetCollectOfObjects(w, NamesArray, ValuesArray)

       

        For x = 0 To UBound(arrayOfObjects)
          If arrayOfObjects(x).Exists = True Then
            Log.Message arrayOfObjects(x).FullName
          End If
        Next
      End Sub

      Function GetCollectOfObjects(ByRef oParent, NamesArray, ValuesArray)

        GetCollectOfObjects = oParent.FindAllChildren(NamesArray, ValuesArray, 100)

      End Function