Category Archives: UIAutomation module

UIAutomation and PowerBuilder 12.5

Many years ago, in 1999-2000, I used to use PowerBuilder. At first, it was 5.2 (a pretty buggy and unstable version as I remember), later I used 7.0. Even in these times, PowerBuilder has been collapsing. Delphi, Visual Basic, Crystal Reports, many newcomers struggled for that tasteful market, visual access to databases.

After, I tried 8.0. These times I thought that, as the majority of successful and lucrative start-ups, PowerBuilder was bought for the purpose to obtain its customers only, not the application itself.

I almost forgot this fun application, with the running man for start, pebbles for source code (sometimes source files behaved strangely. Joke? Nope, source files are not mere text files here. They are specific files for numerous platforms, therefore they could be broken, huh). DataWindows, source code editors with pink band for inherited code, etc, etc, … The old good app.

Recently, I saw a question in a LinkedIn group: “Any recommendations on a UI Automation tool, preferably open source or free, that works with PowerBuilder 12.0 and/or 12.5”.

I was surprised by the fact that somebody still needs testing against PowerBuilder, decided that SAP gave it the second life and downloaded 12.5.

My first impression was that PowerBuilder shipped in two editions: .NET and classic. I glanced at the .NET edition, got that it produced WPF applications and lost the interest.

The classic edition, on the opposite, took me. With nostalgia and disgust at all these fun but unfriendly menu and toolbars, I started testing all that I found. I discovered that I almost completely forgot how to build a window (the start-up script), attach a menu to it, attach a data window to it, etc, so that I turned to tutorials and samples. I could not run the tutorial because I forgot the password to the sample SQL Anywhere DB, and I opened samples.

1. Advanced GUI

Having started the sample,



this app appeared.


To my shock, it was too advanced: no accessibility is provided. While I could work by names with the tutorial app, Sybase left only AutomaitonId and ClasName for testers. Awful!

To open the Help/About window, testers need to run the following abracadabra:

Get-UIAWindow -Name advanced*gui* | Get-UIAMenuItem -AutomationId 'item 2' | Invoke-UIAMenuItemExpand | Get-UIAMenuItem -AutomationId 'item 10002' | Invoke-UIAMenuItemClick;

The old-school tab control and toolbars are Panes.
The grid is accessible, but, but…
This code gets the topmost field in the grid and turns John into Johnny:

Get-UIAWindow -Name advanced*gui* | Get-UIAText -Name first_name_t | Invoke-UIAControlClick; Get-UIAControlFromPoint | Set-UIAControlText -Text Johnny;


The rest of grid fields share the same name, what is even worse.

The second tab is better: names of control are available to testers.


Get-UIARadioButton -Name Horizontal | Invoke-UIARadioButtonSelectItem -ItemName Horizontal;


Other three tabs were not better: the most of the controls are Panes.
I checked other samples, some could be automated, some are problematical.


Daily automation: getting selected radio button

This is truth, the phrase “only one who completely understood the topic can explain it to others” and “to put it so simply that even a five-year old guy would get it”. When I tried to write how to get an item that is selected, such as a radio button, I discovered that it’s not so easy as it should be. If a control containing items does not support SelectionPattern, there is a problem.
This fact led to creation of the Get-UIASelectedItem cmdlet.
To demonstrate how it works, let’s start calc.exe in the Programmer mode:

ipmo [path]\UIAutomation.dll
Start-Process calc -PassThru | Get-UIAWindow | Get-UIAMenuItem -Name View | Invoke-UIAMenuItemExpand | Get-UIAMenuItem -Name Programmer | Invoke-UIAMenuItemClick;

The calc window in this mode looks like:


There are two sets of radio buttons. Unfortunately, containers of these controls do nothing, as they don’t support SelectionPattern. It would be excellent if the following code worked:

# this code does not work
Start-Process calc -PassThru | Get-UIAWindow | Get-UIAImage -Name 'some name' | Get-UIAPaneSelection;

The problem is that none of two images supports SelectionPattern (and this is very atypical for an Image to support the most of the patterns).

This fact forces us to find out a solution using only those patterns that available to us. We know that radio buttons are likely to support SelectionItemPattern. Excellent! Let’s use this pattern.

We can group controls and get only those that are selected:

# this code does not work
Get-UIAImage -AutomationId 1080 | Get-UIARadioButton | Get-UIASelectedItem;

Why does this code not work? The answer is simple: images are not containers for radio buttons. Even though two groups of radio buttons work simultaneously, i.e. there can be selected two radio buttons, one for each image, we can’t rely on images. All radio buttons, by the opinion of MS UI Automation, are under the Pane that includes the most of controls.


What should we do to get the selected radio button on the upper image? We can group radio button manually and put them as an input to the Get-UIASelectedItem cmdlet:

"hex","dec","oct","bin" | %{ Get-UIARadioButton -Name $_; } | Get-UIASelectedItem | Read-UIAControlName

Trying to improve the documentation…

The long public holidays in Russia is a gift. When the employer pays salary as if we work, these ten days are the gift for personal projects. Have you heard that a French actor has recently changed citizenship? Just in time, in the time we are working on our projects while the whole world is working for the boss.

Instead of writing code, I started writing texts. The first project is UIAutomation. Several topics are already rewritten or reorganized, several are in progress.




The hard fate of SePSX 0.4.8

The last month was a month of deep code restructuring. Experiments with the appropriate IoC (now, it’s Autofac), writing a number of fast tests, changing the chain of calls from cmdlet-code to cmdlet-command-code, all this stuff took time.

Things suddenly changed with yesterday’s Selenium 2.27. There were three of seven constructors broken in any driver server component (ChromeDriver, InternetExplorerDriver), and code has been changed significantly to avoid exceptions.

The last minute 2.27.1 fixes the issue, however, code of SePSX became more stressful to this type of issue. Selenium 2.27.1 is available as Beta 3 of 0.4.8.

Turned a year!

Just remembered that the PowerShell testing suite turned a year. As it believed, approx. on November 28th, 2011, the result of a programming mistake, of course (a piece of code didn’t work in PowerShell, just a usage mistake), the decision to write up C#-cmdlets has been made. 🙂

Since then, our frameworks have changed significantly. It was only UIAutomation which was the root of the suite. Now, there are several frameworks published and several versions upcoming.

Shortly, I’d drop a word about the Software Testing Using PowerShell team plans. From the features that are almost ready to those that are only in mind. What will the upcoming winter bring to us?


  • on fail, the Invoke-UIA[ControlType]Click cmdlets will try Win32 click by default. This behavior (the user wants it click and it clicks) is most awaiting (thanks to JohnQuest for the idea).
  • the Set-UIA[ControlType]Text cmdlets will check the result and try to use SendKeys on a failure
  • the Set-UIAControlKeys cmdlet will try several times to put text into the input field, checking the result
  • UIAutomationSpy are going to produce more useful code. Moreover, the code produced is going to be faster. How? When possible, UIAutomationSpy will set the -Win32 parameter, what, in certain situations, accelerates tests significantly (working with controls near grids and listviews is slow; this can be healed by using Win32 handles).
  • UIAutomationSpy will finally check code that it generates (sometimes what can be got by hovering over is not the same that can be got by searching in the Automation tree).
  • at least ten pages of documentation as what is published is like a mad mix
  • setup for the module
  • Java Access Brigde (that has not been tried yet)
  • we will try to use UIA2 if it’s possible to combine two UI Automation technologies


  • support for ChromeOptions, InternetExplorerOptions and FirefoxProfile
  • fast-working ‘named’ cmdlets Get-Se[TagName]
  • cmdlets for working with tables
  • SeleniumSpy
  • in a perspective, support for other browsers


  • TestLink add-in (missing functionality)
  • TFS add-in
  • working with test cases in SQLite, TestLink, various files


  • EC2 and S3 cmdlets to allow automated test lab deployment and execution


  • a small set of cmdlets allowing us to start/stop/suspend/snapshot guests


  • these days we are working on harnessing a Dependency Injection framework. By now, SePSX is partially sitting on Autofac 2.6 and we are also experimenting with NInject 3 in other projects. TLAddin has benefited from using Moq. The reasons we are working on not a business-understood features are such:
  1. the number of tests is growing and the testing cycle should be running every several minutes. Hundreds of tests we already have are for daily framework verification (they take twenty minutes or more, what is critical for us). On the opposite, a hundred of unit tests we have already had take less than five seconds (and around seventeen seconds does Gallio take to get the consciousness at the start of testing)
  2. we need more through-out testing of our code

Projects’ roadmap’s gotten some dates

The recently published roadmap now contains schedule for upcoming functionality. As time continues, more features’ll get exact dates where only month is written now.

Daily automation: Execution plan for UI Automation?

Have you tried to debug GUI or UI Automation scripts? It’s possible, of course, however this activity is often like making a mountain out of a molehill. Why?, may you ask. Because, because you need to run part of your scripts, or the whole suite, in the debugging mode, and this disturbance is, most often, from a single error.

It might be time-consuming. It’s not so pleasant: you need to interrupt your activity and do something another. Maybe, insert more Write-Host or Write-Verbose statements. Or extend the log. Or run the code inside command-line or GUI-based debugger.

Well, something simple you can now do directly from your script! A couple of months ago, the most of cmdlets (I’m about he UIAutomation module) could return only one object. Now, cmdlets return  all objects that match. Even absolutely all. This is a typical behavior. This is also a problem: imagine the following hypothetical code: you get a window, after that you want to get one or more panes, and, finally, buttons. Say, Close and Cancel.

Your code looks like:

ipmo [path]\UIAutomation.dll
Get-UIAWindow -n "window name" | Get-UIAPane | Get-UIAButton -n C*;

Suddenly, you drove into an error. What? Error? I see the buttons, you think. The answer is simple: you’ve gotten two or three panes, but only one pane contains these buttons. You are given an error: the second and the third panes admitted that they lack buttons.

What would you do to resolve this? You need somehow learn which pane is yours. Here comes the Execution plan. What is it? I sure, many of us already know what an execution plan in MS SQL is. I was very excited about it, when, more than a decade ago, I’ve been achieving MCDBA. It’s how your queries will work and how long.

If you have never heard about it, several google results are worth being visited now: the search result.

Returning to our panes and buttons, we can now discuss what our plan consists of. UIAutomation 0.8.2. offers highlighter squares of ten colors for ‘generations’ of controls and numbers that allow you learn the order controls were output.

What is the thing a ‘generation’ of controls? I called so a wave of output. In our example, generation one is the window itself (it will be bordered and numbered 1). The second generation is panes (another color and numbers 2 in their upper-down corners). Finally, the third generation is buttons, also in another color.

Let’s run this code:

ipmo [path]\UIAutomation.dll
Start-Process calc -PassThru | Get-UIAWindow | Get-UIAButton; Get-UIAMenuItem; Get-UIAComboBox; Get-UIAEdit;

Here is how it looks like:

If we drag the window from under the ‘mesh’ of squares, what will be seen:

Number at the lower-right corners of squares follow the steps they have appeared:

  1. Get-UIAWindow
  2. Get-UIAButton
  3. Get-UIAMenuItem
  4. Get-UIAComboBox
  5. Get-UIAEdit

This may help in a complicated situation when you don’t know what path in the Automation tree your code walks.

Finally, there is a problem with PowerShell 2.0, or even powershell.exe -version 2. Thus, this feature is for PowerShell 3.0 running in the 3 mode.

PowerShell 3.0 with excellent support of localized cmdlets

Thinking about keyword-driven testing… This was the second time I did something inside UIAutomationAliases.dll.

The last time, I added some aliases like Get-Button to simplify readability. Today, I went further and added more aliases, for example, in Russian.

It was the shock, powershell.exe works with these cmdlets even though they are seen as question mark sets on my English Windows 8 RP:

What’s more, ISE fully supports them:

Intellisense also works:

All tests were performed in PowerShell 3.0 (Widnows 8 RP).


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

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 -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

This slideshow requires JavaScript.

What the WordPress :)

Isn’t it a bug?

%d bloggers like this: