Ask a Question

GUI Walker test

SOLVED
PeterMitcham
Occasional Contributor

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

 

1 ACCEPTED SOLUTION

Accepted Solutions
EnergizerBunny
Contributor

Re: GUI Walker test

 

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

 

View solution in original post

6 REPLIES 6
EnergizerBunny
Contributor

Re: GUI Walker test

 

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

 

View solution in original post

PeterMitcham
Occasional Contributor

Re: GUI Walker test

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

 

 

 

EnergizerBunny
Contributor

Re: GUI Walker test

I'm not 100% sure, but I think it has to do with the fact that VBScript can refer to an object, but cannot copy it.

 

http://www.4guysfromrolla.com/webtech/050201-1.shtml

 

joseph_michaud
Moderator

Re: GUI Walker test

I don't see it.  Tried it (using Sys.Process("Orders")) and I get no errors regardless of how I specify oParent.

 

( When you set ValuesArray, shouldn't True be a string...?  I don't know offhand how VBScript does the type coercion. )

 

 

-----
Joseph
PeterMitcham
Occasional Contributor

Re: GUI Walker test

It was clearly an environmental issue as after I rebooted the machine I could no longer reproduce the problem


 .

PeterMitcham
Occasional Contributor

Re: GUI Walker test

In the spirit of détente i have attached the GUIWalker test I have created.

 

The idea of the test is that it provides a list of controls in the child structure from a designated parent and compares the returned structure to a baseline. When calling the FindAllChildren method I am only interested in alias entries i have created (this allows me to ignore all the padding you get with dotnet applications)

 

I have been deliberately brief with the list of property and control types I test for, however, it is possible to extend it to whatever level of detail you want (be aware it will slow down the test a fair bit)

 

Where a difference is found it outputs them as warnings. The comparison can handle both differences at the control and property level, outputting not just differences in values but also missing and additional items\properties in both the baseline and received.

 

Should a baseline not exist, it will also create one for you based upon the strucutre it finds.

 

Anyways...Enjoy

cancel
Showing results for 
Search instead for 
Did you mean: