Tag Archives: Win32 click

Daily automation: peeling the onion


Sometimes, hit happens. It’s a shame to confess, but rarely even I recommend simple Win32 clicks. Today was the story about such clicks. A member of the test team, not a newcomer to UIAutomation and with thousands of test cases in the suite behind, the guy complained that Invoke-UIAControlClick (i.e., PostMessage) did not work!

I approached, and it didn’t work! The panic was spreading out among the testers, suggestions like ‘use mouse_event!’ or ‘revise the code!’ was hovering around the room.

The answer was simple. The Invoke-UIAControlClick cmdlet as well as the PostMessage/SendMessage Win32 call hits by control’s handle. We attempted to do the following:

Get-UIAWindow -n window_name | Set-UIAFocus | Get-UIATab -n tab_name | Invoke-UIAControlClick -X 500 -Y 125;

What the world was awaiting was:

Get-UIAWindow -n window_name | Set-UIAFocus | Get-UIATab -n tab_name | Get-UIAPane | Get-UIAPane | Get-UIAPane | Invoke-UIAControlClick -X 500 -Y 125;

Each control in this pipeline had a handle and there was no point to hit the tab if the link was on the lowest pane.
Layers are of almost the same size and put one over one. Even spy++ couldn’t help as nobody knew which layers was pointed to by the spy++ target cursor in order to collect messages.

Task: help to find the right level.

Requirements: write out the script that hit-tests every layer of controls and prints their handles.

Solution: below is the script that walks down the hierarchy and prints out handles of controls:

function hittest
{
 param(
 [System.Windows.Automation.AutomationElement]$element,
 [int]$X,
 [int]$Y
 )
 if ($element | Invoke-UIAControlClick -X $X -Y $Y) {
 Write-Host "The control has handle $($element | Read-UIAControlNativeWindowHandle)";
 }
}

Get-UIAWindow -Name *window*name* | Set-UIAFocus | `
 Get-UIATab -Name *tab*name* | `
 Get-UIAControlDescendants | `
 %{hittest $_ 500 125;}

The script tries to click on each control and outputs the handle value. The Invoke-UIAControlClick cmdlet couldn’t decide was or wasn’t a click successful and returns $true if no crash were during the script execution.

Anyhow, you can use handles to get controls and click by handle in a cycle to find out the control you need.

Daily automation: walking through the Start menu


Task: click the Computer item in the Start menu.

Requirements: use UIAutomation to demonstrate the technique.

Solution: although the solution is simple, it may be difficult to find out. The current version of UIAutomationSpy is slightly outdated and not yet recommends using the Get-UIADesktop cmdlet. Okay, this time we’ll do it manually, having in mind that a newer version of UIAutomationSpy is promised.

Here is the solution. At first, we open the Start menu by clicking the Start button. After that, we are seeking for a window that is the underlying level which the menu is placed upon. Finally, we get a list item, called of course Computer and send a Win32 click to there.

This sample is not ready to globalization.

ipmo [path]\UIAutomation.dll;

# click the Start button and open the Start menu
Get-UIADesktop | Get-UIAButton -Name Start | Invoke-UIAButtonClick; 
# Navigating through the Start menu and clicking the list item of our interest
Get-UIADesktop | Get-UIAcontrol -Class 'DV2ControlHost' -Name 'Start menu' | Get-UIAPane -Class 'DesktopSpecialFolders' | Get-UIAListItem -Name 'Computer' | Invoke-UIAControlClick;

After the code is processed by PowerShell, the Computer folder is open.

(MS) UIAutomation: performing a Win32 click on a VMware guest


Task: explain how to make your UI test script working in the VMware environment.

Requirements: provide scripters with recommendations.

Solution: sometimes you need to do a specific click. It might happen if a control does not support InvokePattern (thus, there’s no Invoke-UIA[ControlType]Cmdlet or there IS a cmdlet, but the control does not support the InvokePattern on its own). Usually it is not a problem: we have a Win32 click (Invoke-UIAControlClick) and cmdlets based on this click (Invoke-UIAControlContextMenu).

All of a sudden you may notice that surprisingly your click does not work. You are running the script on a VMware guest and the problem is that the cursor refuses positioning. In other words, the API function SetCursorPos does not work.

Theoretically, there might be used OpenInputDesktop, SetThreadDesktop and similar stuff. However, there is a much simplier way: just uninstall VMware Pointing device. With losing a bit of comfort, you’ll get your script working.

%d bloggers like this: