Daily automaiton: how to deal with windows?


On the project forum, questions about windows have been posted today. I think, the community is interesting in he answers.

Question:

Please, give some examples how to wait for new window with unpredictable Name value(it can be various error or notify messages)?; how to enumerate all opened windows? I want to remove windows to clean desktop after unsuccessful run of application.

Answer:

1) how to wait for a new window with random Name?

first of all, there are ways to take a window by its ProcessId/pid, ProcessName/pn and its process object. If you issue the process, all the following would work:

# you've set a name for process somewhere in the code
$processName = "calc";

# get the window by its process id
Get-UIAWindow -pid (Start-Process $processName -PassThru).Id

# get the window by its process name
Get-UIAWindow -pn (Start-Process $processName -PassThru).ProcessName

second, you also can use a part of its name (supposing that some part of a name is uncahngeble from run to run);

Start-Process calc; Get-UIAWindow -n *lato*

Note that rare windows that are not seen by MS Automation and could be found by using FindWindow, still don’t support wild cards (it will be done relatively soon). I know only one such an example: on a 64-bit OS, a 32-bit MMC snap-in that is not shown in the TaskBar, runs its own window instead of the main MMC window (It’s really rare case).
 

2) Which opened windows do you want to enumerate?

2.1) window with known to you a part of name:

Start-Process calc; Start-Process calc; Start-Process calc;
Get-UIADesktop | Get-UIAControlChildren -ControlType Window | ?{$_.Current.Name.Contains("alcu")}

2.2) if you need to collect all the dialog of the application under test, there is search down the Automaiton tree

# you should run PowerShell as Asministrator to reproduce this test
Start-Process services.msc -PassThru | Get-UIAWindow | Get-UIAMenuItem -Name File | Invoke-UIAMenuItemClick | Get-UIAMenuItem -Name Opt* | Invoke-UIAMenuItemClick;

# now we have several windows in the process mmc: the main window, the Options window 
# and one or more internal frames of mmc itself
# as mmc has windows called snap-ins (or possibly even more windows I'm not aware of)

# in the code below, you don't need to use the Get-UIAWindow cmdlet
# because the last window you've successfully gotten
# stored in the [UIAutomation.CurrentData]::CurrentWindow variable
Get-UIAControlDescendants -ControlType Window | %{$_.Current.Name;}

# in this case, we have gotten only two windows, both with names
# in more complicated cases, you need to use several properties to select a window
Get-UIAControlDescendants -ControlType Window | %{Write-Host "$($_.Current.Name)`t$($_.Current.AutomaitonId)`t$($_.Current.ClassName)";}

there also are Search- cmdlets, but these are considered legacy as they use TreeWalker what means more cross-process callc during the test:

# the search for a specified window
Search-UIAControl -Name Options -ControlType Window
# the code assumes that you already have the main window
# and the same as the code:
[UIAutomation.CurrentData]::CurrentWindow | Search-UIAControl -Name Options -ControlType Window

As can be seen, the Search-UIAControl cmdlet is more specific (like every good search), whereas Get-UIAControlDescendants returns all that is of type specified.

2.3) if you need to catch inexplicable windows like a dialog in the process of the application under test, use the Register-UIAWindowsOpenedEvent cmdlet (it’s recommended to use also the Unregister-UIAEvent cmdlet from time to time during the test suite):

Start-Process services.msc -PassThru | Get-UIAWindow | Register-UIAWindowOpenedEvent -EventAction {param($src, $e) [System.Windows.Forms.MessageBox]::Show("A new window is open: $($src.Cached.Name)");};
Get-UIAMenuItem -Name File | Invoke-UIAMenuItemClick | Get-UIAMenuItem -Name Opt* | Invoke-UIAMenuItemClick;

2.4) finally, if you need to catch a windows of another process that appears during the test, use the standard Register-WMIObjectEvent cmdlet (there are a lot of ways to write the code as parameters of the cmdlet can be used in various combinaitons):

the smaple from Richard Siddaway’s Blog: http://msmvps.com/blogs/richardsiddaway/archive/2009/11/07/powershell-wmi-events.aspx

3) you can eliminate processes, it’s the best choise in many situations

Start-Process calc; Start-Process calc; Start-Process calc;
Stop-Process -Name calc

However, some applications should save their data or close connections before exiting, so that you need to use something like in the item 2.1 (Get-UIADesktop | Get-UIAControlChildren: main windows are always children of the desktop) to get all of them to perform exit via main menu or hitting the Close button…

 

Advertisements

One response

  1. Thanks for the answers… it really helped me a lot

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

%d bloggers like this: