Monthly Archives: January, 2013

Daily automation: SendKeys tricks


Today’s comment is absolutely worth posting here!

How to send a special character via SendKeys – it may be not so easy as I thought.

First of all, how to do this task in an easy way (i.e., using ValuePattern). I created a simple Windows Forms application called ‘testeditbox’ with a label and a text box (the label is not used in the test, just a typical case text box + label).

SendKeys001
We can write in and, after, clean it the following way:

Get-UIAWindow -n testeditbox | Get-UIAEdit | Set-UIAEditText texttexttext;

SendKeys002

Get-UIAWindow -n testeditbox | Get-UIAEdit | Set-UIAEditText "";

SendKeys003

Now, we are going to perform this without using the pattern. There are two ways to put text in: Set-UIAControlText and Set-UIAControlKeys.
The first method can’t send special characters (it’s just my fault, I need to add the possibility), it works through the SendMessage API call. It should work pretty well as it sends to a handle.
The second is .NET SendKeys.
The problem is that SendKeys sends only to the focused control. Well, I achieved the result this way:

Get-UIAWindow -n testeditbox | Get-UIAEdit | Set-UIAFocus;
Get-UIAEdit | Set-UIAControlKeys "text2";

SendKeys004

Get-UIAWindow -n testeditbox | Get-UIAEdit | Set-UIAFocus;
Get-UIAEdit | Set-UIAControlKeys "^(A){DELETE}";

SendKeys005

Step by step guide:
1) get a control
2) set focus
3) get a control again (the Set-UIAControlKeys requires input), the control is foreground now
4) put keys to the control (Ctrl+A and Delete).

If your control of some other sort, you may need to do other tricks. Nonetheless, the idea behind is as I demonstrated.

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,

PB125_00001

PB125_00002

this app appeared.

PB125_00003

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;

PB125_00005

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.

PB125_00006

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

PB125_00007

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:

CalcProgrammerMode001

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.

Get-UIAPane;

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

Pipeline001

 

Pipeline002

%d bloggers like this: