Sign in to follow this  
Followers 0
tester123

AutoIT - Basics

20 posts in this topic

Hi! I am trying to do some automated functional testing for a windows application and I just got my hands on AutoIT. Looks like most (if not all) standard windows applications have a Control ID set. Unfortunately, the Control ID field is blank when i mouse hover using the Finder tool. So looks like the application (written in C) hasnt set a ID to each element? (I did read the help document where it says that the Control ID is the numeric field which Windows provides, but I'm not sure how to make it show up when it doesnt)

I've used XCode's UI Automation for iPad apps and we use "setAccessibilityIdenitifier" to uniquely identify each field. I am trying to find out the equivalent for a Windows application.

That begs the question, is AutoIT even the correct tool? All my testing is calculation based. So you can assume 2 input fields and one output. So if the user enters 5, and 2 and hits "Add", I need to check if the output is 7. So i need to uniquely identify each element.

I also noticed when there is a group of elements, when i hover my mouse over the group, i get "Static" as the classname and only the coordinates change when i try to access each element, and every other control like Instance, ClassNameNN all remain the same. Any ideas?

Thanks a bunch!

Share this post


Link to post
Share on other sites



I usualy use mouseclick when the buttons don't have id's, but this is for clicking, to access values is a different story, and i don't know how to help. :

AutoIt is the correct tool, if you want to do calculations like that.


Spoiler

Paster - Main function is to paste text, but has more functions.

OpenW - Open With... alternative, Open any file with any application, set it's icon, set application as default.

Renamer - Rename files and folders, remove portions of text from the filename etc.

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Firefox Profile Backup - Backup/restore previously saved profile.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

 

Share this post


Link to post
Share on other sites

I usualy use mouseclick when the buttons don't have id's, but this is for clicking, to access values is a different story, and i don't know how to help. :

AutoIt is the correct tool, if you want to do calculations like that.

 

Thanks for the quick reply! Yeah, mouseclick is a good temporary idea. However, i need to uniquely identify all elements on the screen. Like setting identifiers in the C code which then AutoIT can pick up.

Share this post


Link to post
Share on other sites

I'd go with memory searching if no upcoming sugestion works.


Spoiler

Paster - Main function is to paste text, but has more functions.

OpenW - Open With... alternative, Open any file with any application, set it's icon, set application as default.

Renamer - Rename files and folders, remove portions of text from the filename etc.

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Firefox Profile Backup - Backup/restore previously saved profile.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

 

Share this post


Link to post
Share on other sites

I'd go with memory searching if no upcoming sugestion works.

 

Did you mean something like this? -

Is it that "complicated" to read a value on the screen :o

Share this post


Link to post
Share on other sites

Well, something like that yes, but it shouldn't be so complicated, maybe someone else comes up with a simple idea.

Do you really have to use that other application? because you can do almost everything in autoit.


Spoiler

Paster - Main function is to paste text, but has more functions.

OpenW - Open With... alternative, Open any file with any application, set it's icon, set application as default.

Renamer - Rename files and folders, remove portions of text from the filename etc.

BeatsPlayer - Music player.

Params Tool - Right click an exe to see it's parameters or execute them.

Regedit Control - Registry browsing history, quickly jump into any saved key.

Time4Shutdown - Write the time for shutdown in minutes.

Power Profiles Tool - Set a profile as active, delete, duplicate, export and import.

Firefox Profile Backup - Backup/restore previously saved profile.

Finished Task Shutdown - Shuts down pc when specified window/Wndl/process closes.

NetworkSpeedShutdown - Shuts down pc if download speed goes under "X" Kb/s.

 

Share this post


Link to post
Share on other sites

Well, something like that yes, but it shouldn't be so complicated, maybe someone else comes up with a simple idea.

Do you really have to use that other application? because you can do almost everything in autoit.

 

Thanks again! Well, i'm only looking at one tool for automation. XCode's UIAutomation is a tool to automate iPhone/iPad apps and I'm looking at an equivalent to use for a standalone Windows desktop application :)

Share this post


Link to post
Share on other sites

Sometimes you simply just cannot get direct access to controls.

AutoIt uses the windows API and generally can only access standard windows applications created using the windows API, so custom controls can be very tricky is not impossible to access the way you want to with AutoIt.

Your problem is not a unique one, and the next step is to name the application you are trying to Automate and and post the full summary output from window info tool.


AutoIt Absolute Beginners    Require a serial    Pause Script    Video Tutorials by Morthawt   ipify 

Monkey's are, like, natures humans.

Share this post


Link to post
Share on other sites

I also have had a case where some parts of the UI would be impossible to access. I solved the problem by sending key presses instead, simply tab / ctrl-tab and space to "click". I find that even custom controls sometimes support the old Win3.11 keyboard navigation.

"most ways lead to Rome, somehow"


I am just a hobby programmer, and nothing great to publish right now.

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Thanks guys! I'll get more specific as suggested:

1) I have 3 text fields with a label next to it.

Eg: UserName <<textfield1>>

Password <<textfield2>>

Email <<textfield3>>

There doesnt seem to be a direct way of saying hey hit textfield1 and enter "tester". (So, i was wondering if I can add a hook in the original C code that will help AutoIT identify "textfield1")

2)I found a method WinGetText that retrieves all the text on the screen. Now i have a dozen output fields, so the Summary on mouse over looks like

<<some text>>

UserName

Tester

Password

123

Email

blahblah@blah.com

<<some text>>

So I'll have to look up the position of "UserName" and then get the next word that follows to find out the actual value of UserName, which is "tester" in this case, and so on. An ideal scenario would be to tag the value of "UserName" and then all i would have to do is , retrieve the value directly instead of doing tons of String manipulation.

I have to prepare hundreds of scripts and thats why i'm trying to keep it generic. Instead of using coordinates or using the keyboard to navigate. Code that will be easy to manage and re-use.

Every tool has its strengths and its a matter of using the right tool for the right purpose. So i'm just curious if AutoIt is the "ideal" for my purposes. :)

Edited by tester123

Share this post


Link to post
Share on other sites

#11 ·  Posted (edited)

just noticed your first post...let me get a function in here that outputs all the controls on the window...then paste the output back to us...requires the winapi download from example scripts on forum...I've noticed, sometimes, if there is something like a grouping, and that grouping is at a higher zvalue than the controls within it, the info tool is not able to grab/focus on those other controls...this will return ALL controls on the window

#include <Array.au3>
#include <WinAPI.au3>
$hWin = WinGetHandle("yourtitle")
Var_GetAllWindowsControls($hWin)

Func Var_GetAllWindowsControls($hCallersWindow)
;~  $giSubFunctionCounter += 1
    ; Get all list of controls
    $sClassList = WinGetClassList($hCallersWindow)

    ; Create array
    $aClassList = StringSplit($sClassList, @CRLF, 2)

    ; Sort array
    _ArraySort($aClassList)
    _ArrayDelete($aClassList, 0)

    ; Loop
    $iCurrentClass = ""
    $iCurrentCount = 1
    $iTotalCounter = 1

    For $i = 0 To UBound($aClassList) - 1
        If $aClassList[$i] = $iCurrentClass Then
            $iCurrentCount += 1
        Else
            $iCurrentClass = $aClassList[$i]
            $iCurrentCount = 1
        EndIf

        $hControl = ControlGetHandle($hCallersWindow, "", "[CLASSNN:" & $iCurrentClass & $iCurrentCount & "]")
        $text = StringRegExpReplace(ControlGetText($hCallersWindow, "", $hControl),"[\n\r]","{@CRLF}")
        $aPos = ControlGetPos($hCallersWindow, "", $hControl)
        $sControlID = _WinAPI_GetDlgCtrlID($hControl)

        If IsArray($aPos) Then
;~          If $gbPerformLog Then Var_SetLogAndActOnState ( 1, $gbLogLevel_Rtrn, "Var_GetAllWindowsControls()", "Func=[Var_GetAllWindowsControls]: ControlCounter=[" & $iTotalCounter & "] ControlID=[" & $sControlID & "] Handle=[" & $hControl & "] ClassNN=[" & $iCurrentClass & $iCurrentCount & "] XPos=[" & $aPos[0] & "] YPos=[" & $aPos[1] & "] Width=[" & $aPos[2] & "] Height=[" & $aPos[3] & "] Text=[" & $text & "].", False, False)
            ConsoleWrite("Func=[Var_GetAllWindowsControls]: ControlCounter=[" & $iTotalCounter & "] ControlID=[" & $sControlID & "] Handle=[" & $hControl & "] ClassNN=[" & $iCurrentClass & $iCurrentCount & "] XPos=[" & $aPos[0] & "] YPos=[" & $aPos[1] & "] Width=[" & $aPos[2] & "] Height=[" & $aPos[3] & "] Text=[" & $text & "]." & @crlf)
        Else
;~          If $gbPerformLog Then Var_SetLogAndActOnState ( 1, $gbLogLevel_Rtrn, "Var_GetAllWindowsControls()", "Func=[Var_GetAllWindowsControls]: ControlCounter=[" & $iTotalCounter & "] ControlID=[" & $sControlID & "] Handle=[" & $hControl & "] ClassNN=[" & $iCurrentClass & $iCurrentCount & "] XPos=[winclosed] YPos=[winclosed] Width=[winclosed] Height=[winclosed] Text=[" & $text & "].", False, False)
        EndIf
        If Not WinExists($hCallersWindow) Then ExitLoop
        $iTotalCounter+=1
    Next
;~  $giSubFunctionCounter -= 1
EndFunc
Edited by jdelaney
1 person likes this

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

 

just noticed your first post...let me get a function in here that outputs all the controls on the window...then paste the output back to us...requires the winapi download from example scripts on forum...I've noticed, sometimes, if there is something like a grouping, and that grouping is at a higher zvalue than the controls within it, the info tool is not able to grab/focus on those other controls...this will return ALL controls on the window

#include <Array.au3>
#include <WinAPI.au3>
$hWin = WinGetHandle("yourtitle")
Var_GetAllWindowsControls($hWin)

Func Var_GetAllWindowsControls($hCallersWindow)
;~  $giSubFunctionCounter += 1
    ; Get all list of controls
    $sClassList = WinGetClassList($hCallersWindow)

    ; Create array
    $aClassList = StringSplit($sClassList, @CRLF, 2)

    ; Sort array
    _ArraySort($aClassList)
    _ArrayDelete($aClassList, 0)

    ; Loop
    $iCurrentClass = ""
    $iCurrentCount = 1
    $iTotalCounter = 1

    For $i = 0 To UBound($aClassList) - 1
        If $aClassList[$i] = $iCurrentClass Then
            $iCurrentCount += 1
        Else
            $iCurrentClass = $aClassList[$i]
            $iCurrentCount = 1
        EndIf

        $hControl = ControlGetHandle($hCallersWindow, "", "[CLASSNN:" & $iCurrentClass & $iCurrentCount & "]")
        $text = StringRegExpReplace(ControlGetText($hCallersWindow, "", $hControl),"[\n\r]","{@CRLF}")
        $aPos = ControlGetPos($hCallersWindow, "", $hControl)
        $sControlID = _WinAPI_GetDlgCtrlID($hControl)

        If IsArray($aPos) Then
;~          If $gbPerformLog Then Var_SetLogAndActOnState ( 1, $gbLogLevel_Rtrn, "Var_GetAllWindowsControls()", "Func=[Var_GetAllWindowsControls]: ControlCounter=[" & $iTotalCounter & "] ControlID=[" & $sControlID & "] Handle=[" & $hControl & "] ClassNN=[" & $iCurrentClass & $iCurrentCount & "] XPos=[" & $aPos[0] & "] YPos=[" & $aPos[1] & "] Width=[" & $aPos[2] & "] Height=[" & $aPos[3] & "] Text=[" & $text & "].", False, False)
            ConsoleWrite("Func=[Var_GetAllWindowsControls]: ControlCounter=[" & $iTotalCounter & "] ControlID=[" & $sControlID & "] Handle=[" & $hControl & "] ClassNN=[" & $iCurrentClass & $iCurrentCount & "] XPos=[" & $aPos[0] & "] YPos=[" & $aPos[1] & "] Width=[" & $aPos[2] & "] Height=[" & $aPos[3] & "] Text=[" & $text & "]." & @crlf)
        Else
;~          If $gbPerformLog Then Var_SetLogAndActOnState ( 1, $gbLogLevel_Rtrn, "Var_GetAllWindowsControls()", "Func=[Var_GetAllWindowsControls]: ControlCounter=[" & $iTotalCounter & "] ControlID=[" & $sControlID & "] Handle=[" & $hControl & "] ClassNN=[" & $iCurrentClass & $iCurrentCount & "] XPos=[winclosed] YPos=[winclosed] Width=[winclosed] Height=[winclosed] Text=[" & $text & "].", False, False)
        EndIf
        If Not WinExists($hCallersWindow) Then ExitLoop
        $iTotalCounter+=1
    Next
;~  $giSubFunctionCounter -= 1
EndFunc

 

You're the man! Sweet piece of code. Thanks :) Thats a huge leap forward. Miles to go, but a good start :)

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

Might be a lil greedy here, but I would like to know if this is doable:

So now i'm able to access elements within the group...so i have class NN like Button21, Button22, Button23, Static36, Static37,Static 38 etc. I understand that this is Windows driven. Now, assuming i have access to modify the code of the application, Is there anyway i can add hooks to the application code such that i can get custom Class NNs like "ButtonAdd", "ButtonEdit", "ButtonDel", "TextSum", "TextDiff" and so on.

If the answer is yes, what fields must be set in the Application code (developed in C) with standard Windows Controls using Visual Studio..

I'm sure there should be some application developers in here who use AutoIT to test their code.

Edited by tester123

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

I know it can be done...but how is a diff story.

I was developing scripts to automate regression/smoke tests on our app, and step one (to consistently find controls) I had them (dev team) expose the ID's of the controls...I then have a repository of all those id's into variables, and that is shared among all my scripts.  Those values are always fixed, where the classnn can change with addition/removal of some controls

Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

I know it can be done...but how is a diff story.

I was developing scripts to automate regression/smoke tests on our app, and step one (to consistently find controls) I had them (dev team) expose the ID's of the controls...I then have a repository of all those id's into variables, and that is shared among all my scripts.  Those values are always fixed, where the classnn can change with addition/removal of some controls

 

Yeah, thats pretty much what I'm trying to accomplish as well. Glad to know that its doable though! Perhaps i should read some Windows documentation or find out from the msdn forums :)

Share this post


Link to post
Share on other sites

I have tried this code, and changed the name "yourtitle", I do not seem to be getting anything different? I am I doing something wrong?

jdelaney, on 21 May 2013 - 5:03 PM, said:

#include &lt;Array.au3&gt;
#include &lt;WinAPI.au3&gt;
$hWin = WinGetHandle("yourtitle")
Var_GetAllWindowsControls($hWin)

Func Var_GetAllWindowsControls($hCallersWindow)
;~  $giSubFunctionCounter += 1
    ; Get all list of controls
    $sClassList = WinGetClassList($hCallersWindow)

    ; Create array
    $aClassList = StringSplit($sClassList, @CRLF, 2)

    ; Sort array
    _ArraySort($aClassList)
    _ArrayDelete($aClassList, 0)

    ; Loop
    $iCurrentClass = ""
    $iCurrentCount = 1
    $iTotalCounter = 1

    For $i = 0 To UBound($aClassList) - 1
        If $aClassList[$i] = $iCurrentClass Then
            $iCurrentCount += 1
        Else
            $iCurrentClass = $aClassList[$i]
            $iCurrentCount = 1
        EndIf

        $hControl = ControlGetHandle($hCallersWindow, "", "[CLASSNN:" &amp; $iCurrentClass &amp; $iCurrentCount &amp; "]")
        $text = StringRegExpReplace(ControlGetText($hCallersWindow, "", $hControl),"[\n\r]","{@CRLF}")
        $aPos = ControlGetPos($hCallersWindow, "", $hControl)
        $sControlID = _WinAPI_GetDlgCtrlID($hControl)

        If IsArray($aPos) Then
;~          If $gbPerformLog Then Var_SetLogAndActOnState ( 1, $gbLogLevel_Rtrn, "Var_GetAllWindowsControls()", "Func=[Var_GetAllWindowsControls]: ControlCounter=[" &amp; $iTotalCounter &amp; "] ControlID=[" &amp; $sControlID &amp; "] Handle=[" &amp; $hControl &amp; "] ClassNN=[" &amp; $iCurrentClass &amp; $iCurrentCount &amp; "] XPos=[" &amp; $aPos[0] &amp; "] YPos=[" &amp; $aPos[1] &amp; "] Width=[" &amp; $aPos[2] &amp; "] Height=[" &amp; $aPos[3] &amp; "] Text=[" &amp; $text &amp; "].", False, False)
            ConsoleWrite("Func=[Var_GetAllWindowsControls]: ControlCounter=[" &amp; $iTotalCounter &amp; "] ControlID=[" &amp; $sControlID &amp; "] Handle=[" &amp; $hControl &amp; "] ClassNN=[" &amp; $iCurrentClass &amp; $iCurrentCount &amp; "] XPos=[" &amp; $aPos[0] &amp; "] YPos=[" &amp; $aPos[1] &amp; "] Width=[" &amp; $aPos[2] &amp; "] Height=[" &amp; $aPos[3] &amp; "] Text=[" &amp; $text &amp; "]." &amp; @crlf)
        Else
;~          If $gbPerformLog Then Var_SetLogAndActOnState ( 1, $gbLogLevel_Rtrn, "Var_GetAllWindowsControls()", "Func=[Var_GetAllWindowsControls]: ControlCounter=[" &amp; $iTotalCounter &amp; "] ControlID=[" &amp; $sControlID &amp; "] Handle=[" &amp; $hControl &amp; "] ClassNN=[" &amp; $iCurrentClass &amp; $iCurrentCount &amp; "] XPos=[winclosed] YPos=[winclosed] Width=[winclosed] Height=[winclosed] Text=[" &amp; $text &amp; "].", False, False)
        EndIf
        If Not WinExists($hCallersWindow) Then ExitLoop
        $iTotalCounter+=1
    Next
;~  $giSubFunctionCounter -= 1
EndFunc

All by me:

"Sometimes you have to go back to where you started, to get to where you want to go." 

"Everybody catches up with everyone, eventually" 

"As you teach others, you are really teaching yourself."

From my dad

"Do not worry about yesterday, as the only thing that you can control is tomorrow."

 

WindowsError.gif

WIKI | Tabs; | Arrays; | Strings | Wiki Arrays | How to ask a Question | Forum Search | FAQ | Tutorials | Original FAQ | ONLINE HELP | UDF's Wiki | AutoIt PDF

AutoIt Snippets | Multple Guis | Interrupting a running function | Another Send

StringRegExp | StringRegExp Help | RegEXTester | REG TUTOR | Reg TUTOT 2

AutoItSetOption | Macros | AutoIt Snippets | Wrapper | Autoit  Docs

SCITE | SciteJump | BB | MyTopics | Programming | UDFs | AutoIt 123 | UDFs Form | UDF

Learning to script | Tutorials | Documentation | IE.AU3 | Games? | FreeSoftware | Path_Online | Core Language

Programming Tips

Excel Changes

ControlHover.UDF

GDI_Plus

Draw_On_Screen

GDI Basics

GDI_More_Basics

GDI Rotate

GDI Graph

GDI  CheckExistingItems

GDI Trajectory

Replace $ghGDIPDll with $__g_hGDIPDll

DLL 101?

Array via Object

GDI Swimlane

GDI Plus French 101 Site

GDI Examples UEZ

GDI Basic Clock

GDI Detection

Ternary operator

Share this post


Link to post
Share on other sites

#19 ·  Posted (edited)

All it will do is output the window handle's controls to your console.  You should validate you pull the proper win handle, prior to calling the function.

Edited by jdelaney

IEbyXPATH-Grab IE DOM objects by XPATH IEscriptRecord-Makings of an IE script recorder ExcelFromXML-Create Excel docs without excel installed GetAllWindowControls-Output all control data on a given window.

Share this post


Link to post
Share on other sites

Anything different from what?

No matter what window title I put in the "yourtitle", I get the same results (the output on the cosole). Tried again today, and now I am getting different results


All by me:

"Sometimes you have to go back to where you started, to get to where you want to go." 

"Everybody catches up with everyone, eventually" 

"As you teach others, you are really teaching yourself."

From my dad

"Do not worry about yesterday, as the only thing that you can control is tomorrow."

 

WindowsError.gif

WIKI | Tabs; | Arrays; | Strings | Wiki Arrays | How to ask a Question | Forum Search | FAQ | Tutorials | Original FAQ | ONLINE HELP | UDF's Wiki | AutoIt PDF

AutoIt Snippets | Multple Guis | Interrupting a running function | Another Send

StringRegExp | StringRegExp Help | RegEXTester | REG TUTOR | Reg TUTOT 2

AutoItSetOption | Macros | AutoIt Snippets | Wrapper | Autoit  Docs

SCITE | SciteJump | BB | MyTopics | Programming | UDFs | AutoIt 123 | UDFs Form | UDF

Learning to script | Tutorials | Documentation | IE.AU3 | Games? | FreeSoftware | Path_Online | Core Language

Programming Tips

Excel Changes

ControlHover.UDF

GDI_Plus

Draw_On_Screen

GDI Basics

GDI_More_Basics

GDI Rotate

GDI Graph

GDI  CheckExistingItems

GDI Trajectory

Replace $ghGDIPDll with $__g_hGDIPDll

DLL 101?

Array via Object

GDI Swimlane

GDI Plus French 101 Site

GDI Examples UEZ

GDI Basic Clock

GDI Detection

Ternary operator

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0