Tag Archives: ControlType.Custom

UIAutomation performance test


I conducted a test that is pretty interesting. As many might know, the more objects on a form, the slower your searches down the Automation tree.
It was measured that search on a form containing an Infragistics grid with 250 rows and 6 columns (i.e., 1500 cells) may take up to fifteen minutes. It depends on many conditions, for example, if a host is relatively ‘fresh’, it takes 383 seconds, i.e. just more than six minutes.
To demystify the topic, I ran the following test:
a simple .NET form with a DataGrid:

The ‘button1’ button creates two columns, the ‘button2’ button adds ten rows per click.

This is the test script:

Get-UIAWindow -n Form1 | Get-UIAButton -n button1 | Invoke-UIAButtonClick;
for ($i = 0; $i -lt 20; $i++) {
 Get-UIAWindow -n Form1 | Get-UIAButton -n button2 | Invoke-UIAButtonClick;
 Write-Host "$(($i + 1) * 10) rows";
 "$(($i + 1) * 10) rows" >> "C:\1\grid_report.txt";
 Measure-Command -Expr {
 Get-UIAWindow -n Form1 | Get-UIATable | Get-UIAControlDescendants | %{Write-Host "$($_.Current.Name)`t$($_.Current.AutomationId)`t$($_.Current.ClassName)`t$($_.Current.ControlType.ProgrammaticName)`t$(($_.GetCurrentPattern([System.Windows.Automation.ValuePattern]::Pattern) -as [System.Windows.Automation.ValuePattern]).Current.Value)";}
 } >> "C:\1\grid_report.txt";
}

The script initializes the form by pressing the ‘button1’ button and performs twenty cycles. Each cycle, the script increases the number of rows in the grid and measures the search time.
In other words, our test measures the speed of search below the grid for the increasing number of rows with the increment equaling to 10.
The results are in the table (the test was performed on a Intel965 box with Windows 8 RP, 6GB RAM and the lowest Crucial M4 SSD):

Surprisingly, even though time the search took is increasing with the increase of the rows number, the objects per second time gradually decreases.
Here are two charts to make it more perceptible:


Both charts tell us two things:

  • the objects per second time is growing not to fast as the number of objects in the grid does, it grows slower
  • somewhere after 150 objects, time of the test begins increasing faster and faster.

The latter fact will be the reason for other tests in the near future (I’ll be informing the community about results).

Finally, the bare speed is not so valuable without other measurements. How much memory has been consumed? After the test, the Task Manager displays that:

The amount of memory is not so shocking if we compare it with the amount SharpDevelop consumes. One instance of SharpDevelop is the instance which the test app has been run from. The second instance did no more than was open with the UIAutomation solution loaded.

The normal amount of memory PowerShell consumes on this host is between 32 and 34 Megabytes, varying from run to run:

The test app, the script and the results are in the Box at the right.

Advertisements

Daily automation: command tabs enumeration


Having come with Office 2007, command tabs are seen in more and more applications. What are command tabs? These are just tab items, from a UIAutomation user’s point of view.

Task: open a command tab by its name. Work with elements inside it.

Requirements: provide a standard way to open a command tab and get controls placed on here.

Solution: the first example is how to open each command tab in an application. With OneNote, taken as an example because never stopping complaints against UI-based tests disturb me ;), we’ll activate all the command tabs, one by another.

[UIAutomation.Preferences]::OnSuccessDelay = 0;

Get-UIAWindow -pn onenote | `
Get-UIAControlDescendants -ControlType TabItem | `
%{
# set initial state before access each tab item
Get-UIATabItem -Name Home | `
Invoke-UIATabItemSelectItem -ItemName Home;

[void](Get-UIAButton -Name File*Tab | `
Invoke-UIAButtonClick);

# select a tab item
$_ | `
Invoke-UIATabItemSelectItem -ItemName $_.Current.Name;

# stop to see where we are
sleep -Seconds 2;

# print out the name of the current tab item
Write-Host "$($_.Current.Name)`t" `
     "$($_.Current.AutomationId)`t" `
     "$($_.Current.ClassName)";   }

As can be easily tested, changing the word onenote to, for example, winword will print out command tabs of Word. (The script tested with OneNote 2010 and Word 2010 on a Windows 8 CP box).

Now we are going to accomplish the second part of this task: printing out all the content of every command tab.

[UIAutomation.Preferences]::OnSuccessDelay = 0;

Get-UIAWindow -pn onenote | `
Get-UIAControlDescendants -ControlType TabItem | `
%{
# set initial state before access each tab item

Get-UIATabItem -Name Home | `
Invoke-UIATabItemSelectItem -ItemName Home;
[void](Get-UIAButton -Name File*Tab | `
Invoke-UIAButtonClick);

# select a tab item
$_ | `
Invoke-UIATabItemSelectItem -ItemName $_.Current.Name;

# stop to see where we are
sleep -Seconds 2;

# print out the name of the current tab item
Write-Host "$($_.Current.Name)`t" `
"$($_.Current.AutomationId)`t" `
"$($_.Current.ClassName)";

# enumerate down the hierarchy    Get-UIACustom -Name ($_.Current.Name) | `
Get-UIAControlDescendants | `
%{
# print out the name of the current tab item
Write-Host "$($_.Current.Name)`t" `
"$($_.Current.AutomationId)`t" `
"$($_.Current.ClassName)";
      }
   }

Note, here we don’t get the hierarchy from under tab items. Tab items become custom controls when they are clicked. Thus, we used here Get-UIACustom fed with the name of the current command tab.

Daily automation: exercising mspaint. Part 1


MSPaint within Windows 7 is a fun toy. Multi-level system of menu (command-tabs and drop-downs), Quick Access Toolbar, Zoom are the things that do mspaint quite similar to the Big Brother and sample for all forever, Microsoft Office. Well, let’s get accustomed with these controls.

Task: use UIAutomation to work with cutting-edge controls, for this goal explain how to use the search cmdlet with application’s menus.

Requirements: perform actions with a picture by means of menu items.

Solution: at first, start the application (don’t I need offer a bit more help? :)). The first example is how to completely renew a picture, i.e. create a new white sheet.:

Set-StrictMode -Version Latest;
ipmo [path]\UIAutomation.dll;
# create a new picture
Get-UIAWindow -pn mspaint | Get-UIACustom -Name 'Application menu' | Invoke-UIACustomClick | Get-UIAMenuItem -Name 'New' | Invoke-UIAMenuItemClick;
try{
 Get-UIAWindow -Name 'Paint' -Seconds 3 | Get-UIAButton -Name "Don`'t Save" | Invoke-UIAButtonClick;
} catch {
 Write-Host "the previous picture was as clean as snow";
}

Here a question can be raised: ‘what should we do if UIAutomationSpy obstinately gives us the code to access the Paste button that is beneath the list of menu items we are working with?’ Okay, there is a fault. The spy may suggest using the control underneath the mouse pointer on its own. Two controls are under the cursor, and the poor application may don’t know which of them we are interested in. Who is impeding us from using the search cmdlet? Below is the way how we can investigate into what the menu list is:

Set-StrictMode -Version Latest;
ipmo [path]\UIAutomation.dll;

(Get-UIAWindow -pn mspaint | Get-UIACustom -Name'Application menu' | Invoke-UIACustomClick | Search-UIAControl -Name 'New').Current;
%d bloggers like this: