Daily automation: taking screenshots unleashed
By default, UIAutomation saves a screenshot if a cmdlet fails. This behavior is set by the default settings:
ipmo [path]\UIAutomation.dll [UIAutomation.Preferences]::OnErrorScreenShot [UIAutomation.Preferences]::ScreenShotFolder
The default folder for storing screenshots is user’s TEMP. Taking a screenshot can be initiated manually, below is how to do it:
ipmo [path]\UIAutomation.dll # saves the desktop Save-UIAScreenshot Save-UIAScreenshot -Description 123
The former line of code creates a file in the TEMP folder, for example: %USERPROFILE%\AppData\Local\Temp\20129261311418.bmp. The latter creates a file with more recognizable name: %USERPROFILE%\AppData\Local\Temp\20129261315161_123.bmp. Wanted better file names? Consider the following piece of code:
ipmo [path]\UIAutomation.dll # saves the desktop to a specified file Save-UIAScreenshot -Path c:\1 -Name 20120921_1.bmp
After we have discussed where we can save a screenshot, it’s time to discuss what can be saved. All the samples above saved the desktop – a reasonable choice if you don’t exactly know what the situation is when test fails. We can save a window, to the TEMP folder or to a folder of your choice:
ipmo [path]\UIAutomation.dll # saves a window Start-Process calc -PassThru | Get-UIAWindow | Save-UIAScreenshot # saves a window to the specified file Start-Process calc -PassThru | Get-UIAWindow | Save-UIAScreenshot -Path c:\1 -Name 20120921_2.bmp # throws an exception 'Save-UIAScreenshot : File 'c:\1\20120921_2.bmp' already exists' Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -n 1 | Save-UIAScreenshot -Path c:\1 -Name 20120921_2.bmp
It’s not cmdlet’s concern if the file you specified already exists, so that it’s up to you to resolve such situations as shown in the code snipped above.
Finally, we can save any control, with or without a handle. The legend says that a control with handle is a window even if it’s a mere control. Times changes, controls without handles are now seen by UIAutomation as windows too. Here we get a button’s screenshot:
ipmo [path]\UIAutomation.dll # saves a button to the specified file Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -n 1 | Save-UIAScreenshot -Path c:\1 -Name 20120921_3.bmp
The advantage of automation (as well as of UIAutomation) is that you can automate even already automated things. Ten screenshots at a time? It’s possible, below we produce screenshots for each of numeric buttons:
ipmo [path]\UIAutomation.dll # generates a screenshot for each numeric button (ten screenshots) Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -SearchCriteria @{automationid='13*'} | Save-UIAScreenshot
Daily automation: more ways to perform a search
Initially, UIAutomation worked only with exact names, so that getting a control with several search conditions was an almost impossible thing:
ipmo [path]\UIAutomation.dll Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -n 1;
When support of wildcards was introduced, search became useful as it was never before:
ipmo [path]\UIAutomation.dll Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -n a*; Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -n [0-9];
Nonetheless, even with wildcards, search capabilities were not so friendly as they could be. Thus, the search criteria were added to Get- cmdlets as they have already been in the Test-UIAControlState and Wait-UIAcontrolState cmdlets.
The code samples below return the same – numeric buttons in Calculator:
ipmo [path]\UIAutomation.dll Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -Name [0-9]; Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -AutomationId '13*'; Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -SearchCriteria @{Name="[0-9]"}; Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -SearchCriteria @{automationid="13*"}; Start-Process calc -PassThru | Get-UIAWindow | Get-UIAControl -SearchCriteria @{Name="[0-9]"}; Start-Process calc -PassThru | Get-UIAWindow | Get-UIAControl -SearchCriteria @{automationid="13*"};
Why do we need more ways for search? Sometimes, we need some kind of grouping of controls:
ipmo [path]\UIAutomation.dll Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -SearchCriteria @{Name="[0-9]"},@{name="c*"}; Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton -SearchCriteria @{automationid="13*"},@{name="a*"};
In the sample, the first search returns numeric buttons plus the Clear, Clear entry and Close (a cross) buttons. The latter returns numeric buttons and the Add button.
There might also be searches like:
ipmo [path]\UIAutomation.dll Start-Process calc -PassThru | Get-UIAWindow | Get-UIAControl -SearchCriteria @{isoffscreen="true"}; Start-Process calc -PassThru | Get-UIAWindow | Get-UIAControl -SearchCriteria @{isenabled="false"};
What’s more, ‘search criteria’ strings (that are natural PowerShell hashtables) are way to store queries in a text file or a database instead of storing lines of code.