Information in this topic applies to desktop applications only. |
This topic explains how TestComplete names objects of MSAA applications exposed via the Microsoft Active Accessibility Support plugin and how you can address these objects in your tests. For more information on addressing windows, controls and objects in other Open Applications and in black-box applications, see Object Browser Naming Notation.
Obtaining Processes
Addressing windows, controls and objects is hierarchical, that is, to obtain any object of the MSAA application’s window, you should first obtain the corresponding process. To do this, you can use the Sys.Process
or Sys.WaitProcess
method that returns a Process
object. The difference between the mentioned methods is that Sys.Process
returns the result immediately while Sys.WaitProcess
delays the script execution until the specified process appears or until the specified time limit is reached.
If the specified process does not exist, the Process
method will post an error message to the test log and return an empty object. If you then attempt to call any other methods or properties using this object, TestComplete will post an error message to the test log. To determine whether the desired process exists, use the Exists
property.
JavaScript, JScript
if (! Sys.WaitProcess("MyMSAAApp").Exists )
Log.Warning("The specified process does not exist.");
Python
if not Sys.WaitProcess("MyMSAAApp").Exists:
Log.Warning("The specified process does not exist.")
VBScript
If Not Sys.WaitProcess("MyMSAAApp").Exists Then
Log.Warning "The specified process does not exist."
End If
DelphiScript
if not Sys.WaitProcess('MyMSAAApp').Exists then
Log.Warning('The specified process does not exist.');
C++Script, C#Script
if (! Sys["WaitProcess"]("MyMSAAApp")["Exists"])
Log["Warning"]("The specified process does not exist.");
For detailed information on how to obtain processes, see Object Browser Naming Notation.
Obtaining Windows and Controls
The way you can address windows and controls in MSAA Open Applications depends on the MSAA engine mode. TestComplete 12 includes the compatibility mode that was used in TestComplete 6 and earlier. The active mode is specified by the Work with MSAA objects in mode compatible with TestComplete 6 and earlier property of your project. If it is unchecked (by default, it is), TestComplete uses the default mode. Otherwise, it uses the compatibility mode.
The two modes are incompatible. The tests recorded or created in the compatibility mode will not play back correctly in the new mode and vice versa.
The rest of this topic explains how to address object principles in both modes.
Addressing Objects (New Mode)
To address controls and objects that are exposed by the MSAA engine, TestComplete uses the objects’ type names that indicate their accessibility roles in the application:
Using type names simplifies the tests and makes them more readable. For a full list of object types that correspond to various accessibility roles, see the following topics:
Besides type names, TestComplete identifies objects by accessibility names. If there are several objects with the same accessibility roles and names in a parent container, TestComplete addresses the object by the accessibility name plus its index among siblings of the same type (the ControlIndexInGroup
property value). The default index, 0, is always omitted. For example:
ListItem("My item")
ListItem("My item", 1)
ListItem("My item", 2)
and so on
The accessible names are case-insensitive. That is, Button("OK")
and Button("ok")
refer to the same object. Note also, that you can use wildcards (* and ?) or regular expressions when addressing objects whose accessibility names have variable parts. The asterisk (*) corresponds to a string of any length (including an empty string), the question mark corresponds to any single character (including none). To specify more complicated parts of accessibility names, use regular expressions.
If the object does not have an accessibility name specified, the way TestComplete addresses this object depends on whether it is windowed or not:
-
Non-windowed objects are addressed by type names and indexes within the parent container. For example:
Table(1)
Link(0)
-
Windowed controls can be addressed with the
Window
method of the parent window like controls of black-box applications.
The following code illustrates MSAA object addressing. It launches Notepad using the Windows Start | Run menu command. The example requires that the * item in the project’s MSAA Options is checked.
JavaScript, JScript
function Test()
{
var p, w;
// Select Start and then Run
p = Sys.Process("Explorer");
p.Window("Shell_TrayWnd").Button("Start").Click();
p.Popup("Application").Window("MenuSite").Popup("Application").MenuItem("Run...").Click();
// Run Notepad
w = p.Dialog("Run");
w.ComboBox("Open:").Window("Edit").Keys("notepad");
w.Button("OK").Click();
}
Python
def Test():
# Select Start and then Run
p = Sys.Process("Explorer")
p.Window("Shell_TrayWnd").Button("Start").Click()
p.Popup("Application").Window("MenuSite").Popup("Application").MenuItem("Run...").Click()
# Run Notepad
w = p.Dialog("Run")
w.ComboBox("Open:").Window("Edit").Keys("notepad")
w.Button("OK").Click()
VBScript
Sub Test
Dim p, w
' Select Start and then Run
Set p = Sys.Process("Explorer")
p.Window("Shell_TrayWnd").Button("Start").Click
p.Popup("Application").Window("MenuSite").Popup("Application").MenuItem("Run...").Click
' Run Notepad
Set w = p.Dialog("Run")
w.ComboBox("Open:").Window("Edit").Keys("notepad")
w.Button("OK").Click
End Sub
DelphiScript
procedure Test;
var p, w;
begin
// Select Start and then Run
p := Sys.Process('Explorer');
p.Window('Shell_TrayWnd').Button('Start').Click;
p.Popup('Application').Window('MenuSite').Popup('Application').MenuItem('Run...').Click;
// Run Notepad
w := p.Dialog('Run');
w.ComboBox('Open:').Window('Edit').Keys('notepad');
w.Button('OK').Click;
end;
C++Script, C#Script
function Test()
{
var p, w;
// Select Start and then Run
p = Sys["Process"]("Explorer");
p["Window"]("Shell_TrayWnd")["Button"]("Start")["Click"]();
p["Popup"]("Application")["Window"]("MenuSite")["Popup"]("Application")["MenuItem"]("Run...")["Click"]();
// Run Notepad
w = p["Dialog"]("Run");
w["ComboBox"]("Open:")["Window"]("Edit")["Keys"]("notepad");
w["Button"]("OK")["Click"]();
}
Also, to wait for an object that is exposed by the MSAA engine, to be exposed, TestComplete adds a number of Wait methods to parent objects: WaitPanel
, WaitTable
, WaitListItem
, WaitPropertyPage
and so on.
These methods are not displayed in the Object Browser and other TestComplete panels and windows, however, they are fully accessible from scripts. The syntax of these Wait
methods is as follows:
WaitTypeName(ObjectNameOrIndex, Timeout)
The methods use the following parameters:
-
TypeName - the type name of the child object (Panel, Table, ListItem, Button, PropertyPage and so on).
-
ObjectNameOrIndex - the accessibility name of the target object, or its index within the container (the
ControlIndexInGroup
property value). It must be the same as the name or index that is displayed in the Object Browser. For example, if the child object is namedPanel("Standard")
, then this parameter should be"Standard"
; if the child object is namedTable(2)
, the parameter should be2
.If the target object is addressed both using the name and index, you should specify both parameters. For example, if the child object is names
ListItem("My Item", 3)
, you should specify --"My Item", 3
. -
Timeout - specifies the waiting time (in milliseconds). If this parameter is 0, the method checks for the object’s existence once and returns immediately. If the parameter is -1, the waiting time is infinite.
If the specified object becomes available before the time period elapses, the Wait methods return this object. Otherwise, they return an empty stub object that only contains the Exists
property. You can use this property to check whether the returned object actually exists.
Below are some examples of child object names and the corresponding Wait method calls (the Timeout parameter is 1000 in all the examples):
Object | Wait Method |
---|---|
Panel("Standard") |
WaitPanel("Standard", 1000) |
Table(2) |
WaitTable(2, 1000) |
ListItem("My Item", 3) |
WaitListItem("My Item", 3, 1000) |
Addressing Objects (Compatibility Mode)
If the Work with MSAA objects in mode compatible with TestComplete 6 and earlier property of your project is checked, then TestComplete addresses objects exposed by the MSAA engine in the same way it did in TestComplete ver. 4 - 6, namely, using the MSAAObject
and WaitMSAAObject
methods. The difference between these two methods is that MSAAObject
returns the requested object immediately, while WaitMSAAObject
delays the test execution until the requested object becomes available to TestComplete or until the specified timeout elapses.
The MSAAObject
and WaitMSAAObject
methods use special object identifiers that specify both the object’s accessible name and role. These identifiers consist of the following parts, which are combined with the underscore characters (_):
-
The prefix that specifies the object’s accessible role. Possible prefixes are listed in the table below. TestComplete uses the short prefix if the object has an accessibility name specified, and the long prefix otherwise.
-
The object’s accessible name (if any), with spaces replaced by underscore characters and any characters except for alphanumeric ones removed, so that the name becomes a valid script identifier.
-
The object’s index among objects that have the same accessible name and role (if greater than 1).
For example:
Identifier | Description |
---|---|
editable_text_Comments | An edit box with the accessible name of “Comments”. |
btn_Normal_View | A button with the accessible name of “Normal View”. |
table | A table with no accessible name. |
cell_2 | The second cell within the table. |
The objects returned by the MSAAObject
and WaitMSAAObject
methods contain methods, properties and actions of onscreen
objects as well as methods and properties of the IAccessible
interface. For more information on the IAccessible
members, see the documentation of the IAccessible
Interface in the MSDN library.
The following code demonstrates how you can address MSAA objects in the compatibility mode. It launches Notepad using the Windows Start | Run menu command. The example requires that the “*” item in the project’s MSAA Options is checked.
JavaScript, JScript
function Test()
{
var p, w, menu;
// Click the Start button
p = Sys.Process("Explorer");
p.Window("Shell_TrayWnd").Window("Button", "Start").MSAAObject("btn_Start").DoDefaultAction();
// Select the Run command in the Start menu
menu = p.Window("BaseBar", "", 1).Window("MenuSite").Window("ToolbarWindow32").MSAAObject("pm_Application");
menu.MSAAObject("mi_Run").MSAAObject("mi_Run").DoDefaultAction();
// Run Notepad
w = p.Window("#32770", "Run");
w.Window("ComboBox").Window("Edit").Keys("notepad");
w.Window("Button", "OK").MSAAObject("btn_OK").DoDefaultAction();
}
Python
def Test():
# Click the Start button
p = Sys.Process("Explorer")
p.Window("Shell_TrayWnd").Window("Button", "Start").MSAAObject("btn_Start").DoDefaultAction()
# Select the Run command in the Start menu
menu = p.Window("BaseBar", "", 1).Window("MenuSite").Window("ToolbarWindow32").MSAAObject("pm_Application")
menu.MSAAObject("mi_Run").MSAAObject("mi_Run").DoDefaultAction()
# Run Notepad
w = p.Window("#32770", "Run")
w.Window("ComboBox").Window("Edit").Keys("notepad")
w.Window("Button", "OK").MSAAObject("btn_OK").DoDefaultAction()
VBScript
Sub Test
Dim p, w, menu
' Click the Start button
Set p = Sys.Process("Explorer")
p.Window("Shell_TrayWnd").Window("Button", "Start").MSAAObject("btn_Start").DoDefaultAction
' Select the Run command in the Start menu
Set menu = p.Window("BaseBar", "", 1).Window("MenuSite").Window("ToolbarWindow32").MSAAObject("pm_Application")
menu.MSAAObject("mi_Run").MSAAObject("mi_Run").DoDefaultAction
' Run Notepad
Set w = p.Window("#32770", "Run")
w.Window("ComboBox").Window("Edit").Keys("notepad")
w.Window("Button", "OK").MSAAObject("btn_OK").DoDefaultAction
End Sub
DelphiScript
procedure Test;
var p, w, menu;
begin
// Click the Start button
p := Sys.Process('Explorer');
p.Window('Shell_TrayWnd').Window('Button', 'Start').MSAAObject('btn_Start').DoDefaultAction;
// Select the Run command in the Start menu
menu := p.Window('BaseBar', '', 1).Window('MenuSite').Window('ToolbarWindow32').MSAAObject('pm_Application');
menu.MSAAObject('mi_Run').MSAAObject('mi_Run').DoDefaultAction;
// Run Notepad
w := p.Window('#32770', 'Run');
w.Window('ComboBox').Window('Edit').Keys('notepad');
w.Window('Button', 'OK').MSAAObject('btn_OK').DoDefaultAction;
end;
C++Script, C#Script
function Test()
{
var p, w, menu;
// Click the Start button
p = Sys["Process"]("Explorer");
p["Window"]("Shell_TrayWnd")["Window"]("Button", "Start")["MSAAObject"]("btn_Start")["DoDefaultAction"]();
// Select the Run command in the Start menu
menu = p["Window"]("BaseBar", "", 1)["Window"]("MenuSite")["Window"]("ToolbarWindow32")["MSAAObject"]("pm_Application");
menu["MSAAObject"]("mi_Run")["MSAAObject"]("mi_Run")["DoDefaultAction"]();
// Run Notepad
w = p["Window"]("#32770", "Run");
w["Window"]("ComboBox")["Window"]("Edit")["Keys"]("notepad");
w["Window"]("Button", "OK")["MSAAObject"]("btn_OK")["DoDefaultAction"]();
}
See Also
Using Microsoft Active Accessibility
Limiting the Number of MSAA Child Objects